Added library target, changed some build settings, and fixed 64-to-32-bit conversion warnings.
5 * Created by Jens Alfke on 8/27/09.
6 * Copyright 2009 Jens Alfke. All rights reserved.
7 * BSD-Licensed: See the file "LICENSE.txt" for details.
17 uint16_t Chunk::type() const {
18 return _keyLength == 0xFFFF ?(uint16_t)_type :KeyValueChunk::kChunkType;
21 const KeyValueChunk* Chunk::asKeyValue() const {
22 return _keyLength == 0xFFFF ?NULL :(const KeyValueChunk*)this;
25 size_t Chunk::writeMultiple (File *file, uint16_t type,
26 Blob blobs[], int count) throw(File::Error) {
27 assert(type != KeyValueChunk::kChunkType);
28 Blob nuBlobs[count+1];
29 uint32_t size = sizeof(Chunk);
30 for (int i=0; i<count; i++) {
31 nuBlobs[i+1] = blobs[i];
32 size += blobs[i].length;
34 Chunk chunk(size, type);
35 nuBlobs[0] = Blob(&chunk, sizeof(chunk));
36 return file->writeMultiple(nuBlobs, count+1);
39 size_t Chunk::writePadding (File *file) {
40 off_t padding = file->position() & 0x03;
44 padding = 4 - padding;
46 Blob pad(&zero, (size_t)padding);
47 return writeMultiple(file, kChunkTypePadding, &pad, 1);
53 void KeyValueChunk::validate() const throw(File::Error) {
54 if (_keyLength >= 0xFFFFU)
55 throw File::Error(ERANGE, "Invalid key length (0xFFFF)");
56 if (valuePtr() > end())
57 throw File::Error(ERANGE, "Bad KeyValueChunk (key-length too large to fit)");
60 Blob KeyValueChunk::key() const {
61 return Blob(&_keyLength +1, _keyLength); // KeyValueChunk doesn't have _type
64 const char* KeyValueChunk::valuePtr() const {
65 size_t vptr = (size_t) key().end();
66 vptr = (vptr+3) & ~3; // 4-byte align
67 return (const char*)vptr;
70 Blob KeyValueChunk::value() const {
71 const char *vp = valuePtr();
72 return Blob(vp, (const char*)end()-vp);
75 bool KeyValueChunk::hasKey (Blob key) const {
76 return key.length==_keyLength
77 && memcmp(key.bytes, &_keyLength +1, key.length)==0;
80 size_t KeyValueChunk::write (File* file, FilePosition pos, Blob key, Blob value) throw(File::Error) {
81 if (key.length >= 0xFFFFU)
82 throw File::Error(ERANGE, "Key too long (>=64k)");
83 uint16_t keyLength = key.length;
84 uint32_t size = sizeof(uint32_t) + sizeof(uint16_t) + keyLength;
85 size_t pad = (pos + size) & 0x3;
89 size += pad + value.length;
91 Chunk chunk(size, KeyValueChunk::kChunkType);
92 chunk._keyLength = keyLength;
94 Blob(&chunk, sizeof(chunk._size)+sizeof(chunk._keyLength)),
98 return file->writeMultiple(b,4);
103 ChunkIterator::ChunkIterator (File* file, FilePosition start)
106 _length((FilePosition)_file->length()),
112 void ChunkIterator::_loadChunk() {
113 if (_pos < _length) {
114 _chunk = (const Chunk*) _file->mappedPosition(_pos);
115 if (_chunk->size() < sizeof(Chunk) || _pos+_chunk->size() > _length)
123 bool ChunkIterator::atEOF() const {
124 return _pos == _length;
127 bool ChunkIterator::next() {
129 _pos += _chunk->size();
132 return _chunk != NULL;