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
128
129
130
131
132
133
134
135
136
137
138
#ifndef LIBCANIH
#define LIBCANIH
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <cstring>
#define int64 unsigned long long
//#define DEBUG
#ifdef DEBUG
#define dout cout
#else
#define dout if (0) cerr
#endif
using namespace std;
namespace libcanister
{
//the canmem object is a generic memory container used commonly
//throughout the canister framework to hold memory of uncertain
//length which may or may not contain null bytes.
class canmem
{
public:
char* data; //the raw memory block
int size; //the absolute length of the block
canmem(); //creates an unallocated canmem
canmem(int allocsize); //creates an allocated, blank canmem of size
canmem(char* strdata); //automates the creation of zero-limited canmems
~canmem(); //cleans up the canmem
void zeromem(); //overwrites this canmem
void fragmem(); //overwrites this canmem with fragment notation
void countlen(); //counts length of zero-limited strings and stores it in size
void trim(); //removes any nulls from the end of the string
static canmem null(); //returns a singleton null canmem
};
//contains information about the canister
class caninfo
{
public:
canmem path; //physical path
canmem internalname; //a name for the canister
int numfiles; //the number of files in the canister
};
//necessary for the use of this class as a type in canfile
class canister;
//this object holds the definition of a 'file' within the
//canister 'filesystem.'
class canfile
{
public:
libcanister::canister* parent; //the canister that holds this file
canmem path; //internal path ('filename')
canmem data; //the file's decompressed contents
int isfrag; //0 = probably not fragment, 1 = definitely a fragment (ignore)
int cfid; //'canfile id' -- a unique ID for this file
int64 dsize; //ondisk size (compressed form size)
int cachestate; //0 = not in memory, 1 = in memory, 2 = in memory and needs flush
//-1 = error, check the data for the message
void cache(); //pull the file from disk and cache it in memory
void cachedump(); //deletes the contents of this file from the memory cache after assuring the on disk copy is up to date
void cachedumpfinal(fstream& infile); //same as cachedump, but more efficient during closing procedures
void flush(); //updates the on disk copy, but retains the memory cache
};
//the primary class
//this defines and controls a single canister
class canister
{
//table of contents
//absolutely worthless to the control code in the canister
//but quite useful to programs using the API, as they may
//desire to enumerate the files in a canister for a user's
//use or for their own.
//contains a newline-delimited list of files in the container.
canfile TOC;
public:
caninfo info; //the general info about this canister
//the raw canfiles -- recommended that programs do not modify
//these files directly, but not enforced.
canfile* files;
bool readonly; //if true then no write routines will do anything
//maximum number of files to have in memory at any given
//time, change this to whatever suits your application.
int cachemax;
int cachecnt; //number of files in the cache (should not be modified)
//both initialize the canister from a physical location
canister (canmem fspath);
canister (char* fspath);
//destroys the canister (after flushing the modded buffers, of course)
~canister();
//open the fspath
//does it exist?
// | --- yes --- opening it (return 1)
// | --- yes --- file is corrupted, halting (return -1)
// | --- no --- making a new one (return 0)
int open();
//close the canister, flush all buffers, clean up
int close();
//deletes the file at path inside this canister
int delFile(canmem path);
//pulls the contents of the file from disk or memory and returns it as a file
canfile getFile(canmem path);
//creates a file if it does not exist, otherwise overwrites
//returns whether operation succeeded
bool writeFile(canmem path, canmem data);
bool writeFile(canfile file);
//get the 'table of contents', a file containing a newline delimited
//list of the file paths in the container which have contents
canfile getTOC();
//brings the cache back within the cachemax limit
//important: sCFID is the safe CFID
//(the CFID of the file we want to avoid uncaching)
//really just used internally, but it can't do any harm.
void cacheclean(int sCFID, bool dFlush = false);
};
}
#endif