#ifndef LIBCANIH #define LIBCANIH #include #include #include #include #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