diff options
Diffstat (limited to 'externals/grill/pool')
-rw-r--r-- | externals/grill/pool/build-pd-darwin.sh | 2 | ||||
-rw-r--r-- | externals/grill/pool/config-pd-darwin.txt | 57 | ||||
-rw-r--r-- | externals/grill/pool/data.cpp | 852 | ||||
-rw-r--r-- | externals/grill/pool/makefile.pd-darwin | 8 | ||||
-rw-r--r-- | externals/grill/pool/pool.cpp | 1842 |
5 files changed, 1831 insertions, 930 deletions
diff --git a/externals/grill/pool/build-pd-darwin.sh b/externals/grill/pool/build-pd-darwin.sh index edd03207..8f21ebcb 100644 --- a/externals/grill/pool/build-pd-darwin.sh +++ b/externals/grill/pool/build-pd-darwin.sh @@ -4,7 +4,7 @@ make -f makefile.pd-darwin && { - if [ $INSTPATH != "" ]; then + if [ "${INSTPATH}" != "" ]; then echo Now install as root sudo make -f makefile.pd-darwin install fi diff --git a/externals/grill/pool/config-pd-darwin.txt b/externals/grill/pool/config-pd-darwin.txt index 7e412c2d..295a8a52 100644 --- a/externals/grill/pool/config-pd-darwin.txt +++ b/externals/grill/pool/config-pd-darwin.txt @@ -1,27 +1,30 @@ -# pool - hierarchical storage object for PD and Max/MSP
-# Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net)
-#
-
-# your c++ compiler (define only if it's different than g++)
-# CXX=g++
-
-# where are the PD header files?
-# leave it blank if it is a system directory (like /usr/local/include),
-# since gcc 3.2 complains about it
-PDPATH=/usr/local/pd/src
-
-# where is the PD executable?
-PD=/usr/local/pd/bin/pd
-
-# where do the flext libraries reside?
-FLEXTPATH=/usr/local/pd/flext
-
-# where should flext libraries be built?
-TARGDIR=./pd-darwin
-
-# where should pool be installed?
-# (leave blank to omit installation)
-INSTPATH=/usr/local/pd/extra
-
-
-
+# pool - hierarchical storage object for PD and Max/MSP +# Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net) +# + +# your c++ compiler (define only if it's different than g++) +# CXX=g++ + +# where are the PD header files? +# leave it blank if it is a system directory (like /usr/local/include), +# since gcc 3.2 complains about it +PDPATH=/usr/local/pd/src + +# where is the PD executable? +PD=/usr/local/pd/bin/pd + +# where do the flext libraries reside? +FLEXTPATH=/usr/local/pd/flext + +# where should flext libraries be built? +TARGDIR=./pd-darwin + +# where should pool be installed? +# (leave blank to omit installation) +INSTPATH=/usr/local/pd/extra + +# additional compiler flags +# (check if they match your system!) +UFLAGS=-malign-power -maltivec + + diff --git a/externals/grill/pool/data.cpp b/externals/grill/pool/data.cpp index 02ee4132..c67c3678 100644 --- a/externals/grill/pool/data.cpp +++ b/externals/grill/pool/data.cpp @@ -1,284 +1,568 @@ -/*
-
-pool - hierarchical storage object for PD and Max/MSP
-
-Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net)
-For information on usage and redistribution, and for a DISCLAIMER OF ALL
-WARRANTIES, see the file, "license.txt," in this distribution.
-
-*/
-
-#include "pool.h"
-
-#include <string.h>
-#include <fstream.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-
-pooldata::pooldata(const S *s,I vcnt,I dcnt):
- sym(s),nxt(NULL),refs(0),
- root(nullatom,NULL,vcnt,dcnt)
-{
- FLEXT_LOG1("new pool %s",sym?flext_base::GetString(sym):"<private>");
-}
-
-pooldata::~pooldata()
-{
- FLEXT_LOG1("free pool %s",sym?flext_base::GetString(sym):"<private>");
-}
-
-
-const A pooldata::nullatom = { A_NULL };
-
-
-V pooldata::Reset()
-{
- root.Reset();
-}
-
-BL pooldata::MkDir(const AtomList &d,I vcnt,I dcnt)
-{
- root.AddDir(d,vcnt,dcnt);
- return true;
-}
-
-BL pooldata::ChkDir(const AtomList &d)
-{
- return root.GetDir(d) != NULL;
-}
-
-BL pooldata::RmDir(const AtomList &d)
-{
- return root.DelDir(d);
-}
-
-BL pooldata::Set(const AtomList &d,const A &key,AtomList *data,BL over)
-{
- pooldir *pd = root.GetDir(d);
- if(!pd) return false;
- pd->SetVal(key,data,over);
- return true;
-}
-
-BL pooldata::Clr(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- if(!pd) return false;
- pd->ClrVal(key);
- return true;
-}
-
-BL pooldata::ClrAll(const AtomList &d,BL rec,BL dironly)
-{
- pooldir *pd = root.GetDir(d);
- if(!pd) return false;
- pd->Clear(rec,dironly);
- return true;
-}
-
-flext::AtomList *pooldata::Peek(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->PeekVal(key):NULL;
-}
-
-poolval *pooldata::Ref(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->RefVal(key):NULL;
-}
-
-poolval *pooldata::Refi(const AtomList &d,I ix)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->RefVali(ix):NULL;
-}
-
-flext::AtomList *pooldata::Get(const AtomList &d,const A &key)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->GetVal(key):NULL;
-}
-
-I pooldata::CntAll(const AtomList &d)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->CntAll():0;
-}
-
-I pooldata::GetAll(const AtomList &d,A *&keys,AtomList *&lst)
-{
- pooldir *pd = root.GetDir(d);
- if(pd)
- return pd->GetAll(keys,lst);
- else {
- keys = NULL; lst = NULL;
- return 0;
- }
-}
-
-I pooldata::CntSub(const AtomList &d)
-{
- pooldir *pd = root.GetDir(d);
- return pd?pd->CntSub():0;
-}
-
-I pooldata::GetSub(const AtomList &d,const t_atom **&dirs)
-{
- pooldir *pd = root.GetDir(d);
- if(pd)
- return pd->GetSub(dirs);
- else {
- dirs = NULL;
- return 0;
- }
-}
-
-
-BL pooldata::Paste(const AtomList &d,const pooldir *clip,I depth,BL repl,BL mkdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd)
- return pd->Paste(clip,depth,repl,mkdir);
- else
- return false;
-}
-
-pooldir *pooldata::Copy(const AtomList &d,const A &key,BL cut)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- AtomList *val = pd->GetVal(key,cut);
- if(val) {
- pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize());
- ret->SetVal(key,val);
- return ret;
- }
- else
- return NULL;
- }
- else
- return NULL;
-}
-
-pooldir *pooldata::CopyAll(const AtomList &d,I depth,BL cut)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- // What sizes should we choose here?
- pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize());
- if(pd->Copy(ret,depth,cut))
- return ret;
- else {
- delete ret;
- return NULL;
- }
- }
- else
- return NULL;
-}
-
-
-static const C *CnvFlnm(C *dst,const C *src,I sz)
-{
-#if FLEXT_SYS == FLEXT_SYS_PD && FLEXT_OS == FLEXT_OS_WIN
- I i,cnt = strlen(src);
- if(cnt >= sz-1) return NULL;
- for(i = 0; i < cnt; ++i)
- dst[i] = src[i] != '/'?src[i]:'\\';
- dst[i] = 0;
- return dst;
-#else
- return src;
-#endif
-}
-
-BL pooldata::LdDir(const AtomList &d,const C *flnm,I depth,BL mkdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ifstream fl(t);
- return fl.good() && pd->LdDir(fl,depth,mkdir);
- }
- else return false;
- }
- else
- return false;
-}
-
-BL pooldata::SvDir(const AtomList &d,const C *flnm,I depth,BL absdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ofstream fl(t);
- AtomList tmp;
- if(absdir) tmp = d;
- return fl.good() && pd->SvDir(fl,depth,tmp);
- }
- else return false;
- }
- else
- return false;
-}
-
-BL pooldata::LdDirXML(const AtomList &d,const C *flnm,I depth,BL mkdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ifstream fl(t);
- BL ret = fl.good() != 0;
- if(ret) {
- fl.getline(tmp,sizeof tmp);
- ret = !strncmp(tmp,"<?xml",5);
- }
- if(ret) {
- fl.getline(tmp,sizeof tmp);
- // DOCTYPE need not be present / only external DOCTYPE is allowed!
- if(!strncmp(tmp,"<!DOCTYPE",9))
- fl.getline(tmp,sizeof tmp);
- ret = !strncmp(tmp,"<pool>",6);
- }
- if(ret)
- ret = pd->LdDirXML(fl,depth,mkdir);
- return ret;
- }
- }
-
- return false;
-}
-
-BL pooldata::SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir)
-{
- pooldir *pd = root.GetDir(d);
- if(pd) {
- C tmp[1024];
- const C *t = CnvFlnm(tmp,flnm,sizeof tmp);
- if(t) {
- ofstream fl(t);
- AtomList tmp;
- if(absdir) tmp = d;
- if(fl.good()) {
- fl << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl;
- fl << "<!DOCTYPE pool SYSTEM \"pool.dtd\">" << endl;
- fl << "<pool>" << endl;
- BL ret = pd->SvDirXML(fl,depth,tmp);
- fl << "</pool>" << endl;
- return ret;
- }
- }
- }
-
- return false;
-}
-
-
+/* + + + +pool - hierarchical storage object for PD and Max/MSP + + + +Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net) + +For information on usage and redistribution, and for a DISCLAIMER OF ALL + +WARRANTIES, see the file, "license.txt," in this distribution. + + + +*/ + + + +#include "pool.h" + + + +#include <string.h> + +#include <fstream.h> + +#include <ctype.h> + +#include <stdlib.h> + + + + + +pooldata::pooldata(const S *s,I vcnt,I dcnt): + + sym(s),nxt(NULL),refs(0), + + root(nullatom,NULL,vcnt,dcnt) + +{ + + FLEXT_LOG1("new pool %s",sym?flext_base::GetString(sym):"<private>"); + +} + + + +pooldata::~pooldata() + +{ + + FLEXT_LOG1("free pool %s",sym?flext_base::GetString(sym):"<private>"); + +} + + + + + +const A pooldata::nullatom = { A_NULL }; + + + + + +V pooldata::Reset() + +{ + + root.Reset(); + +} + + + +BL pooldata::MkDir(const AtomList &d,I vcnt,I dcnt) + +{ + + root.AddDir(d,vcnt,dcnt); + + return true; + +} + + + +BL pooldata::ChkDir(const AtomList &d) + +{ + + return root.GetDir(d) != NULL; + +} + + + +BL pooldata::RmDir(const AtomList &d) + +{ + + return root.DelDir(d); + +} + + + +BL pooldata::Set(const AtomList &d,const A &key,AtomList *data,BL over) + +{ + + pooldir *pd = root.GetDir(d); + + if(!pd) return false; + + pd->SetVal(key,data,over); + + return true; + +} + + + +BL pooldata::Clr(const AtomList &d,const A &key) + +{ + + pooldir *pd = root.GetDir(d); + + if(!pd) return false; + + pd->ClrVal(key); + + return true; + +} + + + +BL pooldata::ClrAll(const AtomList &d,BL rec,BL dironly) + +{ + + pooldir *pd = root.GetDir(d); + + if(!pd) return false; + + pd->Clear(rec,dironly); + + return true; + +} + + + +flext::AtomList *pooldata::Peek(const AtomList &d,const A &key) + +{ + + pooldir *pd = root.GetDir(d); + + return pd?pd->PeekVal(key):NULL; + +} + + + +poolval *pooldata::Ref(const AtomList &d,const A &key) + +{ + + pooldir *pd = root.GetDir(d); + + return pd?pd->RefVal(key):NULL; + +} + + + +poolval *pooldata::Refi(const AtomList &d,I ix) + +{ + + pooldir *pd = root.GetDir(d); + + return pd?pd->RefVali(ix):NULL; + +} + + + +flext::AtomList *pooldata::Get(const AtomList &d,const A &key) + +{ + + pooldir *pd = root.GetDir(d); + + return pd?pd->GetVal(key):NULL; + +} + + + +I pooldata::CntAll(const AtomList &d) + +{ + + pooldir *pd = root.GetDir(d); + + return pd?pd->CntAll():0; + +} + + + +I pooldata::GetAll(const AtomList &d,A *&keys,AtomList *&lst) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) + + return pd->GetAll(keys,lst); + + else { + + keys = NULL; lst = NULL; + + return 0; + + } + +} + + + +I pooldata::CntSub(const AtomList &d) + +{ + + pooldir *pd = root.GetDir(d); + + return pd?pd->CntSub():0; + +} + + + +I pooldata::GetSub(const AtomList &d,const t_atom **&dirs) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) + + return pd->GetSub(dirs); + + else { + + dirs = NULL; + + return 0; + + } + +} + + + + + +BL pooldata::Paste(const AtomList &d,const pooldir *clip,I depth,BL repl,BL mkdir) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) + + return pd->Paste(clip,depth,repl,mkdir); + + else + + return false; + +} + + + +pooldir *pooldata::Copy(const AtomList &d,const A &key,BL cut) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) { + + AtomList *val = pd->GetVal(key,cut); + + if(val) { + + pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize()); + + ret->SetVal(key,val); + + return ret; + + } + + else + + return NULL; + + } + + else + + return NULL; + +} + + + +pooldir *pooldata::CopyAll(const AtomList &d,I depth,BL cut) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) { + + // What sizes should we choose here? + + pooldir *ret = new pooldir(nullatom,NULL,pd->VSize(),pd->DSize()); + + if(pd->Copy(ret,depth,cut)) + + return ret; + + else { + + delete ret; + + return NULL; + + } + + } + + else + + return NULL; + +} + + + + + +static const C *CnvFlnm(C *dst,const C *src,I sz) + +{ + +#if FLEXT_SYS == FLEXT_SYS_PD && FLEXT_OS == FLEXT_OS_WIN + + I i,cnt = strlen(src); + + if(cnt >= sz-1) return NULL; + + for(i = 0; i < cnt; ++i) + + dst[i] = src[i] != '/'?src[i]:'\\'; + + dst[i] = 0; + + return dst; + +#else + + return src; + +#endif + +} + + + +BL pooldata::LdDir(const AtomList &d,const C *flnm,I depth,BL mkdir) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) { + + C tmp[1024]; + + const C *t = CnvFlnm(tmp,flnm,sizeof tmp); + + if(t) { + + ifstream fl(t); + + return fl.good() && pd->LdDir(fl,depth,mkdir); + + } + + else return false; + + } + + else + + return false; + +} + + + +BL pooldata::SvDir(const AtomList &d,const C *flnm,I depth,BL absdir) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) { + + C tmp[1024]; + + const C *t = CnvFlnm(tmp,flnm,sizeof tmp); + + if(t) { + + ofstream fl(t); + + AtomList tmp; + + if(absdir) tmp = d; + + return fl.good() && pd->SvDir(fl,depth,tmp); + + } + + else return false; + + } + + else + + return false; + +} + + + +BL pooldata::LdDirXML(const AtomList &d,const C *flnm,I depth,BL mkdir) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) { + + C tmp[1024]; + + const C *t = CnvFlnm(tmp,flnm,sizeof tmp); + + if(t) { + + ifstream fl(t); + + BL ret = fl.good() != 0; + + if(ret) { + + fl.getline(tmp,sizeof tmp); + + ret = !strncmp(tmp,"<?xml",5); + + } + + if(ret) { + + fl.getline(tmp,sizeof tmp); + + // DOCTYPE need not be present / only external DOCTYPE is allowed! + + if(!strncmp(tmp,"<!DOCTYPE",9)) + + fl.getline(tmp,sizeof tmp); + + ret = !strncmp(tmp,"<pool>",6); + + } + + if(ret) + + ret = pd->LdDirXML(fl,depth,mkdir); + + return ret; + + } + + } + + + + return false; + +} + + + +BL pooldata::SvDirXML(const AtomList &d,const C *flnm,I depth,BL absdir) + +{ + + pooldir *pd = root.GetDir(d); + + if(pd) { + + C tmp[1024]; + + const C *t = CnvFlnm(tmp,flnm,sizeof tmp); + + if(t) { + + ofstream fl(t); + + AtomList tmp; + + if(absdir) tmp = d; + + if(fl.good()) { + + fl << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" << endl; + + fl << "<!DOCTYPE pool SYSTEM \"pool.dtd\">" << endl; + + fl << "<pool>" << endl; + + BL ret = pd->SvDirXML(fl,depth,tmp); + + fl << "</pool>" << endl; + + return ret; + + } + + } + + } + + + + return false; + +} + + + + + diff --git a/externals/grill/pool/makefile.pd-darwin b/externals/grill/pool/makefile.pd-darwin index fec83c27..5cc81b82 100644 --- a/externals/grill/pool/makefile.pd-darwin +++ b/externals/grill/pool/makefile.pd-darwin @@ -17,11 +17,11 @@ FLEXTLIB=$(FLEXTPATH)/flext.a # compiler+linker stuff INCLUDES=$(PDPATH) LIBPATH= -FLAGS=-DPD -Dunix -DMACOSX -Wno-unused -Wno-parentheses -Wno-switch -Wstrict-prototypes # -maltivec -CFLAGS=-O6 -#CFLAGS=-g +FLAGS=-DFLEXT_SYS=2 +CFLAGS=-O6 ${UFLAGS} -Wno-unused -Wno-parentheses -Wno-switch -Wstrict-prototypes LIBS=m LDFLAGS=-bundle -bundle_loader $(PD) +FRAMEWORKS=Carbon # --------------------------------------------- @@ -51,7 +51,7 @@ $(TARGDIR)/%.o : $(DIR)/%.cpp $(CXX) -c $(CFLAGS) $(FLAGS) $(patsubst %,-I%,$(INCLUDES) $(FLEXTPATH)) $< -o $@ $(TARGET) : $(patsubst %.cpp,$(TARGDIR)/%.o,$(SRCS)) $(FLEXTLIB) - $(CXX) $(LDFLAGS) $^ $(patsubst %,-L%,$(LIBPATH)) $(patsubst %,-l%,$(LIBS)) -o $@ + $(CXX) $(LDFLAGS) $^ $(patsubst %,-framework %,$(FRAMEWORKS)) $(patsubst %,-L%,$(LIBPATH)) $(patsubst %,-l%,$(LIBS)) -o $@ chmod 755 $@ $(INSTPATH): diff --git a/externals/grill/pool/pool.cpp b/externals/grill/pool/pool.cpp index 68c9a266..d48f4a7a 100644 --- a/externals/grill/pool/pool.cpp +++ b/externals/grill/pool/pool.cpp @@ -1,614 +1,1228 @@ -/*
-
-pool - hierarchical storage object for PD and Max/MSP
-
-Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net)
-For information on usage and redistribution, and for a DISCLAIMER OF ALL
-WARRANTIES, see the file, "license.txt," in this distribution.
-
-*/
-
-#include "pool.h"
-
-#include <string.h>
-#include <fstream.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#define VBITS 6
-#define DBITS 5
-
-inline I compare(I a,I b) { return a == b?0:(a < b?-1:1); }
-inline I compare(F a,F b) { return a == b?0:(a < b?-1:1); }
-
-static I compare(const S *a,const S *b)
-{
- if(a == b)
- return 0;
- else
- return strcmp(flext::GetString(a),flext::GetString(b));
-}
-
-static I compare(const A &a,const A &b)
-{
- if(flext::GetType(a) == flext::GetType(b)) {
- switch(flext::GetType(a)) {
- case A_FLOAT:
- return compare(flext::GetFloat(a),flext::GetFloat(b));
-#if FLEXT_SYS == FLEXT_SYS_MAX
- case A_LONG:
- return compare(flext::GetInt(a),flext::GetInt(b));
-#endif
- case A_SYMBOL:
- return compare(flext::GetSymbol(a),flext::GetSymbol(b));
-#if FLEXT_SYS == FLEXT_SYS_PD
- case A_POINTER:
- return flext::GetPointer(a) == flext::GetPointer(b)?0:(flext::GetPointer(a) < flext::GetPointer(b)?-1:1);
-#endif
- default:
- FLEXT_LOG("pool - atom comparison: type not handled");
- return -1;
- }
- }
- else
- return flext::GetType(a) < flext::GetType(b)?-1:1;
-}
-
-
-poolval::poolval(const A &k,AtomList *d):
- data(d),nxt(NULL)
-{
- SetAtom(key,k);
-}
-
-poolval::~poolval()
-{
- if(data) delete data;
- if(nxt) delete nxt;
-}
-
-poolval &poolval::Set(AtomList *d)
-{
- if(data) delete data;
- data = d;
- return *this;
-}
-
-poolval *poolval::Dup() const
-{
- return new poolval(key,data?new AtomList(*data):NULL);
-}
-
-
-pooldir::pooldir(const A &d,pooldir *p,I vcnt,I dcnt):
- parent(p),nxt(NULL),vals(NULL),dirs(NULL),
- vbits(vcnt?Int2Bits(vcnt):VBITS),dbits(dcnt?Int2Bits(dcnt):DBITS),
- vsize(1<<vbits),dsize(1<<dbits)
-{
- Reset();
- CopyAtom(&dir,&d);
-}
-
-pooldir::~pooldir()
-{
- Reset(false);
-
- if(nxt) delete nxt;
-}
-
-V pooldir::Clear(BL rec,BL dironly)
-{
- if(rec && dirs) {
- for(I i = 0; i < dsize; ++i) if(dirs[i].d) { delete dirs[i].d; dirs[i].d = NULL; }
- }
- if(!dironly && vals) {
- for(I i = 0; i < vsize; ++i) if(vals[i].v) { delete vals[i].v; vals[i].v = NULL; }
- }
-}
-
-V pooldir::Reset(BL realloc)
-{
- Clear(true,false);
-
- if(dirs) delete[] dirs;
- if(vals) delete[] vals;
-
- if(realloc) {
- dirs = new direntry[dsize];
- ZeroMem(dirs,dsize*sizeof *dirs);
- vals = new valentry[vsize];
- ZeroMem(vals,vsize*sizeof *vals);
- }
- else
- dirs = NULL,vals = NULL;
-}
-
-pooldir *pooldir::AddDir(I argc,const A *argv,I vcnt,I dcnt)
-{
- if(!argc) return this;
-
- I c = 1,dix = DIdx(argv[0]);
- pooldir *prv = NULL,*ix = dirs[dix].d;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(argv[0],ix->dir);
- if(c <= 0) break;
- }
-
- if(c || !ix) {
- pooldir *nd = new pooldir(argv[0],this,vcnt,dcnt);
- nd->nxt = ix;
-
- if(prv) prv->nxt = nd;
- else dirs[dix].d = nd;
- dirs[dix].cnt++;
- ix = nd;
- }
-
- return ix->AddDir(argc-1,argv+1);
-}
-
-pooldir *pooldir::GetDir(I argc,const A *argv,BL rmv)
-{
- if(!argc) return this;
-
- I c = 1,dix = DIdx(argv[0]);
- pooldir *prv = NULL,*ix = dirs[dix].d;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(argv[0],ix->dir);
- if(c <= 0) break;
- }
-
- if(c || !ix)
- return NULL;
- else {
- if(argc > 1)
- return ix->GetDir(argc-1,argv+1,rmv);
- else if(rmv) {
- pooldir *nd = ix->nxt;
- if(prv) prv->nxt = nd;
- else dirs[dix].d = nd;
- dirs[dix].cnt--;
- ix->nxt = NULL;
- return ix;
- }
- else
- return ix;
- }
-}
-
-BL pooldir::DelDir(I argc,const A *argv)
-{
- pooldir *pd = GetDir(argc,argv,true);
- if(pd && pd != this) {
- delete pd;
- return true;
- }
- else
- return false;
-}
-
-V pooldir::SetVal(const A &key,AtomList *data,BL over)
-{
- I c = 1,vix = VIdx(key);
- poolval *prv = NULL,*ix = vals[vix].v;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(key,ix->key);
- if(c <= 0) break;
- }
-
- if(c || !ix) {
- // no existing data found
-
- if(data) {
- poolval *nv = new poolval(key,data);
- nv->nxt = ix;
-
- if(prv) prv->nxt = nv;
- else vals[vix].v = nv;
- vals[vix].cnt++;
- }
- }
- else if(over) {
- // data exists... only set if overwriting enabled
-
- if(data)
- ix->Set(data);
- else {
- // delete key
-
- poolval *nv = ix->nxt;
- if(prv) prv->nxt = nv;
- else vals[vix].v = nv;
- vals[vix].cnt--;
- ix->nxt = NULL;
- delete ix;
- }
- }
-}
-
-poolval *pooldir::RefVal(const A &key)
-{
- I c = 1,vix = VIdx(key);
- poolval *ix = vals[vix].v;
- for(; ix; ix = ix->nxt) {
- c = compare(key,ix->key);
- if(c <= 0) break;
- }
-
- return c || !ix?NULL:ix;
-}
-
-
-poolval *pooldir::RefVali(I rix)
-{
- for(I vix = 0; vix < vsize; ++vix)
- if(rix > vals[vix].cnt) rix -= vals[vix].cnt;
- else {
- poolval *ix = vals[vix].v;
- for(; ix && rix; ix = ix->nxt) --rix;
- if(ix && !rix) return ix;
- }
- return NULL;
-}
-
-flext::AtomList *pooldir::PeekVal(const A &key)
-{
- poolval *ix = RefVal(key);
- return ix?ix->data:NULL;
-}
-
-flext::AtomList *pooldir::GetVal(const A &key,BL cut)
-{
- I c = 1,vix = VIdx(key);
- poolval *prv = NULL,*ix = vals[vix].v;
- for(; ix; prv = ix,ix = ix->nxt) {
- c = compare(key,ix->key);
- if(c <= 0) break;
- }
-
- if(c || !ix)
- return NULL;
- else {
- AtomList *ret;
- if(cut) {
- poolval *nv = ix->nxt;
- if(prv) prv->nxt = nv;
- else vals[vix].v = nv;
- vals[vix].cnt--;
- ix->nxt = NULL;
- ret = ix->data; ix->data = NULL;
- delete ix;
- }
- else
- ret = new AtomList(*ix->data);
- return ret;
- }
-}
-
-I pooldir::CntAll() const
-{
- I cnt = 0;
- for(I vix = 0; vix < vsize; ++vix) cnt += vals[vix].cnt;
- return cnt;
-}
-
-I pooldir::GetKeys(AtomList &keys)
-{
- I cnt = CntAll();
- keys(cnt);
-
- for(I vix = 0; vix < vsize; ++vix) {
- poolval *ix = vals[vix].v;
- for(I i = 0; ix; ++i,ix = ix->nxt)
- SetAtom(keys[i],ix->key);
- }
- return cnt;
-}
-
-I pooldir::GetAll(A *&keys,AtomList *&lst,BL cut)
-{
- I cnt = CntAll();
- keys = new A[cnt];
- lst = new AtomList[cnt];
-
- for(I i = 0,vix = 0; vix < vsize; ++vix) {
- poolval *ix = vals[vix].v;
- for(; ix; ++i) {
- SetAtom(keys[i],ix->key);
- lst[i] = *ix->data;
-
- if(cut) {
- poolval *t = ix;
- vals[vix].v = ix = ix->nxt;
- vals[vix].cnt--;
- t->nxt = NULL; delete t;
- }
- else
- ix = ix->nxt;
- }
- }
- return cnt;
-}
-
-
-I pooldir::CntSub() const
-{
- I cnt = 0;
- for(I dix = 0; dix < dsize; ++dix) cnt += dirs[dix].cnt;
- return cnt;
-}
-
-
-I pooldir::GetSub(const A **&lst)
-{
- const I cnt = CntSub();
- lst = new const A *[cnt];
- for(I i = 0,dix = 0; dix < dsize; ++dix) {
- pooldir *ix = dirs[dix].d;
- for(; ix; ix = ix->nxt) lst[i++] = &ix->dir;
- }
- return cnt;
-}
-
-
-BL pooldir::Paste(const pooldir *p,I depth,BL repl,BL mkdir)
-{
- BL ok = true;
-
- for(I vi = 0; vi < p->vsize; ++vi) {
- for(poolval *ix = p->vals[vi].v; ix; ix = ix->nxt) {
- SetVal(ix->key,new AtomList(*ix->data),repl);
- }
- }
-
- if(ok && depth) {
- for(I di = 0; di < p->dsize; ++di) {
- for(pooldir *dix = p->dirs[di].d; ok && dix; dix = dix->nxt) {
- pooldir *ndir = mkdir?AddDir(1,&dix->dir):GetDir(1,&dix->dir);
- if(ndir) {
- ok = ndir->Paste(dix,depth > 0?depth-1:depth,repl,mkdir);
- }
- }
- }
- }
-
- return ok;
-}
-
-BL pooldir::Copy(pooldir *p,I depth,BL cut)
-{
- BL ok = true;
-
- if(cut) {
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt)
- p->SetVal(ix->key,ix->data);
- vals[vi].cnt = 0;
- vals[vi].v = NULL;
- }
- }
- else {
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
- p->SetVal(ix->key,new AtomList(*ix->data));
- }
- }
- }
-
- if(ok && depth) {
- for(I di = 0; di < dsize; ++di) {
- for(pooldir *dix = dirs[di].d; ok && dix; dix = dix->nxt) {
- pooldir *ndir = p->AddDir(1,&dix->dir);
- if(ndir)
- ok = ndir->Copy(dix,depth > 0?depth-1:depth,cut);
- else
- ok = false;
- }
- }
- }
-
- return ok;
-}
-
-
-static C *ReadAtom(C *c,A *a)
-{
- // skip whitespace
- while(*c && isspace(*c)) ++c;
- if(!*c) return NULL;
-
- const C *m = c; // remember position
-
- // check for word type (s = 0,1,2 ... int,float,symbol)
- I s = 0;
- for(; *c && !isspace(*c); ++c) {
- if(!isdigit(*c))
- s = (*c != '.' || s == 1)?2:1;
- }
-
- if(a) {
- switch(s) {
- case 0: // integer
-#if FLEXT_SYS == FLEXT_SYS_MAX
- flext::SetInt(*a,atoi(m));
- break;
-#endif
- case 1: // float
- flext::SetFloat(*a,(F)atof(m));
- break;
- default: { // anything else is a symbol
- C t = *c; *c = 0;
- flext::SetString(*a,m);
- *c = t;
- break;
- }
- }
- }
-
- return c;
-}
-
-static BL ReadAtoms(istream &is,flext::AtomList &l,C del)
-{
- C tmp[1024];
- is.getline(tmp,sizeof tmp,del);
- if(is.eof() || !is.good()) return false;
-
- I i,cnt;
- C *t = tmp;
- for(cnt = 0; ; ++cnt) {
- t = ReadAtom(t,NULL);
- if(!t) break;
- }
-
- l(cnt);
- if(cnt) {
- for(i = 0,t = tmp; i < cnt; ++i)
- t = ReadAtom(t,&l[i]);
- }
- return true;
-}
-
-static V WriteAtom(ostream &os,const A &a)
-{
- switch(a.a_type) {
- case A_FLOAT:
- os << a.a_w.w_float;
- break;
-#if FLEXT_SYS == FLEXT_SYS_MAX
- case A_LONG:
- os << a.a_w.w_long;
- break;
-#endif
- case A_SYMBOL:
- os << flext::GetString(flext::GetSymbol(a));
- break;
- }
-}
-
-static V WriteAtoms(ostream &os,const flext::AtomList &l)
-{
- for(I i = 0; i < l.Count(); ++i) {
-// if(IsSymbol(l[i]) os << "\"";
- WriteAtom(os,l[i]);
-// if(IsSymbol(l[i]) os << "\"";
- if(i < l.Count()-1) os << ' ';
- }
-}
-
-BL pooldir::LdDir(istream &is,I depth,BL mkdir)
-{
- for(I i = 1; !is.eof(); ++i) {
- AtomList d,k,*v = new AtomList;
- BL r = ReadAtoms(is,d,',');
- r = r && ReadAtoms(is,k,',') && k.Count() == 1;
- r = r && ReadAtoms(is,*v,'\n') && v->Count();
-
- if(r) {
- if(depth < 0 || d.Count() <= depth) {
- pooldir *nd = mkdir?AddDir(d):GetDir(d);
- if(nd) {
- nd->SetVal(k[0],v); v = NULL;
- }
- #ifdef FLEXT_DEBUG
- else
- post("pool - directory was not found",i);
- #endif
- }
- }
- else if(!is.eof())
- post("pool - format mismatch encountered, skipped line %i",i);
-
- if(v) delete v;
- }
- return true;
-}
-
-BL pooldir::SvDir(ostream &os,I depth,const AtomList &dir)
-{
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
- WriteAtoms(os,dir);
- os << " , ";
- WriteAtom(os,ix->key);
- os << " , ";
- WriteAtoms(os,*ix->data);
- os << endl;
- }
- }
- if(depth) {
- I nd = depth > 0?depth-1:-1;
- for(I di = 0; di < dsize; ++di) {
- for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) {
- ix->SvDir(os,nd,AtomList(dir).Append(ix->dir));
- }
- }
- }
- return true;
-}
-
-BL pooldir::LdDirXML(istream &is,I depth,BL mkdir)
-{
-/*
- for(I i = 1; !is.eof(); ++i) {
- AtomList d,k,*v = new AtomList;
- BL r = ReadAtoms(is,d,',');
- r = r && ReadAtoms(is,k,',') && k.Count() == 1;
- r = r && ReadAtoms(is,*v,'\n') && v->Count();
-
- if(r) {
- if(depth < 0 || d.Count() <= depth) {
- pooldir *nd = mkdir?AddDir(d):GetDir(d);
- if(nd) {
- nd->SetVal(k[0],v); v = NULL;
- }
- #ifdef FLEXT_DEBUG
- else
- post("pool - directory was not found",i);
- #endif
- }
- }
- else if(!is.eof())
- post("pool - format mismatch encountered, skipped line %i",i);
-
- if(v) delete v;
- }
- return true;
-*/
- return false;
-}
-
-BL pooldir::SvDirXML(ostream &os,I depth,const AtomList &dir)
-{
- if(dir.Count()) {
- os << "<dir key=\"";
- WriteAtom(os,dir[dir.Count()-1]);
- os << "\">" << endl;
- }
-
- for(I vi = 0; vi < vsize; ++vi) {
- for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) {
- os << "<value key=\"";
- WriteAtom(os,ix->key);
- os << "\">";
- WriteAtoms(os,*ix->data);
- os << "</value>" << endl;
- }
- }
-
- if(depth) {
- I nd = depth > 0?depth-1:-1;
- for(I di = 0; di < dsize; ++di) {
- for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) {
- ix->SvDirXML(os,nd,AtomList(dir).Append(ix->dir));
- }
- }
- }
-
- if(dir.Count()) os << "</dir>" << endl;
- return true;
-}
-
-
-
-
+/* + + + +pool - hierarchical storage object for PD and Max/MSP + + + +Copyright (c) 2002-2003 Thomas Grill (xovo@gmx.net) + +For information on usage and redistribution, and for a DISCLAIMER OF ALL + +WARRANTIES, see the file, "license.txt," in this distribution. + + + +*/ + + + +#include "pool.h" + + + +#include <string.h> + +#include <fstream.h> + +#include <ctype.h> + +#include <stdlib.h> + + + +#define VBITS 6 + +#define DBITS 5 + + + +inline I compare(I a,I b) { return a == b?0:(a < b?-1:1); } + +inline I compare(F a,F b) { return a == b?0:(a < b?-1:1); } + + + +static I compare(const S *a,const S *b) + +{ + + if(a == b) + + return 0; + + else + + return strcmp(flext::GetString(a),flext::GetString(b)); + +} + + + +static I compare(const A &a,const A &b) + +{ + + if(flext::GetType(a) == flext::GetType(b)) { + + switch(flext::GetType(a)) { + + case A_FLOAT: + + return compare(flext::GetFloat(a),flext::GetFloat(b)); + +#if FLEXT_SYS == FLEXT_SYS_MAX + + case A_LONG: + + return compare(flext::GetInt(a),flext::GetInt(b)); + +#endif + + case A_SYMBOL: + + return compare(flext::GetSymbol(a),flext::GetSymbol(b)); + +#if FLEXT_SYS == FLEXT_SYS_PD + + case A_POINTER: + + return flext::GetPointer(a) == flext::GetPointer(b)?0:(flext::GetPointer(a) < flext::GetPointer(b)?-1:1); + +#endif + + default: + + FLEXT_LOG("pool - atom comparison: type not handled"); + + return -1; + + } + + } + + else + + return flext::GetType(a) < flext::GetType(b)?-1:1; + +} + + + + + +poolval::poolval(const A &k,AtomList *d): + + data(d),nxt(NULL) + +{ + + SetAtom(key,k); + +} + + + +poolval::~poolval() + +{ + + if(data) delete data; + + if(nxt) delete nxt; + +} + + + +poolval &poolval::Set(AtomList *d) + +{ + + if(data) delete data; + + data = d; + + return *this; + +} + + + +poolval *poolval::Dup() const + +{ + + return new poolval(key,data?new AtomList(*data):NULL); + +} + + + + + +pooldir::pooldir(const A &d,pooldir *p,I vcnt,I dcnt): + + parent(p),nxt(NULL),vals(NULL),dirs(NULL), + + vbits(vcnt?Int2Bits(vcnt):VBITS),dbits(dcnt?Int2Bits(dcnt):DBITS), + + vsize(1<<vbits),dsize(1<<dbits) + +{ + + Reset(); + + CopyAtom(&dir,&d); + +} + + + +pooldir::~pooldir() + +{ + + Reset(false); + + + + if(nxt) delete nxt; + +} + + + +V pooldir::Clear(BL rec,BL dironly) + +{ + + if(rec && dirs) { + + for(I i = 0; i < dsize; ++i) if(dirs[i].d) { delete dirs[i].d; dirs[i].d = NULL; } + + } + + if(!dironly && vals) { + + for(I i = 0; i < vsize; ++i) if(vals[i].v) { delete vals[i].v; vals[i].v = NULL; } + + } + +} + + + +V pooldir::Reset(BL realloc) + +{ + + Clear(true,false); + + + + if(dirs) delete[] dirs; + + if(vals) delete[] vals; + + + + if(realloc) { + + dirs = new direntry[dsize]; + + ZeroMem(dirs,dsize*sizeof *dirs); + + vals = new valentry[vsize]; + + ZeroMem(vals,vsize*sizeof *vals); + + } + + else + + dirs = NULL,vals = NULL; + +} + + + +pooldir *pooldir::AddDir(I argc,const A *argv,I vcnt,I dcnt) + +{ + + if(!argc) return this; + + + + I c = 1,dix = DIdx(argv[0]); + + pooldir *prv = NULL,*ix = dirs[dix].d; + + for(; ix; prv = ix,ix = ix->nxt) { + + c = compare(argv[0],ix->dir); + + if(c <= 0) break; + + } + + + + if(c || !ix) { + + pooldir *nd = new pooldir(argv[0],this,vcnt,dcnt); + + nd->nxt = ix; + + + + if(prv) prv->nxt = nd; + + else dirs[dix].d = nd; + + dirs[dix].cnt++; + + ix = nd; + + } + + + + return ix->AddDir(argc-1,argv+1); + +} + + + +pooldir *pooldir::GetDir(I argc,const A *argv,BL rmv) + +{ + + if(!argc) return this; + + + + I c = 1,dix = DIdx(argv[0]); + + pooldir *prv = NULL,*ix = dirs[dix].d; + + for(; ix; prv = ix,ix = ix->nxt) { + + c = compare(argv[0],ix->dir); + + if(c <= 0) break; + + } + + + + if(c || !ix) + + return NULL; + + else { + + if(argc > 1) + + return ix->GetDir(argc-1,argv+1,rmv); + + else if(rmv) { + + pooldir *nd = ix->nxt; + + if(prv) prv->nxt = nd; + + else dirs[dix].d = nd; + + dirs[dix].cnt--; + + ix->nxt = NULL; + + return ix; + + } + + else + + return ix; + + } + +} + + + +BL pooldir::DelDir(I argc,const A *argv) + +{ + + pooldir *pd = GetDir(argc,argv,true); + + if(pd && pd != this) { + + delete pd; + + return true; + + } + + else + + return false; + +} + + + +V pooldir::SetVal(const A &key,AtomList *data,BL over) + +{ + + I c = 1,vix = VIdx(key); + + poolval *prv = NULL,*ix = vals[vix].v; + + for(; ix; prv = ix,ix = ix->nxt) { + + c = compare(key,ix->key); + + if(c <= 0) break; + + } + + + + if(c || !ix) { + + // no existing data found + + + + if(data) { + + poolval *nv = new poolval(key,data); + + nv->nxt = ix; + + + + if(prv) prv->nxt = nv; + + else vals[vix].v = nv; + + vals[vix].cnt++; + + } + + } + + else if(over) { + + // data exists... only set if overwriting enabled + + + + if(data) + + ix->Set(data); + + else { + + // delete key + + + + poolval *nv = ix->nxt; + + if(prv) prv->nxt = nv; + + else vals[vix].v = nv; + + vals[vix].cnt--; + + ix->nxt = NULL; + + delete ix; + + } + + } + +} + + + +poolval *pooldir::RefVal(const A &key) + +{ + + I c = 1,vix = VIdx(key); + + poolval *ix = vals[vix].v; + + for(; ix; ix = ix->nxt) { + + c = compare(key,ix->key); + + if(c <= 0) break; + + } + + + + return c || !ix?NULL:ix; + +} + + + + + +poolval *pooldir::RefVali(I rix) + +{ + + for(I vix = 0; vix < vsize; ++vix) + + if(rix > vals[vix].cnt) rix -= vals[vix].cnt; + + else { + + poolval *ix = vals[vix].v; + + for(; ix && rix; ix = ix->nxt) --rix; + + if(ix && !rix) return ix; + + } + + return NULL; + +} + + + +flext::AtomList *pooldir::PeekVal(const A &key) + +{ + + poolval *ix = RefVal(key); + + return ix?ix->data:NULL; + +} + + + +flext::AtomList *pooldir::GetVal(const A &key,BL cut) + +{ + + I c = 1,vix = VIdx(key); + + poolval *prv = NULL,*ix = vals[vix].v; + + for(; ix; prv = ix,ix = ix->nxt) { + + c = compare(key,ix->key); + + if(c <= 0) break; + + } + + + + if(c || !ix) + + return NULL; + + else { + + AtomList *ret; + + if(cut) { + + poolval *nv = ix->nxt; + + if(prv) prv->nxt = nv; + + else vals[vix].v = nv; + + vals[vix].cnt--; + + ix->nxt = NULL; + + ret = ix->data; ix->data = NULL; + + delete ix; + + } + + else + + ret = new AtomList(*ix->data); + + return ret; + + } + +} + + + +I pooldir::CntAll() const + +{ + + I cnt = 0; + + for(I vix = 0; vix < vsize; ++vix) cnt += vals[vix].cnt; + + return cnt; + +} + + + +I pooldir::GetKeys(AtomList &keys) + +{ + + I cnt = CntAll(); + + keys(cnt); + + + + for(I vix = 0; vix < vsize; ++vix) { + + poolval *ix = vals[vix].v; + + for(I i = 0; ix; ++i,ix = ix->nxt) + + SetAtom(keys[i],ix->key); + + } + + return cnt; + +} + + + +I pooldir::GetAll(A *&keys,AtomList *&lst,BL cut) + +{ + + I cnt = CntAll(); + + keys = new A[cnt]; + + lst = new AtomList[cnt]; + + + + for(I i = 0,vix = 0; vix < vsize; ++vix) { + + poolval *ix = vals[vix].v; + + for(; ix; ++i) { + + SetAtom(keys[i],ix->key); + + lst[i] = *ix->data; + + + + if(cut) { + + poolval *t = ix; + + vals[vix].v = ix = ix->nxt; + + vals[vix].cnt--; + + t->nxt = NULL; delete t; + + } + + else + + ix = ix->nxt; + + } + + } + + return cnt; + +} + + + + + +I pooldir::CntSub() const + +{ + + I cnt = 0; + + for(I dix = 0; dix < dsize; ++dix) cnt += dirs[dix].cnt; + + return cnt; + +} + + + + + +I pooldir::GetSub(const A **&lst) + +{ + + const I cnt = CntSub(); + + lst = new const A *[cnt]; + + for(I i = 0,dix = 0; dix < dsize; ++dix) { + + pooldir *ix = dirs[dix].d; + + for(; ix; ix = ix->nxt) lst[i++] = &ix->dir; + + } + + return cnt; + +} + + + + + +BL pooldir::Paste(const pooldir *p,I depth,BL repl,BL mkdir) + +{ + + BL ok = true; + + + + for(I vi = 0; vi < p->vsize; ++vi) { + + for(poolval *ix = p->vals[vi].v; ix; ix = ix->nxt) { + + SetVal(ix->key,new AtomList(*ix->data),repl); + + } + + } + + + + if(ok && depth) { + + for(I di = 0; di < p->dsize; ++di) { + + for(pooldir *dix = p->dirs[di].d; ok && dix; dix = dix->nxt) { + + pooldir *ndir = mkdir?AddDir(1,&dix->dir):GetDir(1,&dix->dir); + + if(ndir) { + + ok = ndir->Paste(dix,depth > 0?depth-1:depth,repl,mkdir); + + } + + } + + } + + } + + + + return ok; + +} + + + +BL pooldir::Copy(pooldir *p,I depth,BL cut) + +{ + + BL ok = true; + + + + if(cut) { + + for(I vi = 0; vi < vsize; ++vi) { + + for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) + + p->SetVal(ix->key,ix->data); + + vals[vi].cnt = 0; + + vals[vi].v = NULL; + + } + + } + + else { + + for(I vi = 0; vi < vsize; ++vi) { + + for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { + + p->SetVal(ix->key,new AtomList(*ix->data)); + + } + + } + + } + + + + if(ok && depth) { + + for(I di = 0; di < dsize; ++di) { + + for(pooldir *dix = dirs[di].d; ok && dix; dix = dix->nxt) { + + pooldir *ndir = p->AddDir(1,&dix->dir); + + if(ndir) + + ok = ndir->Copy(dix,depth > 0?depth-1:depth,cut); + + else + + ok = false; + + } + + } + + } + + + + return ok; + +} + + + + + +static C *ReadAtom(C *c,A *a) + +{ + + // skip whitespace + + while(*c && isspace(*c)) ++c; + + if(!*c) return NULL; + + + + const C *m = c; // remember position + + + + // check for word type (s = 0,1,2 ... int,float,symbol) + + I s = 0; + + for(; *c && !isspace(*c); ++c) { + + if(!isdigit(*c)) + + s = (*c != '.' || s == 1)?2:1; + + } + + + + if(a) { + + switch(s) { + + case 0: // integer + +#if FLEXT_SYS == FLEXT_SYS_MAX + + flext::SetInt(*a,atoi(m)); + + break; + +#endif + + case 1: // float + + flext::SetFloat(*a,(F)atof(m)); + + break; + + default: { // anything else is a symbol + + C t = *c; *c = 0; + + flext::SetString(*a,m); + + *c = t; + + break; + + } + + } + + } + + + + return c; + +} + + + +static BL ReadAtoms(istream &is,flext::AtomList &l,C del) + +{ + + C tmp[1024]; + + is.getline(tmp,sizeof tmp,del); + + if(is.eof() || !is.good()) return false; + + + + I i,cnt; + + C *t = tmp; + + for(cnt = 0; ; ++cnt) { + + t = ReadAtom(t,NULL); + + if(!t) break; + + } + + + + l(cnt); + + if(cnt) { + + for(i = 0,t = tmp; i < cnt; ++i) + + t = ReadAtom(t,&l[i]); + + } + + return true; + +} + + + +static V WriteAtom(ostream &os,const A &a) + +{ + + switch(a.a_type) { + + case A_FLOAT: + + os << a.a_w.w_float; + + break; + +#if FLEXT_SYS == FLEXT_SYS_MAX + + case A_LONG: + + os << a.a_w.w_long; + + break; + +#endif + + case A_SYMBOL: + + os << flext::GetString(flext::GetSymbol(a)); + + break; + + } + +} + + + +static V WriteAtoms(ostream &os,const flext::AtomList &l) + +{ + + for(I i = 0; i < l.Count(); ++i) { + +// if(IsSymbol(l[i]) os << "\""; + + WriteAtom(os,l[i]); + +// if(IsSymbol(l[i]) os << "\""; + + if(i < l.Count()-1) os << ' '; + + } + +} + + + +BL pooldir::LdDir(istream &is,I depth,BL mkdir) + +{ + + for(I i = 1; !is.eof(); ++i) { + + AtomList d,k,*v = new AtomList; + + BL r = ReadAtoms(is,d,','); + + r = r && ReadAtoms(is,k,',') && k.Count() == 1; + + r = r && ReadAtoms(is,*v,'\n') && v->Count(); + + + + if(r) { + + if(depth < 0 || d.Count() <= depth) { + + pooldir *nd = mkdir?AddDir(d):GetDir(d); + + if(nd) { + + nd->SetVal(k[0],v); v = NULL; + + } + + #ifdef FLEXT_DEBUG + + else + + post("pool - directory was not found",i); + + #endif + + } + + } + + else if(!is.eof()) + + post("pool - format mismatch encountered, skipped line %i",i); + + + + if(v) delete v; + + } + + return true; + +} + + + +BL pooldir::SvDir(ostream &os,I depth,const AtomList &dir) + +{ + + for(I vi = 0; vi < vsize; ++vi) { + + for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { + + WriteAtoms(os,dir); + + os << " , "; + + WriteAtom(os,ix->key); + + os << " , "; + + WriteAtoms(os,*ix->data); + + os << endl; + + } + + } + + if(depth) { + + I nd = depth > 0?depth-1:-1; + + for(I di = 0; di < dsize; ++di) { + + for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) { + + ix->SvDir(os,nd,AtomList(dir).Append(ix->dir)); + + } + + } + + } + + return true; + +} + + + +BL pooldir::LdDirXML(istream &is,I depth,BL mkdir) + +{ + +/* + + for(I i = 1; !is.eof(); ++i) { + + AtomList d,k,*v = new AtomList; + + BL r = ReadAtoms(is,d,','); + + r = r && ReadAtoms(is,k,',') && k.Count() == 1; + + r = r && ReadAtoms(is,*v,'\n') && v->Count(); + + + + if(r) { + + if(depth < 0 || d.Count() <= depth) { + + pooldir *nd = mkdir?AddDir(d):GetDir(d); + + if(nd) { + + nd->SetVal(k[0],v); v = NULL; + + } + + #ifdef FLEXT_DEBUG + + else + + post("pool - directory was not found",i); + + #endif + + } + + } + + else if(!is.eof()) + + post("pool - format mismatch encountered, skipped line %i",i); + + + + if(v) delete v; + + } + + return true; + +*/ + + return false; + +} + + + +BL pooldir::SvDirXML(ostream &os,I depth,const AtomList &dir) + +{ + + if(dir.Count()) { + + os << "<dir key=\""; + + WriteAtom(os,dir[dir.Count()-1]); + + os << "\">" << endl; + + } + + + + for(I vi = 0; vi < vsize; ++vi) { + + for(poolval *ix = vals[vi].v; ix; ix = ix->nxt) { + + os << "<value key=\""; + + WriteAtom(os,ix->key); + + os << "\">"; + + WriteAtoms(os,*ix->data); + + os << "</value>" << endl; + + } + + } + + + + if(depth) { + + I nd = depth > 0?depth-1:-1; + + for(I di = 0; di < dsize; ++di) { + + for(pooldir *ix = dirs[di].d; ix; ix = ix->nxt) { + + ix->SvDirXML(os,nd,AtomList(dir).Append(ix->dir)); + + } + + } + + } + + + + if(dir.Count()) os << "</dir>" << endl; + + return true; + +} + + + + + + + + + |