aboutsummaryrefslogtreecommitdiff
path: root/externals/grill/pool
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2003-03-12 04:40:48 +0000
committerThomas Grill <xovo@users.sourceforge.net>2003-03-12 04:40:48 +0000
commit72312b8ee69c00c50a7e7470a3147ff627d98410 (patch)
tree629df0e3fbb1e97ee483e6c5f35e4fecca0c2570 /externals/grill/pool
parentd65dcff92fe76c0ff5053f81f80df32f496dc371 (diff)
""
svn path=/trunk/; revision=466
Diffstat (limited to 'externals/grill/pool')
-rw-r--r--externals/grill/pool/build-pd-darwin.sh2
-rw-r--r--externals/grill/pool/config-pd-darwin.txt57
-rw-r--r--externals/grill/pool/data.cpp852
-rw-r--r--externals/grill/pool/makefile.pd-darwin8
-rw-r--r--externals/grill/pool/pool.cpp1842
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;
+
+}
+
+
+
+
+
+
+
+
+