00001 #ifndef PACKAGE_H
00002 #define PACKAGE_H
00003
00004 #define USE_ZLIB
00005
00006 #include <stdint.h>
00007 #include <string>
00008 #include <map>
00009 #include <vector>
00010 #include <stack>
00011
00012 #ifdef USE_ZLIB
00013 #include <zlib.h>
00014 #endif
00015
00016 #define MAX_CHUNK_NAME_LENGTH 255
00017
00018 typedef uint32_t len_t;
00019
00020 class package;
00021
00022 class chunk_writer
00023 {
00024 private:
00025 package *pkg;
00026 std::string name;
00027 len_t first_block;
00028 len_t cur_block;
00029 len_t block_len;
00030 #ifdef USE_ZLIB
00031 z_stream zs;
00032 Bytef *z_buffer;
00033 #endif
00034 void raw_write(const void *data, len_t len);
00035 void finish_block(len_t next);
00036 public:
00037 chunk_writer(package *parent, const std::string _name);
00038 ~chunk_writer();
00039 void write(const void *data, len_t len);
00040 friend class package;
00041 };
00042
00043 class chunk_reader
00044 {
00045 private:
00046 chunk_reader(package *parent, len_t start);
00047 void init(len_t start);
00048 package *pkg;
00049 len_t next_block;
00050 len_t off, block_left;
00051 #ifdef USE_ZLIB
00052 bool eof;
00053 z_stream zs;
00054 Bytef z_buffer[32768];
00055 #endif
00056 len_t raw_read(void *data, len_t len);
00057 public:
00058 chunk_reader(package *parent, const std::string _name);
00059 ~chunk_reader();
00060 len_t read(void *data, len_t len);
00061 void read_all(std::vector<char> &data);
00062 friend class package;
00063 };
00064
00065 class package
00066 {
00067 public:
00068 package(const char* file, bool writeable, bool empty = false);
00069 ~package();
00070 chunk_writer* writer(const std::string name);
00071 chunk_reader* reader(const std::string name);
00072 void commit();
00073 void delete_chunk(const std::string name);
00074 bool has_chunk(const std::string name);
00075 std::vector<std::string> list_chunks();
00076 void abort();
00077 void unlink();
00078 private:
00079 std::string filename;
00080 bool rw;
00081 int fd;
00082 len_t file_len;
00083 int n_users;
00084 bool dirty;
00085 bool aborted;
00086 std::map<std::string, len_t> directory;
00087 std::map<len_t, len_t> free_blocks;
00088 std::stack<len_t> unlinked_blocks;
00089 std::map<len_t, std::pair<len_t, len_t> > block_map;
00090 len_t extend_block(len_t at, len_t size, len_t by);
00091 len_t alloc_block();
00092 void finish_chunk(const std::string name, len_t at);
00093 void free_chunk(const std::string name);
00094 len_t write_directory();
00095 void collect_blocks();
00096 void free_block(len_t at, len_t size);
00097 void seek(len_t to);
00098 void fsck();
00099 void read_directory(len_t start, uint8_t version);
00100 void trace_chunk(len_t start);
00101 void load();
00102 friend class chunk_writer;
00103 friend class chunk_reader;
00104 };
00105
00106 #endif