diff options
author | Adam Borowski <kilobyte@angband.pl> | 2010-08-20 02:12:53 +0200 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2010-08-20 02:12:53 +0200 |
commit | b25ec0a923318fd601619cd0bd89a9c262ef74e1 (patch) | |
tree | 38d077a4e21a31ffa6ea0da77978e4e4ccd4adb1 /crawl-ref/source/package.h | |
parent | a290ba3a83431e38b1d54ed611e7892e38e0fdfd (diff) | |
download | crawl-ref-b25ec0a923318fd601619cd0bd89a9c262ef74e1.tar.gz crawl-ref-b25ec0a923318fd601619cd0bd89a9c262ef74e1.zip |
The transactional save packager.
Diffstat (limited to 'crawl-ref/source/package.h')
-rw-r--r-- | crawl-ref/source/package.h | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/crawl-ref/source/package.h b/crawl-ref/source/package.h new file mode 100644 index 0000000000..9ff525c49c --- /dev/null +++ b/crawl-ref/source/package.h @@ -0,0 +1,96 @@ +#ifndef PACKAGE_H +#define PACKAGE_H + +#define USE_ZLIB + +#include <stdint.h> +#include <string> +#include <map> +#include <vector> +#include <stack> + +#ifdef USE_ZLIB +#include <zlib.h> +#endif + +typedef uint32_t len_t; + +class package; + +class chunk_writer +{ +private: + chunk_writer(package *parent, const std::string _name); + package *pkg; + std::string name; + len_t first_block; + len_t cur_block; + len_t block_len; +#ifdef USE_ZLIB + z_stream zs; + Bytef *z_buffer; +#endif + void raw_write(const void *data, len_t len); + void finish_block(len_t next); +public: + ~chunk_writer(); + void write(const void *data, len_t len); + friend class package; +}; + +class chunk_reader +{ +private: + chunk_reader(package *parent, len_t start); + package *pkg; + len_t next_block; + len_t off, block_left; +#ifdef USE_ZLIB + bool eof; + z_stream zs; + Bytef z_buffer[32768]; +#endif + len_t raw_read(void *data, len_t len); +public: + ~chunk_reader(); + len_t read(void *data, len_t len); + friend class package; +}; + +class package +{ +public: + package(const char* file, bool writeable, bool empty = false); + ~package(); + chunk_writer* writer(const std::string name); + chunk_reader* reader(const std::string name); + void commit(); + void delete_chunk(const std::string name); + bool has_chunk(const std::string name); + std::vector<std::string> list_chunks(); +private: + bool rw; + int fd; + len_t file_len; + int n_users; + bool dirty; + std::map<std::string, len_t> directory; + std::map<len_t, len_t> free_blocks; + std::stack<len_t> unlinked_blocks; + std::map<len_t, std::pair<len_t, len_t> > block_map; + len_t extend_block(len_t at, len_t size, len_t by); + len_t alloc_block(); + void finish_chunk(const std::string name, len_t at); + void free_chunk(const std::string name); + len_t write_directory(); + void collect_blocks(); + void free_block(len_t at, len_t size); + void seek(len_t to); + void fsck(); + void read_directory(len_t start); + void trace_chunk(len_t start); + friend class chunk_writer; + friend class chunk_reader; +}; + +#endif |