/* pool - hierarchical storage object for PD and Max/MSP Copyright (c) 2002-2006 Thomas Grill (gr@grrrr.org) For information on usage and redistribution, and for a DISCLAIMER OF ALL WARRANTIES, see the file, "license.txt," in this distribution. */ #ifndef __POOL_H #define __POOL_H #define FLEXT_ATTRIBUTES 1 #include #if !defined(FLEXT_VERSION) || (FLEXT_VERSION < 500) #error You need at least flext version 0.5.0 #endif #include using namespace std; typedef void V; typedef int I; typedef unsigned long UL; typedef float F; typedef char C; typedef bool BL; typedef t_atom A; typedef t_symbol S; typedef flext::AtomListStatic<8> Atoms; class poolval: public flext { public: poolval(const A &key,AtomList *data); ~poolval(); poolval &Set(AtomList *data); poolval *Dup() const; A key; AtomList *data; poolval *nxt; }; class pooldir: public flext { public: pooldir(const A &dir,pooldir *parent,I vcnt,I dcnt); ~pooldir(); V Clear(BL rec,BL dironly = false); V Reset(BL realloc = true); BL Empty() const { return !dirs && !vals; } BL HasDirs() const { return dirs != NULL; } BL HasVals() const { return vals != NULL; } pooldir *GetDir(I argc,const A *argv,BL cut = false); pooldir *GetDir(const AtomList &d,BL cut = false) { return GetDir(d.Count(),d.Atoms(),cut); } BL DelDir(I argc,const A *argv); BL DelDir(const AtomList &d) { return DelDir(d.Count(),d.Atoms()); } pooldir *AddDir(I argc,const A *argv,I vcnt = 0,I dcnt = 0); pooldir *AddDir(const AtomList &d,I vcnt = 0,I dcnt = 0) { return AddDir(d.Count(),d.Atoms(),vcnt,dcnt); } V SetVal(const A &key,AtomList *data,BL over = true); BL SetVali(I ix,AtomList *data); V ClrVal(const A &key) { SetVal(key,NULL); } BL ClrVali(I ix) { return SetVali(ix,NULL); } AtomList *PeekVal(const A &key); AtomList *GetVal(const A &key,BL cut = false); I CntAll() const; I GetAll(A *&keys,Atoms *&lst,BL cut = false); I PrintAll(char *buf,int len) const; I GetKeys(AtomList &keys); I CntSub() const; I GetSub(const A **&dirs); poolval *RefVal(const A &key); poolval *RefVali(I ix); BL Paste(const pooldir *p,I depth,BL repl,BL mkdir); BL Copy(pooldir *p,I depth,BL cur); BL LdDir(istream &is,I depth,BL mkdir); BL LdDirXML(istream &is,I depth,BL mkdir); BL SvDir(ostream &os,I depth,const AtomList &dir = AtomList()); BL SvDirXML(ostream &os,I depth,const AtomList &dir = AtomList(),I ind = 0); int VSize() const { return vsize; } int DSize() const { return dsize; } protected: int VIdx(const A &v) const { return FoldBits(AtomHash(v),vbits); } int DIdx(const A &d) const { return FoldBits(AtomHash(d),dbits); } A dir; pooldir *nxt; pooldir *parent; const I vbits,dbits,vsize,dsize; static unsigned int FoldBits(unsigned long h,int bits); static int Int2Bits(unsigned long n); struct valentry { int cnt; poolval *v; }; struct direntry { int cnt; pooldir *d; }; valentry *vals; direntry *dirs; private: BL LdDirXMLRec(istream &is,I depth,BL mkdir,AtomList &d); }; class pooldata: public flext { public: pooldata(const S *s = NULL,I vcnt = 0,I dcnt = 0); ~pooldata(); bool Private() const { return sym == NULL; } V Push() { ++refs; } BL Pop() { return --refs > 0; } V Reset() { root.Reset(); } BL MkDir(const AtomList &d,I vcnt = 0,I dcnt = 0) { root.AddDir(d,vcnt,dcnt); return true; } BL ChkDir(const AtomList &d) { return root.GetDir(d) != NULL; } BL RmDir(const AtomList &d) { return root.DelDir(d); } BL Set(const AtomList &d,const A &key,AtomList *data,BL over = true) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->SetVal(key,data,over); return true; } BL Seti(const AtomList &d,I ix,AtomList *data) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->SetVali(ix,data); return true; } BL Clr(const AtomList &d,const A &key) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->ClrVal(key); return true; } BL Clri(const AtomList &d,I ix) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->ClrVali(ix); return true; } BL ClrAll(const AtomList &d,BL rec,BL dironly = false) { pooldir *pd = root.GetDir(d); if(!pd) return false; pd->Clear(rec,dironly); return true; } AtomList *Peek(const AtomList &d,const A &key) { pooldir *pd = root.GetDir(d); return pd?pd->PeekVal(key):NULL; } AtomList *Get(const AtomList &d,const A &key) { pooldir *pd = root.GetDir(d); return pd?pd->GetVal(key):NULL; } poolval *Ref(const AtomList &d,const A &key) { pooldir *pd = root.GetDir(d); return pd?pd->RefVal(key):NULL; } poolval *Refi(const AtomList &d,I ix) { pooldir *pd = root.GetDir(d); return pd?pd->RefVali(ix):NULL; } I CntAll(const AtomList &d) { pooldir *pd = root.GetDir(d); return pd?pd->CntAll():0; } I PrintAll(const AtomList &d); I GetAll(const AtomList &d,A *&keys,Atoms *&lst); I CntSub(const AtomList &d) { pooldir *pd = root.GetDir(d); return pd?pd->CntSub():0; } I GetSub(const AtomList &d,const t_atom **&dirs); BL Paste(const AtomList &d,const pooldir *clip,I depth = -1,BL repl = true,BL mkdir = true); pooldir *Copy(const AtomList &d,const A &key,BL cut); pooldir *CopyAll(const AtomList &d,I depth,BL cut); BL LdDir(const AtomList &d,const C *flnm,I depth,BL mkdir = true); BL SvDir(const AtomList &d,const C *flnm,I depth,BL absdir); BL Load(const C *flnm) { AtomList l; return LdDir(l,flnm,-1); } BL Save(const C *flnm) { AtomList l; return SvDir(l,flnm,-1,true); } BL LdDirXML(const AtomList &d,const C *flnm,I depth,BL mkdir = true); BL SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir); BL LoadXML(const C *flnm) { AtomList l; return LdDirXML(l,flnm,-1); } BL SaveXML(const C *flnm) { AtomList l; return SvDirXML(l,flnm,-1,true); } I refs; const S *sym; pooldata *nxt; pooldir root; private: static const A nullatom; }; #endif