File: package.h

package info (click to toggle)
crawl 2%3A0.34.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 100,188 kB
  • sloc: cpp: 363,709; ansic: 27,765; javascript: 9,516; python: 8,463; perl: 3,293; java: 3,132; xml: 2,380; makefile: 1,835; sh: 611; objc: 250; cs: 15; sed: 9; lisp: 3
file content (127 lines) | stat: -rw-r--r-- 2,964 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#pragma once

#define USE_ZLIB

#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdint>
#ifdef USE_ZLIB
#include <zlib.h>
#endif

using std::map;
using std::pair;
using std::set;
using std::string;
using std::vector;

#if !defined(DGAMELAUNCH) && !defined(DEBUG_DIAGNOSTICS)
#define DO_FSYNC
#endif

#define MAX_CHUNK_NAME_LENGTH 255

typedef uint32_t plen_t;

class package;

class chunk_writer
{
private:
    package *pkg;
    string name;
    plen_t first_block;
    plen_t cur_block;
    plen_t block_len;
#ifdef USE_ZLIB
    z_stream zs;
    Bytef *z_buffer;
#endif
    void raw_write(const void *data, plen_t len);
    void finish_block(plen_t next);
public:
    chunk_writer(package *parent, const string &_name);
    ~chunk_writer();
    void write(const void *data, plen_t len);
    friend class package;
};

class chunk_reader
{
private:
    chunk_reader(package *parent, plen_t start);
    void init(plen_t start);
    package *pkg;
    plen_t first_block, next_block;
    plen_t off, block_left;
#ifdef USE_ZLIB
    bool eof;
    z_stream zs;
    Bytef z_buffer[32768];
#endif
    plen_t raw_read(void *data, plen_t len);
public:
    chunk_reader(package *parent, const string &_name);
    ~chunk_reader();
    plen_t read(void *data, plen_t len);
    void read_all(vector<char> &data);
    friend class package;
};

class package
{
public:
    package(const char* file, bool writeable, bool empty = false);
    package();
    ~package();
    chunk_writer* writer(const string &name);
    chunk_reader* reader(const string &name);
    void commit();
    void delete_chunk(const string &name);
    bool has_chunk(const string &name);
    vector<string> list_chunks();
    void abort();
    void unlink();
    string get_filename() { return filename; }

    // statistics
    plen_t get_slack();
    plen_t get_size() const { return file_len; }
    plen_t get_chunk_fragmentation(const string &name);
    plen_t get_chunk_compressed_length(const string &name);
private:
    string filename;
    bool rw;
    int fd;
    plen_t file_len;
    int n_users;
    bool dirty;
    bool aborted;
#ifdef DO_FSYNC
    bool tmp;
#endif
    map<string, plen_t> directory;
    map<plen_t, plen_t> free_blocks;
    vector<plen_t> unlinked_blocks;
    map<plen_t, pair<plen_t, plen_t> > block_map;
    set<plen_t> new_chunks;
    map<plen_t, uint32_t> reader_count;
    plen_t extend_block(plen_t at, plen_t size, plen_t by);
    plen_t alloc_block(plen_t &size);
    void finish_chunk(const string &name, plen_t at);
    void free_chunk(const string &name);
    plen_t write_directory();
    void collect_blocks();
    void free_block_chain(plen_t at);
    void free_block(plen_t at, plen_t size);
    void seek(plen_t to);
    void fsck();
    void read_directory(plen_t start, uint8_t version);
    void trace_chunk(plen_t start);
    void load();
    void load_traces();
    friend class chunk_writer;
    friend class chunk_reader;
};