jens@0: /* jens@0: * Chunk.h jens@0: * Ottoman jens@0: * jens@0: * Created by Jens Alfke on 8/27/09. jens@0: * Copyright 2009 Jens Alfke. All rights reserved. jens@0: * BSD-Licensed: See the file "LICENSE.txt" for details. jens@0: */ jens@0: jens@0: #ifndef _MOOSEYARD_CHUNK_ jens@0: #define _MOOSEYARD_CHUNK_ jens@0: #include "File.h" jens@0: jens@0: namespace Mooseyard { jens@0: jens@0: class KeyValueChunk; jens@0: jens@0: #pragma pack(2) jens@0: jens@0: /** An item stored in a file. It's prefixed with its length, so that the entire file jens@0: can be scanned for chunks easily. */ jens@0: class Chunk { jens@0: public: jens@0: uint32_t size() const {return _size;} jens@0: uint16_t type() const; jens@0: jens@0: /** If this is a KeyValueChunk, returns itself cast to that type, else NULL. */ jens@0: const KeyValueChunk* asKeyValue() const; jens@0: jens@0: /** Write a Chunk to the file, in pieces a la writev. */ jens@0: static size_t writeMultiple (File *file, uint16_t type, jens@0: Blob blobs[], int count) throw(File::Error); jens@0: jens@0: static size_t writePadding (File *file); jens@0: jens@0: static const uint16_t kChunkTypePadding = 0; jens@0: jens@0: const void* end() const {return offsetBy(this,_size);} jens@0: jens@0: protected: jens@0: Chunk (uint32_t size, uint16_t type) :_size(size), _keyLength(0xFFFF), _type(type) { } jens@0: jens@0: private: jens@0: // This is mapped to data in the file! Don't mess with it! jens@0: LittleEndian _size; jens@0: LittleEndian _keyLength; // Used by KeyValueChunk; else 0xFFFF jens@0: LittleEndian _type; // Not used by KeyValueChunk jens@0: friend class KeyValueChunk; jens@0: }; jens@0: jens@0: jens@0: /** A key/value pair as stored in the memory-mapped file. */ jens@0: class KeyValueChunk :public Chunk { jens@0: public: jens@0: Blob key() const; jens@0: Blob value() const; jens@0: jens@0: bool hasKey (Blob key) const; jens@0: jens@0: void validate() const throw(File::Error); jens@0: jens@0: /** Write a KeyValueChunk to a file. */ jens@0: static size_t write (File* file, FilePosition pos, Blob key, Blob value) throw(File::Error); jens@0: jens@0: static const uint16_t kChunkType = 1; jens@0: jens@0: private: jens@0: const char* valuePtr() const; jens@0: }; jens@0: jens@0: #pragma options align=reset jens@0: jens@0: jens@0: /** An iterator over all the Chunks in a file. */ jens@0: class ChunkIterator { jens@0: public: jens@0: ChunkIterator (File*, FilePosition start); jens@0: jens@0: const Chunk* chunk() const {return _chunk;} jens@0: FilePosition position() const {return _pos;} jens@0: bool atEOF() const; jens@0: bool next(); jens@0: jens@0: operator const Chunk*() const {return _chunk;} jens@0: virtual bool hasValue() const {return _chunk != NULL;} jens@0: operator bool() const {return hasValue();} jens@0: ChunkIterator& operator++() {next(); return *this;} jens@0: private: jens@0: void _loadChunk(); jens@0: File *_file; jens@0: FilePosition _pos, _length; jens@0: const Chunk* _chunk; jens@0: }; jens@0: jens@0: } jens@0: jens@0: #endif _MOOSEYARD_CHUNK_