#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "huffman.h"
#define ptrdist(a,b) (((char *)a)-((char *)b))
#define ptrmov(a,b) ((typeof(a)) (((char *)(a))+b))
#define nextstruct(x) x = (typeof(x))(ptrmov(x,sizeof(typeof(*x))+x->len));
typedef unsigned char uchar;
enum{FN_DIR,FN_ENDDIR,FN_FILE,FN_END};
/*
	 FN_FILE normal file.
	 FN_END end of database.
	 FN_DIR directory. 
	 FN_ENDDIR end of directory.
		  */
enum {_FN_LFILEINFO,_FN_DIRINFO,_FN_LDIRINFO,_FN_DIREND,_FN_END};
struct fileinfo{
uchar len:5,prefix:3;
/*len is lengh of s. if len=0 then prefix is constant from _FN_ enum*/ 
uchar s[];
}__attribute__((__packed__));
struct lfileinfo{
uchar slen:5,sprefix:3;
uchar len;
signed char prefix;
uchar s[];
}__attribute__((__packed__));
struct dirinfo{
	uchar slen:5,sprefix:3;
	uchar len;
	uchar s[];
} __attribute__((__packed__));
struct ldirinfo{
	uchar slen:5,sprefix:3;
	unsigned int len;
	uchar s[];
} __attribute__((__packed__));


union fname{
	struct fileinfo *fn;
	struct lfileinfo *lfn;
	struct dirinfo *dn;
	struct ldirinfo *ldn;
};
typedef struct{
	uchar *fullname,*name,*dirname;
	int filetype;/*FN_ constant*/
	union fname fn,fnbegin;
	uchar *ptr;
	hcode *hc;
	int mtime;
	int *hist,*newhist;
}dbase;

dbase *initdbase(int *hist);
dbase *readdb(char *file);
void writedb(dbase *db,char *file);

void addfile(dbase *fi,uchar *file);
void adddir(dbase *fi,uchar *dir);
void addenddir(dbase *fi);

void writefile(dbase *fi,uchar *file);
void writedir(dbase *fi,uchar *dir);
void writeend(dbase *fi);
void writeenddir(dbase *fi);

void readfile(dbase *fi);
