From 1d6d1e8c73193f57a9c98387ea42eb91eb4d21d1 Mon Sep 17 00:00:00 2001 From: Georg Holzmann Date: Fri, 21 Oct 2005 11:56:32 +0000 Subject: only moving to a new directory svn path=/trunk/externals/grh/; revision=3740 --- PDContainer/include/ContainerBase.h | 136 ++++++++ PDContainer/include/GlobalStuff.h | 274 +++++++++++++++ PDContainer/include/HDeque.h | 80 +++++ PDContainer/include/HList.h | 250 ++++++++++++++ PDContainer/include/HMap.h | 67 ++++ PDContainer/include/HMultiMap.h | 80 +++++ PDContainer/include/HMultiSet.h | 81 +++++ PDContainer/include/HPrioQueue.h | 100 ++++++ PDContainer/include/HQueue.h | 77 +++++ PDContainer/include/HSet.h | 82 +++++ PDContainer/include/HStack.h | 77 +++++ PDContainer/include/HVector.h | 66 ++++ PDContainer/include/MapBase.h | 655 ++++++++++++++++++++++++++++++++++++ PDContainer/include/QueueStack.h | 61 ++++ PDContainer/include/SequBase.h | 341 +++++++++++++++++++ PDContainer/include/SimpleBase.h | 539 +++++++++++++++++++++++++++++ 16 files changed, 2966 insertions(+) create mode 100755 PDContainer/include/ContainerBase.h create mode 100755 PDContainer/include/GlobalStuff.h create mode 100755 PDContainer/include/HDeque.h create mode 100755 PDContainer/include/HList.h create mode 100755 PDContainer/include/HMap.h create mode 100755 PDContainer/include/HMultiMap.h create mode 100755 PDContainer/include/HMultiSet.h create mode 100755 PDContainer/include/HPrioQueue.h create mode 100755 PDContainer/include/HQueue.h create mode 100755 PDContainer/include/HSet.h create mode 100755 PDContainer/include/HStack.h create mode 100755 PDContainer/include/HVector.h create mode 100755 PDContainer/include/MapBase.h create mode 100755 PDContainer/include/QueueStack.h create mode 100755 PDContainer/include/SequBase.h create mode 100755 PDContainer/include/SimpleBase.h (limited to 'PDContainer/include') diff --git a/PDContainer/include/ContainerBase.h b/PDContainer/include/ContainerBase.h new file mode 100755 index 0000000..c32a22a --- /dev/null +++ b/PDContainer/include/ContainerBase.h @@ -0,0 +1,136 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// ContainerBase.h + + +#ifndef _container_base_h___ +#define _container_base_h___ + + +#include "include/GlobalStuff.h" +#include + +using std::map; + + +//--------------------------------------------------- +/* this is the base class of all the containers + */ +template +class ContainerBase +{ + protected: + + /* this is the static container with all the datas + * the string is the namespace of the Container + */ + static map data_; + + /* holds the number of the current namespace + * (the string of the namespace is stored in the map above) + */ + string h_namespace_; + + /* this string is the name of the datatype + * (e.g. h_set, h_map, ...) + */ + string dataname_; + + private: + + /* Copy Construction is not allowed + */ + ContainerBase(const ContainerBase &src) + { } + + /* assignement operator is not allowed + */ + const ContainerBase& operator = + (const ContainerBase&) + { } + + public: + + /* Standard Constructor + * no namespace + */ + ContainerBase() + { } + + /* Destructor + */ + virtual ~ContainerBase() + { } + + /* sets the namespace variable + */ + void setNamespace(string h_namespace) + { + h_namespace_ = h_namespace; + //ContainerType container; + //data_.insert(std::pair(h_namespace_,container)); + } + + /* get the namespace string + */ + string getNamespace() const + { return h_namespace_; } + + /* prints out the help text + */ + virtual void help(); + + /* clears all the data of the current namespaces + * in all objects from the same container + */ + virtual void clearNamespace() + { data_.erase(h_namespace_); } + + /* clears all the data of the current container + * ( in all namespaces !!!!! ) + * so be carefull !!! + */ + virtual void clearAll() + { data_.clear(); } + + /* get the size of the container + */ + virtual int getSize() const + { return data_[h_namespace_].size(); } +}; + + +//--------------------------------------------------- +/* defines the static members + */ +template +map ContainerBase::data_; + +//--------------------------------------------------- +/* prints out the help text + */ +template +void ContainerBase::help() +{ + post("\nPD-Container, Version: "PDC_VERSION""); + post("object: %s",dataname_.c_str()); + post("------------------------------------------"); + post("this is an implementation of the container"); + post("objects from the Standard Template"); + post("Library (STL) of C++"); + post("for documentation see the help patches"); + post("(by Georg Holzmann , 2004-2005)"); + post("------------------------------------------\n"); +} + + + +#endif //_container_base_h___ diff --git a/PDContainer/include/GlobalStuff.h b/PDContainer/include/GlobalStuff.h new file mode 100755 index 0000000..6cb96cc --- /dev/null +++ b/PDContainer/include/GlobalStuff.h @@ -0,0 +1,274 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// GlobalStuff.h + + +#ifndef _global_stuff_h___ +#define _global_stuff_h___ + + +#include "m_pd.h" +#include +#include +#include +#include +#include +//#include //DEBUG + +using std::string; +using std::ostringstream; +using std::istringstream; +using std::ofstream; +using std::ifstream; +using std::endl; + + +// current version +#define PDC_VERSION "0.2" + + +// TinyXML +//#define TIXML_USE_STL +#include "tinyxml/tinyxml.h" + + +//--------------------------------------------------- +/* This function compares two pd t_atoms + */ +static bool compareAtoms(t_atom &atom1, t_atom &atom2) +{ + if(atom1.a_type == A_FLOAT && atom2.a_type == A_FLOAT) + return (atom1.a_w.w_float == atom2.a_w.w_float); + + if(atom1.a_type == A_SYMBOL && atom2.a_type == A_SYMBOL) + return (strcmp(atom1.a_w.w_symbol->s_name, + atom2.a_w.w_symbol->s_name) == 0); + + if(atom1.a_type == A_POINTER && atom2.a_type == A_POINTER) + return (atom1.a_w.w_gpointer == atom2.a_w.w_gpointer); + + return false; +} + + +//--------------------------------------------------- +/* one Element holds one data element, which can be + * a list, a float or a symbol + */ +class Element +{ + private: + t_atom *atom; + int length; + + public: + Element() : atom(NULL), length(0) + { } + + Element(int size_, t_atom *atom_) : atom(NULL), length(0) + { + if(atom_ && size_) + { + length = size_; + + // !!!! FIXME !!!! + // hack to avoid lockating too much memory + // (somewhere I read an uninitialized value ... + // ... but where !?) + if(length>999) + { + post("Element, constr1: invalid construction !!! should be fixed !!!"); + length=0; + atom=NULL; + return; + } + + atom = (t_atom*)copybytes(atom_, length*sizeof(t_atom)); + } + } + + // Copy Constr. + Element(const Element &src) : atom(NULL), length(0) + { + if(src.atom) + { + length = src.length; + + // !!!! FIXME !!!! + // hack to avoid lockating too much memory + // (somewhere I read an uninitialized value ... + // ... but where !?) + if(length>999) + { + post("Element, constr2: invalid construction !!! should be fixed !!!"); + length=0; + atom=NULL; + return; + } + + atom = (t_atom*)copybytes(src.atom, length*sizeof(t_atom)); + } + } + + // Destructor + ~Element() + { + if(atom) + freebytes(atom, length*sizeof(t_atom)); + } + + // set atoms and length + void setAtoms(int size_, t_atom *atom_) + { + if(atom) + { + freebytes(atom, length*sizeof(t_atom)); + length=0; + atom=NULL; + } + + if(atom_) + { + length = size_; + + // !!!! FIXME !!!! + // hack to avoid lockating too much memory + // (somewhere I read an uninitialized value ... + // ... but where !?) + if(length>999) + { + post("Element, setAtoms: invalid construction !!! should be fixed !!!"); + length=0; + atom=NULL; + return; + } + + atom = (t_atom*)copybytes(atom_, length*sizeof(t_atom)); + } + } + + int getLength() + { return length; } + + // shallow copy !!! + t_atom *getAtom() + { return atom; } + + //Assignement Operator + const Element& operator = (const Element &src) + { + if(atom) + { + freebytes(atom, length*sizeof(t_atom)); + length=0; + atom=NULL; + } + + if(src.atom) + { + length = src.length; + + // !!!! FIXME !!!! + // hack to avoid lockating too much memory + // (somewhere I read an uninitialized value ... + // ... but where !?) + if(length>999) + { + post("Element, assignment: invalid construction !!! should be fixed !!!"); + length=0; + atom=NULL; + return (*this); + } + + atom = (t_atom*)copybytes(src.atom, length*sizeof(t_atom)); + } + + return (*this); + } + + // operator== to compare the objects + bool operator== (const Element &key) const + { + if (length != key.length) + return false; + + for (int i=0; i < length; i++) + { + if(!compareAtoms(atom[i],key.atom[i])) + return false; + } + + return true; + } + + // operator< to compare the objects + // (needed by map, set, ...) + bool operator< (const Element &key) const + { + if (length == key.length) + { + bool difference = false; + int index; + + for (index = 0; indexs_name, + key.atom[index].a_w.w_symbol->s_name) < 0); + + if( atom[index].a_type == A_POINTER + && key.atom[index].a_type == A_POINTER ) + return (atom[index].a_w.w_gpointer < key.atom[index].a_w.w_gpointer); + + return false; + } // different length + else + return (length < key.length); + + } +}; + + +#endif //_global_stuff_h___ diff --git a/PDContainer/include/HDeque.h b/PDContainer/include/HDeque.h new file mode 100755 index 0000000..02600cf --- /dev/null +++ b/PDContainer/include/HDeque.h @@ -0,0 +1,80 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HDeque.h + +#ifndef _h_deque_h__ +#define _h_deque_h__ + + +#include "include/SequBase.h" +#include + +using std::deque; + + +//--------------------------------------------------- +/* this is the class of the deque + */ +class HDeque : +public SequBase< deque, deque::iterator > +{ + + private: + + /* Copy Construction is not allowed + */ + HDeque(const HDeque &src) + { } + + /* assignement operator is not allowed + */ + const HDeque& operator = (const HDeque&) + { return *this; } + + public: + + /* Standard Constructor + * no namespace + */ + HDeque() + { dataname_ = "h_deque"; } + + /* Constructor + * with a namespace + */ + HDeque(string h_namespace) + { + dataname_ = "h_deque"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HDeque() { } + + /* inserts an element at the front of + * the container (so then the size + * increases by one !!!) + */ + virtual void pushFront(Element value) + { data_[h_namespace_].push_front(value); } + + /* removes the element from the front of + * the container (so then the size + * decreases by one !!!) + */ + virtual void popFront() + { data_[h_namespace_].pop_front(); } +}; + + + +#endif //_h_deque_h__ diff --git a/PDContainer/include/HList.h b/PDContainer/include/HList.h new file mode 100755 index 0000000..b8a5768 --- /dev/null +++ b/PDContainer/include/HList.h @@ -0,0 +1,250 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HList.h + +#ifndef _h_list_h__ +#define _h_list_h__ + + +#include "include/SimpleBase.h" +#include + +using std::list; + + +//--------------------------------------------------- +/* this is the class of the list + */ +class HList : +public SimpleBase< list, list::iterator > +{ + protected: + /* this integer holds the current position of the + * iterator, because accessing the iterator directly + * from PD is very buggy... + * (maybe I'll change this !) + */ + int i_pos_; + + /* the internal iterator, you can navigate + * through the container with it + */ + list::iterator iter_; + + private: + + /* Copy Construction is not allowed + */ + HList(const HList &src) + { } + + /* assignement operator is not allowed + */ + const HList& operator = (const HList&) + { return *this; } + + public: + + /* Standard Constructor + * no namespace + */ + HList() + { + dataname_ = "h_list"; + i_pos_=0; + } + + /* Constructor + * with a namespace + */ + HList(string h_namespace) + { + dataname_ = "h_list"; + setNamespace(h_namespace); + i_pos_=0; + } + + /* Destructor + */ + virtual ~HList() { } + + /* inserts an element at the end of + * the container + */ + virtual void pushBack(Element value) + { data_[h_namespace_].push_back(value); } + + /* removes the element from the end of + * the container + */ + virtual void popBack() + { data_[h_namespace_].pop_back(); } + + /* inserts an element at the end of + * the container + */ + virtual void pushFront(Element value) + { data_[h_namespace_].push_front(value); } + + /* removes the element from the end of + * the container + */ + virtual void popFront() + { data_[h_namespace_].pop_front(); } + + /* returns the last element + */ + virtual Element &back() const + { return data_[h_namespace_].back(); } + + /* returns the first element + */ + virtual Element &front() const + { return data_[h_namespace_].front(); } + + /* inserts an element at the current + * iterator position + */ + virtual void insert(Element value) + { + makeIterator(); + data_[h_namespace_].insert(iter_, value); + i_pos_++; + } + + /* overrides the element at the current + * iterator position + */ + virtual void modify(Element value) + { + makeIterator(); + *iter_=value; + } + + + /* gives back the element at the current + * iterator position + */ + virtual Element get() + { + makeIterator(); + + // key was not found if iterator is pointing to the end + if(iter_ == data_[h_namespace_].end()) + throw "h_list, get: Element not found !"; + + return *iter_; + } + + /* removes all elements with that value + */ + virtual void remove(Element value) + { data_[h_namespace_].remove(value); } + + /* removes an element at the current + * iterator position + */ + virtual void del() + { + makeIterator(); + + if(data_[h_namespace_].size() == 0) + return; + + if(iter_ == data_[h_namespace_].end()) + { + post("h_list, delete: not possible, go back by 1 (iterator points to the element after the end) !!!"); + return; + } + + data_[h_namespace_].erase(iter_); + } + + /* get the size of the sequence + */ + virtual int getSize() const + { return data_[h_namespace_].size(); } + + /* set current iterator position + */ + virtual void setIterPos(int position) + { i_pos_ = position; } + + /* get the current iterator position + */ + virtual int getIterPos() + { + makeIterator(); + return i_pos_; + } + + /* sets the iterator position the the begin + * of the list + */ + virtual void begin() + { i_pos_ = 0; } + + /* sets the iterator position the the end + * of the list + */ + virtual void end() + { i_pos_ = data_[h_namespace_].size(); } + + /* increases the iterator position by one + */ + virtual void next() + { i_pos_++; } + + /* decreases the iterator position by one + */ + virtual void last() + { i_pos_--; } + + /* removes all but the first element in every + * consecutive group of equal elements + */ + virtual void unique() + { data_[h_namespace_].unique(); } + + /* reverses the order of elements in the list + */ + virtual void reverse() + { data_[h_namespace_].reverse(); } + + /* sorts the list according to operator< + */ + virtual void sort() + { data_[h_namespace_].sort(); } + + /* reads from file + */ + virtual bool readFromFile(string filename); + + private: + /* generates the current iterator position + */ + void makeIterator() + { + if(i_pos_<0) + i_pos_=0; + + if((unsigned)i_pos_ > data_[h_namespace_].size()) + i_pos_=data_[h_namespace_].size(); + + // this is a hack to make the iterator, I'll change this ! + iter_=data_[h_namespace_].begin(); + for(int i = 0; i +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HMap.h + + +#ifndef _h_map_h__ +#define _h_map_h__ + +#include "include/MapBase.h" + +using std::map; + +//--------------------------------------------------- +/* this is the class of the map + */ +class HMap : +public MapBase< map, map::iterator > +{ + // gcc4.0 food: + //this->data_; + //this->h_namespace_; + //this->dataname_; + + private: + + /* Copy Construction is not allowed + */ + HMap(const HMap &src) + { } + + /* assignement operator is not allowed + */ + const HMap& operator = (const HMap&) + { return *this; } + + public: + + /* Constructor + * no namespace + */ + HMap() + { dataname_ = "h_map"; } + + /* Constructor + * with a namespace + */ + HMap(string h_namespace) + { + dataname_ = "h_map"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HMap() { } +}; + + +#endif // _h_map_h__ diff --git a/PDContainer/include/HMultiMap.h b/PDContainer/include/HMultiMap.h new file mode 100755 index 0000000..0c7a9f7 --- /dev/null +++ b/PDContainer/include/HMultiMap.h @@ -0,0 +1,80 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HMultiMap.h + + +#ifndef _h_multi_map_h__ +#define _h_multi_map_h__ + +#include "include/MapBase.h" + +using std::multimap; + +//--------------------------------------------------- +/* this is the class of the map + */ +class HMultiMap : +public MapBase< multimap, multimap::iterator > +{ + + private: + + /* Copy Construction is not allowed + */ + HMultiMap(const HMultiMap &src) + { } + + /* assignement operator is not allowed + */ + const HMultiMap& operator = (const HMultiMap&) + { return *this; } + + public: + + /* Constructor + * no namespace + */ + HMultiMap() + { dataname_ = "h_multimap"; } + + /* Constructor + * with a namespace + */ + HMultiMap(string h_namespace) + { + dataname_ = "h_multimap"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HMultiMap() { } + + /* Add a key-value pair + */ + virtual void add(Element key, Element value) + { + this->data_[this->h_namespace_].insert(std::pair(key,value)); + } + + /* Get the Nr. of values from the specific Key + */ + virtual int getNr(Element &key) const + { return data_[h_namespace_].count(key); } + + /* Get a value from the specific Key with the index number + * index starts with 0 + */ + virtual Element &get(Element &key, int index) const; +}; + + +#endif // _h_multi_map_h__ diff --git a/PDContainer/include/HMultiSet.h b/PDContainer/include/HMultiSet.h new file mode 100755 index 0000000..7bfc36f --- /dev/null +++ b/PDContainer/include/HMultiSet.h @@ -0,0 +1,81 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HMultiSet.h + + +#ifndef _h_multi_set_h__ +#define _h_multi_set_h__ + +#include "include/SimpleBase.h" +#include + +using std::multiset; + +//--------------------------------------------------- +/* this is the class of the set + */ +class HMultiSet : +public SimpleBase< multiset, multiset::iterator > +{ + + private: + + /* Copy Construction is not allowed + */ + HMultiSet(const HMultiSet &src) + { } + + /* assignement operator is not allowed + */ + const HMultiSet& operator = (const HMultiSet&) + { return *this; } + + public: + + /* Constructor + * no namespace + */ + HMultiSet() + { dataname_ = "h_multiset"; } + + /* Constructor + * with a namespace + */ + HMultiSet(string h_namespace) + { + dataname_ = "h_multiset"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HMultiSet() { } + + /* add an element + */ + virtual void add(Element key) + { data_[h_namespace_].insert(key); } + + /* look if the element is set + * returns how often this element was set + * 0 if it isn't set + */ + virtual int get(const Element &key) const + { return data_[h_namespace_].count(key); } + + /* removes an element from the container + */ + virtual void remove(const Element &key) const + { data_[h_namespace_].erase(key); } +}; + + +#endif // _h_multi_set_h__ diff --git a/PDContainer/include/HPrioQueue.h b/PDContainer/include/HPrioQueue.h new file mode 100755 index 0000000..d1bddda --- /dev/null +++ b/PDContainer/include/HPrioQueue.h @@ -0,0 +1,100 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HPriority_Queue.h + +#ifndef _h_priority_queue_h__ +#define _h_priority_queue_h__ + + +#include "include/QueueStack.h" +#include + +using std::priority_queue; + +class ElementPrio +{ + public: + Element element; + float priority; + + bool operator< (const ElementPrio &key) const + { + return (priority < key.priority); + } + const ElementPrio& operator = (const ElementPrio &src) + { + priority = src.priority; + element = src.element; + return (*this); + } +}; + +//--------------------------------------------------- +/* this is the class of the priority_queue + */ +class HPrioQueue : +public QueueStack< priority_queue, int > +{ + + private: + + /* Copy Construction is not allowed + */ + HPrioQueue(const HPrioQueue &src) + { } + + /* assignement operator is not allowed + */ + const HPrioQueue& operator = (const HPrioQueue&) + { return *this; } + + public: + + /* Standard Constructor + * no namespace + */ + HPrioQueue() + { dataname_ = "h_priority_queue"; } + + /* Constructor + * with a namespace + */ + HPrioQueue(string h_namespace) + { + dataname_ = "h_priority_queue"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HPrioQueue() { } + + /* inserts an element in the container + */ + virtual void push(float prio, Element value) + { + ElementPrio data; + data.priority = prio; + data.element = value; + + data_[h_namespace_].push(data); + } + + /* returns the element from the top of + * the stack + */ + virtual Element top() const + { return data_[h_namespace_].top().element; } +}; + + + +#endif //_h_priority_queue_h__ diff --git a/PDContainer/include/HQueue.h b/PDContainer/include/HQueue.h new file mode 100755 index 0000000..025fe52 --- /dev/null +++ b/PDContainer/include/HQueue.h @@ -0,0 +1,77 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HQueue.h + +#ifndef _h_queue_h__ +#define _h_queue_h__ + + +#include "include/QueueStack.h" +#include + +using std::queue; + + +//--------------------------------------------------- +/* this is the class of the queue + */ +class HQueue : +public QueueStack< queue, int > +{ + + private: + + /* Copy Construction is not allowed + */ + HQueue(const HQueue &src) + { } + + /* assignement operator is not allowed + */ + const HQueue& operator = (const HQueue&) + { return *this; } + + public: + + /* Standard Constructor + * no namespace + */ + HQueue() + { dataname_ = "h_queue"; } + + /* Constructor + * with a namespace + */ + HQueue(string h_namespace) + { + dataname_ = "h_queue"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HQueue() { } + + /* inserts an element in the container + */ + virtual void push(Element value) + { data_[h_namespace_].push(value); } + + /* returns the element from the top of + * the stack + */ + virtual Element &front() const + { return data_[h_namespace_].front(); } +}; + + + +#endif //_h_queue_h__ diff --git a/PDContainer/include/HSet.h b/PDContainer/include/HSet.h new file mode 100755 index 0000000..231b909 --- /dev/null +++ b/PDContainer/include/HSet.h @@ -0,0 +1,82 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HSet.h + + +#ifndef _h_set_h__ +#define _h_set_h__ + +#include "include/SimpleBase.h" +#include + +using std::set; + +//--------------------------------------------------- +/* this is the class of the set + */ +class HSet : +public SimpleBase< set, set::iterator > +{ + + private: + + /* Copy Construction is not allowed + */ + HSet(const HSet &src) + { } + + /* assignement operator is not allowed + */ + const HSet& operator = (const HSet&) + { return *this; } + + public: + + /* Constructor + * no namespace + */ + HSet() + { dataname_ = "h_set"; } + + /* Constructor + * with a namespace + */ + HSet(string h_namespace) + { + dataname_ = "h_set"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HSet() { } + + /* add an element + */ + virtual void add(Element key) + { data_[h_namespace_].insert(key); } + + /* look if the element is set + * returns 1 if it is set + * 0 if it isn't set + */ + virtual int get(const Element &key) const + { return (data_[h_namespace_].find(key) + != data_[h_namespace_].end()); } + + /* removes an element from the container + */ + virtual void remove(const Element &key) const + { data_[h_namespace_].erase(key); } +}; + + +#endif // _h_set_h__ diff --git a/PDContainer/include/HStack.h b/PDContainer/include/HStack.h new file mode 100755 index 0000000..8050af9 --- /dev/null +++ b/PDContainer/include/HStack.h @@ -0,0 +1,77 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HStack.h + +#ifndef _h_stack_h__ +#define _h_stack_h__ + + +#include "include/QueueStack.h" +#include + +using std::stack; + + +//--------------------------------------------------- +/* this is the class of the stack + */ +class HStack : +public QueueStack< stack, int > +{ + + private: + + /* Copy Construction is not allowed + */ + HStack(const HStack &src) + { } + + /* assignement operator is not allowed + */ + const HStack& operator = (const HStack&) + { return *this; } + + public: + + /* Standard Constructor + * no namespace + */ + HStack() + { dataname_ = "h_stack"; } + + /* Constructor + * with a namespace + */ + HStack(string h_namespace) + { + dataname_ = "h_stack"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HStack() { } + + /* inserts an element in the container + */ + virtual void push(Element value) + { data_[h_namespace_].push(value); } + + /* returns the element from the top of + * the stack + */ + virtual Element &top() const + { return data_[h_namespace_].top(); } +}; + + + +#endif //_h_stack_h__ diff --git a/PDContainer/include/HVector.h b/PDContainer/include/HVector.h new file mode 100755 index 0000000..933da80 --- /dev/null +++ b/PDContainer/include/HVector.h @@ -0,0 +1,66 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HVector.h + +#ifndef _h_vector_h__ +#define _h_vector_h__ + + +#include "include/SequBase.h" +#include + +using std::vector; + + +//--------------------------------------------------- +/* this is the class of the vector + */ +class HVector : +public SequBase< vector, vector::iterator > +{ + + private: + + /* Copy Construction is not allowed + */ + HVector(const HVector &src) + { } + + /* assignement operator is not allowed + */ + const HVector& operator = (const HVector&) + { return *this; } + + public: + + /* Standard Constructor + * no namespace + */ + HVector() + { dataname_ = "h_vector"; } + + /* Constructor + * with a namespace + */ + HVector(string h_namespace) + { + dataname_ = "h_vector"; + setNamespace(h_namespace); + } + + /* Destructor + */ + virtual ~HVector() { } +}; + + + +#endif //_h_vector_h__ diff --git a/PDContainer/include/MapBase.h b/PDContainer/include/MapBase.h new file mode 100755 index 0000000..cf295de --- /dev/null +++ b/PDContainer/include/MapBase.h @@ -0,0 +1,655 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// MapBase.h + +#ifndef _map_base_h__ +#define _map_base_h__ + +#include "include/ContainerBase.h" + + +//--------------------------------------------------- +/* this is the base class of map and multimap + */ +template +class MapBase : public ContainerBase +{ + + private: + + /* Copy Construction is not allowed + */ + MapBase(const MapBase &src) + { } + + /* assignement operator is not allowed + */ + const MapBase& operator = + (const MapBase&) + { } + + public: + + /* Standard Constructor + * no namespace + */ + MapBase() + { } + + /* Destructor + */ + virtual ~MapBase() { }; + + /* Add a key-value pair + */ + virtual void add(Element key, Element value) + { + // first remove old entry, then insert + this->data_[this->h_namespace_].erase(key); + this->data_[this->h_namespace_].insert(std::pair(key,value)); + } + + /* Get a value from the specific Key + */ + virtual Element &get(const Element &key) const + { + ContTypeIterator iter = this->data_[this->h_namespace_].find(key); + + // key was not found if iterator is pointing to the end + if(iter == this->data_[this->h_namespace_].end()) + throw "PDContainer, get: Element not found !"; + + return (*iter).second; + } + + /* removes a pair with this key + */ + virtual void remove(const Element &key) + { + if(!this->data_[this->h_namespace_].erase(key)) + throw "PDContainer, remove: Element not found !"; + } + + /* prints all the data of the current namespace to the console + */ + virtual void printAll(); + + /* saves all the data of the current namespace to a file + * Fileformat: + * ... - ... + * e.g.: + * f 1 f 2 - f 4 + * s foo f 12.34234 - f 3 f 5 s gege + * types: s=symbol, f=float + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ + virtual bool saveToFile(string filename); + + /* saves all the data of the current namespace to a XML file + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ + virtual bool saveToFileXML(string filename); + + /* reads from an input file and adds the data to + * the current namespace + * Fileformat: see saveToFile + * returns true on success + */ + virtual bool readFromFile(string filename); + + /* reads from an XML input file and adds the data to + * the current namespace + * returns true on success + */ + virtual bool readFromFileXML(string filename); +}; + +//---------------------------------------------------- +/* prints all the data of the current namespace to the console + */ +template +void MapBase::printAll() +{ + ContTypeIterator iter = this->data_[this->h_namespace_].begin(); + + post("\n%s: printing namespace %s",this->dataname_.c_str(),this->h_namespace_.c_str()); + post("--------------------------------------------------"); + + bool data_here = false; + while(iter != this->data_[this->h_namespace_].end()) + { + ostringstream output(""); + + // Key: + Element key = (*iter).first; + if (key.getLength() > 1) // list + { + output << "list "; + for (int i=0; i < key.getLength(); i++) + { + if (key.getAtom()[i].a_type == A_FLOAT) + output << key.getAtom()[i].a_w.w_float << " "; + if (key.getAtom()[i].a_type == A_SYMBOL) + output << key.getAtom()[i].a_w.w_symbol->s_name << " "; + if (key.getAtom()[i].a_type == A_POINTER) + output << "(gpointer)" << key.getAtom()[i].a_w.w_gpointer << " "; + } + } + else // no list + { + if (key.getAtom()[0].a_type == A_FLOAT) + output << "float " << key.getAtom()[0].a_w.w_float << " "; + if (key.getAtom()[0].a_type == A_SYMBOL) + output << "symbol " + << key.getAtom()[0].a_w.w_symbol->s_name << " "; + if (key.getAtom()[0].a_type == A_POINTER) + output << "pointer " << key.getAtom()[0].a_w.w_gpointer << " "; + } + + // Value: + output << " -- "; + Element el = (*iter).second; + if (el.getLength() > 1) // list + { + output << "list "; + for (int i=0; i < el.getLength(); i++) + { + if (el.getAtom()[i].a_type == A_FLOAT) + output << el.getAtom()[i].a_w.w_float << " "; + if (el.getAtom()[i].a_type == A_SYMBOL) + output << el.getAtom()[i].a_w.w_symbol->s_name << " "; + if (el.getAtom()[i].a_type == A_POINTER) + output << "(gpointer)" << el.getAtom()[i].a_w.w_gpointer << " "; + } + } + else // no list + { + if (el.getAtom()[0].a_type == A_FLOAT) // hier segfault nach get !!! + output << "float " << el.getAtom()[0].a_w.w_float << " "; + if (el.getAtom()[0].a_type == A_SYMBOL) + output << "symbol " + << el.getAtom()[0].a_w.w_symbol->s_name << " "; + if (el.getAtom()[0].a_type == A_POINTER) + output << "pointer " << el.getAtom()[0].a_w.w_gpointer << " "; + } + + post("%s",output.str().c_str()); + data_here = true; + iter++; + } + if(!data_here) + post("no data in current namespace!"); + post("--------------------------------------------------"); +} + +//---------------------------------------------------- +/* saves all the data of the current namespace to a file + * Fileformat: + * ... - ... + * e.g.: + * f 1 f 2 - f 4 + * s foo f 12.34234 - f 3 f 5 s gege + * types: s=symbol, f=float + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ +template +bool MapBase::saveToFile(string filename) +{ + ofstream outfile; + ContTypeIterator iter = this->data_[this->h_namespace_].begin(); + + outfile.open(filename.c_str()); + + if(!outfile) + return false; + + while(iter != this->data_[this->h_namespace_].end()) + { + Element key = (*iter).first; + Element el = (*iter).second; + bool have_pointer = false; + + // check if there is a pointer and then don't store it + for (int i=0; i < key.getLength(); i++) + if (key.getAtom()[i].a_type == A_POINTER) + have_pointer=true; + for (int i=0; i < el.getLength(); i++) + if (el.getAtom()[i].a_type == A_POINTER) + have_pointer=true; + + if(have_pointer) + { + post("PDContainer: will not store pointers !!!"); + iter++; + } + else + { + // add key: + for (int i=0; i < key.getLength(); i++) + { + if (key.getAtom()[i].a_type == A_FLOAT) + outfile << "f " << key.getAtom()[i].a_w.w_float << " "; + if (key.getAtom()[i].a_type == A_SYMBOL) + outfile << "s " << key.getAtom()[i].a_w.w_symbol->s_name << " "; + } + + outfile << "- "; + + // add Value: + for (int i=0; i < el.getLength(); i++) + { + if (el.getAtom()[i].a_type == A_FLOAT) + outfile << "f " << el.getAtom()[i].a_w.w_float << " "; + if (el.getAtom()[i].a_type == A_SYMBOL) + outfile << "s " << el.getAtom()[i].a_w.w_symbol->s_name << " "; + } + + outfile << endl; + iter++; + } + } + + outfile.close(); + + return true; +} + +//---------------------------------------------------- +/* saves all the data of the current namespace to a XML file + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ +template + bool MapBase::saveToFileXML(string filename) +{ + ostringstream output(""); + ContTypeIterator iter = this->data_[this->h_namespace_].begin(); + + // add XML Header: + output << "\n" + << "\n" + << "dataname_ << "\">\n"; + + while(iter != this->data_[this->h_namespace_].end()) + { + Element key((*iter).first); + Element el((*iter).second); + bool have_pointer = false; + + // check if there is a pointer and then don't store it + for (int i=0; i < key.getLength(); i++) + if (key.getAtom()[i].a_type == A_POINTER) + have_pointer=true; + for (int i=0; i < el.getLength(); i++) + if (el.getAtom()[i].a_type == A_POINTER) + have_pointer=true; + + if(have_pointer) + { + post("PDContainer: will not store pointers !!!"); + iter++; + } + else + { + + output << "\n"; + + // add Key: + output << "\n"; + + for (int i=0; i < key.getLength(); i++) + { + if (key.getAtom()[i].a_type == A_FLOAT) + output << " " << key.getAtom()[i].a_w.w_float << " \n"; + if (key.getAtom()[i].a_type == A_SYMBOL) + output << "" << key.getAtom()[i].a_w.w_symbol->s_name << " \n"; + } + + output << "\n"; + + + // add Value: + output << "\n"; + + for (int i=0; i < el.getLength(); i++) + { + if (el.getAtom()[i].a_type == A_FLOAT) + output << " " << el.getAtom()[i].a_w.w_float << " \n"; + if (el.getAtom()[i].a_type == A_SYMBOL) + output << "" << el.getAtom()[i].a_w.w_symbol->s_name << " \n"; + } + + output << "\n"; + + output << "\n"; + + iter++; + + } + } + + output << "\n"; + + // now write to file: + TiXmlDocument outfile( filename.c_str() ); + outfile.Parse( output.str().c_str() ); + + if ( outfile.Error() ) return false; + + outfile.SaveFile(); + + return true; +} + +//---------------------------------------------------- +/* reads the data from the file into the current + * namespace + * Fileformat: see saveToFile + * returns true on success + */ +template +bool MapBase::readFromFile(string filename) +{ + ifstream infile; + infile.open(filename.c_str()); + + if(!infile) + return false; + + Element key; + Element el; + + string line; + bool go_on = false; + char type; + string symbol; + t_float number; + int key_count, val_count; + + while (getline(infile, line)) + { + // first parse the instream, to get the number of atoms + // (= length of the elements) + + istringstream instream(line); + ostringstream key_str(""); + ostringstream value_str(""); + + // Key: + go_on = false; key_count = 0; + while(!go_on) + { + instream >> type; + if (type == 's') + { + key_count++; + instream >> symbol; + key_str << "s " << symbol; + } + if (type == 'f') + { + key_count++; + instream >> number; + key_str << "f " << number; + } + if (type == '-') + go_on = true; + key_str << " "; + } + + // Value: + go_on = false; val_count = 0; + while(!go_on) + { + instream >> type; + if (instream.eof()) + { + go_on = true; + break; + } + if (type == 's') + { + val_count++; + instream >> symbol; + value_str << "s " << symbol; + } + if (type == 'f') + { + val_count++; + instream >> number; + value_str << "f " << number; + } + if (instream.eof()) + go_on = true; + value_str << " "; + } + + + // now make the key and value objects, parse again the data + // into the objects and add them to the container + + // Key: + + t_atom *key_atom = (t_atom*)getbytes(key_count*sizeof(t_atom)); + t_atom *val_atom = (t_atom*)getbytes(val_count*sizeof(t_atom)); + if(key_atom == NULL || val_atom == NULL) + post("Fatal Error Out Of Memory (%s-readFromFile)",this->dataname_.c_str()); + + istringstream key_istr(key_str.str()); + istringstream value_istr(value_str.str()); + + for(int i = 0; i < key_count; i++) + { + key_istr >> type; + if (type == 's') + { + key_istr >> symbol; + SETSYMBOL(&key_atom[i],gensym(const_cast(symbol.c_str()))); + } + if (type == 'f') + { + key_istr >> number; + SETFLOAT(&key_atom[i],number); + } + } + + for(int i = 0; i < val_count; i++) + { + value_istr >> type; + if (type == 's') + { + value_istr >> symbol; + SETSYMBOL(&val_atom[i],gensym(const_cast(symbol.c_str()))); + } + if (type == 'f') + { + value_istr >> number; + SETFLOAT(&val_atom[i],number); + } + } + + key.setAtoms(key_count,key_atom); + el.setAtoms(val_count, val_atom); + // insert the data + this->data_[this->h_namespace_].insert(std::pair(key,el)); + + freebytes(key_atom, key_count*sizeof(t_atom)); + freebytes(val_atom, val_count*sizeof(t_atom)); + } + + infile.close(); + + return true; +} + +//---------------------------------------------------- +/* reads the data from the XML file into the current + * namespace + * returns true on success + */ +template + bool MapBase::readFromFileXML(string filename) +{ + TiXmlDocument doc( filename.c_str() ); + + if( !doc.LoadFile() ) return false; + + TiXmlNode *parent = 0; + TiXmlElement *child1 = 0; + TiXmlElement *child2 = 0; + TiXmlElement *child3 = 0; + + t_atom *key_atom = 0; + t_atom *val_atom = 0; + Element key; + Element el; + t_float f; + bool parsed=false; + + + // Get the tag and check type + parent = doc.FirstChild( "PDContainer" ); + if(!parent) return false; + + if(!parent->ToElement()) return false; + if(!parent->ToElement()->Attribute("type")) + { + post("readXML: you must specify an attribute type in !"); + return false; + } + + string type(parent->ToElement()->Attribute("type")); + if( type != "h_map" && type != "h_multimap" ) + { + post("readXML: wrong container type (attribute type in ) !"); + return false; + } + + if( type != this->dataname_ ) + post("readXML: importing data from %s!", type.c_str() ); + + // iterate through all the tags + for( child1 = parent->FirstChildElement("element"); child1; + child1 = child1->NextSiblingElement("element") ) + { + // get the tag + child2 = child1->FirstChildElement( "key" ); + if(!child2) return false; + + // get nr of keys and allocate mem for them + // (if its a pd list) + int key_count = 0; + for( child3 = child2->FirstChildElement(); child3; + child3 = child3->NextSiblingElement() ) + key_count++; + + key_atom = (t_atom*)getbytes(key_count*sizeof(t_atom)); + if(key_atom == NULL) + { + post("Fatal Error Out Of Memory (%s-readFromFile)",this->dataname_.c_str()); + return false; + } + + // iterate through all the atoms of + key_count = 0; + for( child3 = child2->FirstChildElement(); child3; + child3 = child3->NextSiblingElement() ) + { + string tag(child3->Value()); + + if(!child3->FirstChild()) continue; + istringstream in(child3->FirstChild()->Value()); + + if(tag == "f" || tag == "float") + { + in >> f; + SETFLOAT(&key_atom[key_count], f); + } + if(tag == "s" || tag == "symbol") + { + SETSYMBOL(&key_atom[key_count], + gensym(const_cast(in.str().c_str()))); + } + + key_count++; + } + + if(!key_count) continue; + + //---------------------- + + // get the tag + child2 = child1->FirstChildElement( "value" ); + if(!child2) return false; + + // get nr of values and allocate mem for them + // (if its a pd list) + int val_count = 0; + for( child3 = child2->FirstChildElement(); child3; + child3 = child3->NextSiblingElement() ) + val_count++; + + val_atom = (t_atom*)getbytes(val_count*sizeof(t_atom)); + if(val_atom == NULL) + { + post("Fatal Error Out Of Memory (%s-readFromFile)",this->dataname_.c_str()); + return false; + } + + // iterate through all the atoms of + val_count = 0; + for( child3 = child2->FirstChildElement(); child3; + child3 = child3->NextSiblingElement() ) + { + string tag(child3->Value()); + + if(!child3->FirstChild()) continue; + istringstream in(child3->FirstChild()->Value()); + + if(tag == "f" || tag == "float") + { + in >> f; + SETFLOAT(&val_atom[val_count],f); + } + if(tag == "s" || tag == "symbol") + { + SETSYMBOL(&val_atom[val_count], + gensym(const_cast(in.str().c_str()))); + } + + val_count++; + } + + if(!val_count) continue; + + // add the element to the container + key.setAtoms(key_count,key_atom); + el.setAtoms(val_count,val_atom); + this->data_[this->h_namespace_].insert(std::pair(key,el)); + + freebytes(key_atom, key_count*sizeof(t_atom)); + freebytes(val_atom, val_count*sizeof(t_atom)); + + parsed = true; + } + return parsed; +} + + +#endif // _map_base_h__ diff --git a/PDContainer/include/QueueStack.h b/PDContainer/include/QueueStack.h new file mode 100755 index 0000000..eb72408 --- /dev/null +++ b/PDContainer/include/QueueStack.h @@ -0,0 +1,61 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// HQueueStack.h + +#ifndef _h_queue_stack_h__ +#define _h_queue_stack_h__ + + +#include "include/ContainerBase.h" + + +//--------------------------------------------------- +/* this is the class of the queue, stack and priority queue + */ +template +class QueueStack : public ContainerBase +{ + + private: + + /* Copy Construction is not allowed + */ + QueueStack(const QueueStack &src) + { } + + /* assignement operator is not allowed + */ + const QueueStack& operator = + (const QueueStack&) + { } + + public: + + /* Standard Constructor + * no namespace + */ + QueueStack() + { } + + /* Destructor + */ + virtual ~QueueStack() { } + + /* removes the value from the top of + * the container + */ + virtual void pop() + { this->data_[this->h_namespace_].pop(); } +}; + + + +#endif //_h_queue_stack_h__ diff --git a/PDContainer/include/SequBase.h b/PDContainer/include/SequBase.h new file mode 100755 index 0000000..40bc4d7 --- /dev/null +++ b/PDContainer/include/SequBase.h @@ -0,0 +1,341 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// SequBase.h + +#ifndef _sequ_base_h__ +#define _sequ_base_h__ + + +#include "include/SimpleBase.h" + + +//--------------------------------------------------- +/* this is the base class of vector and deque + */ +template +class SequBase : public SimpleBase +{ + + private: + + /* Copy Construction is not allowed + */ + SequBase(const SequBase &src) + { } + + /* assignement operator is not allowed + */ + const SequBase& operator = + (const SequBase&) + { } + + public: + + /* Standard Constructor + * no namespace + */ + SequBase() + { } + + /* Destructor + */ + virtual ~SequBase() { }; + + /* change the element at the index + */ + virtual void set(int index, Element value) + { this->data_[this->h_namespace_][index] = value; } + + /* get the element from the index + */ + virtual Element &get(int index) const + { return this->data_[this->h_namespace_][index]; } + + /* resize the sequence + */ + virtual void resize(int size) + { this->data_[this->h_namespace_].resize(size); } + + /* inserts an element at the end of + * the container (so then the size + * increases by one !!!) + */ + virtual void pushBack(Element value) + { this->data_[this->h_namespace_].push_back(value); } + + /* removes the element from the end of + * the container (so then the size + * decreases by one !!!) + */ + virtual void popBack() + { this->data_[this->h_namespace_].pop_back(); } + + /* returns the last element + */ + virtual Element &back() const + { return this->data_[this->h_namespace_].back(); } + + /* returns the first element + */ + virtual Element &front() const + { return this->data_[this->h_namespace_].front(); } + + /* inserts an element before the element + * with the given index + */ + virtual void insert(int index, Element value) + { this->data_[this->h_namespace_].insert(this->data_[this->h_namespace_].begin()+index, value); } + + /* removes the element with that index from the + * container + */ + virtual void remove(int index) + { this->data_[this->h_namespace_].erase(this->data_[this->h_namespace_].begin()+index); } + + /* reads from an input file and adds the data to + * the current namespace + * Fileformat: see saveToFile + * index: inserts the data starting with this index + * returns true on success + */ + virtual bool readFromFile2(string filename, int index); + + /* reads from a XML input file and adds the data to + * the current namespace + * index: inserts the data starting with this index + * returns true on success + */ + virtual bool readFromFile2XML(string filename, int index); +}; + + +//---------------------------------------------------- +/* reads the data from the file into the current + * namespace + * Fileformat: see saveToFile + * index: inserts the data starting with this index + * returns true on success + */ +template +bool SequBase::readFromFile2(string filename, int index) +{ + ifstream infile; + infile.open(filename.c_str()); + + if(!infile) + return false; + + Element key; + + string line; + bool go_on = false; + char type; + string symbol; + t_float number; + int key_count; + int max_index = this->data_[this->h_namespace_].size(); + + while (getline(infile, line)) + { + // first parse the instream, to get the number of atoms + // (= size of the list) + + if(index < 0 || index >= max_index) + { + post("%s, read: wrong index !!",this->dataname_.c_str()); + return false; + } + + istringstream instream(line); + ostringstream key_str(""); + + go_on = false; key_count = 0; + while(!go_on) + { + instream >> type; + if (instream.eof()) + { + go_on = true; + break; + } + if (type == 's') + { + key_count++; + instream >> symbol; + key_str << "s " << symbol; + } + if (type == 'f') + { + key_count++; + instream >> number; + key_str << "f " << number; + } + if (instream.eof()) + go_on = true; + key_str << " "; + } + + // now objects, parse again the data + // into the objects and add them to the container + + t_atom *key_atom = (t_atom*)getbytes(key_count*sizeof(t_atom)); + + if(key_atom == NULL) + post("Fatal Error Out Of Memory (%s-readFromFile)",this->dataname_.c_str()); + + istringstream key_istr(key_str.str()); + + for(int i = 0; i < key_count; i++) + { + key_istr >> type; + if (type == 's') + { + key_istr >> symbol; + SETSYMBOL(&key_atom[i],gensym(const_cast(symbol.c_str()))); + } + if (type == 'f') + { + key_istr >> number; + SETFLOAT(&key_atom[i],number); + } + } + + key.setAtoms(key_count,key_atom); + // insert the data + this->data_[this->h_namespace_][index] = key; + index++; + + freebytes(key_atom, key_count*sizeof(t_atom)); + } + + infile.close(); + + return true; +} + +//---------------------------------------------------- +/* reads the data from the XML file into the current + * namespace + * index: inserts the data starting with this index + * returns true on success + */ +template + bool SequBase::readFromFile2XML(string filename, int index) +{ + int max_index = this->data_[this->h_namespace_].size(); + if(index < 0 || index >= max_index) + { + post("%s, read: wrong index !!",this->dataname_.c_str()); + return false; + } + + + TiXmlDocument doc( filename.c_str() ); + + if( !doc.LoadFile() ) return false; + + TiXmlNode *parent = 0; + TiXmlElement *child1 = 0; + TiXmlElement *child2 = 0; + + t_atom *el_atom = 0; + Element el; + t_float f; + bool parsed=false; + + + // Get the tag and check type + parent = doc.FirstChild( "PDContainer" ); + if(!parent) return false; + + if(!parent->ToElement()) return false; + if(!parent->ToElement()->Attribute("type")) + { + post("readXML: you must specify an attribute type in !"); + return false; + } + + string type(parent->ToElement()->Attribute("type")); + + if( type != "h_vector" && type != "h_list" && type != "h_deque" && + type != "h_set" && type != "h_multiset") + { + post("readXML: wrong container type (attribute type in ) !"); + return false; + } + + if( type != this->dataname_ ) + post("readXML: importing data from %s!", type.c_str() ); + + // iterate through all the tags + for( child1 = parent->FirstChildElement("element"); child1; + child1 = child1->NextSiblingElement("element") ) + { + // get nr of atoms and allocate mem for them + // (if its a pd list) + int atoms = 0; + for( child2 = child1->FirstChildElement(); child2; + child2 = child2->NextSiblingElement() ) + atoms++; + + el_atom = (t_atom*)getbytes(atoms*sizeof(t_atom)); + + if(el_atom == NULL) + { + post("Fatal Error Out Of Memory (%s-readFromFile)",this->dataname_.c_str()); + return false; + } + + // iterate through all the atoms of one + atoms = 0; + for( child2 = child1->FirstChildElement(); child2; + child2 = child2->NextSiblingElement() ) + { + string tag(child2->Value()); + + if(!child2->FirstChild()) continue; + istringstream in(child2->FirstChild()->Value()); + + if(tag == "f" || tag == "float") + { + in >> f; + SETFLOAT(&el_atom[atoms], f); + } + if(tag == "s" || tag == "symbol") + { + SETSYMBOL(&el_atom[atoms], + gensym(const_cast(in.str().c_str()))); + } + + atoms++; + } + + if(!atoms) continue; + + + // add the element to the container + el.setAtoms(atoms,el_atom); + + // insert the data + this->data_[this->h_namespace_][index] = el; + index++; + + freebytes(el_atom, atoms*sizeof(t_atom)); + + parsed = true; + } + return parsed; + +} + + + +#endif //_sequ_base_h__ diff --git a/PDContainer/include/SimpleBase.h b/PDContainer/include/SimpleBase.h new file mode 100755 index 0000000..75203ec --- /dev/null +++ b/PDContainer/include/SimpleBase.h @@ -0,0 +1,539 @@ +// *********************(c)*2004*********************> +// -holzilib--holzilib--holzilib--holzilib--holzilib-> +// ++++PD-External++by+Georg+Holzmann++grh@gmx.at++++> +// +// PDContainer: +// this is a port of the containers from the C++ STL +// (Standard Template Library) +// for usage see the documentation and PD help files +// for license see readme.txt +// +// SimpleBase.h + +#ifndef _simple_base_h__ +#define _simple_base_h__ + + +#include "include/ContainerBase.h" + + +//--------------------------------------------------- +/* this is the base class of all simple containers + */ +template +class SimpleBase : public ContainerBase +{ + + private: + + /* Copy Construction is not allowed + */ + SimpleBase(const SimpleBase &src) + { } + + /* assignement operator is not allowed + */ + const SimpleBase& operator = + (const SimpleBase&) + { } + + public: + + /* Standard Constructor + * no namespace + */ + SimpleBase() + { } + + /* Destructor + */ + virtual ~SimpleBase() { }; + + /* prints all the data of the current namespace to the console + */ + virtual void printAll(); + + /* prints all the data of the current namespace to the console + * (with the index as prefix) + */ + virtual void printAllIndex(); + + /* saves all the data of the current namespace to a file + * Fileformat: + * ... + * e.g.: + * f 1 f 2 f 4 + * s foo f 12.34234 + * types: s=symbol, f=float + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ + virtual bool saveToFile(string filename); + + /* saves all the data of the current namespace to a XML file + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ + virtual bool saveToFileXML(string filename); + + /* reads from an input file and adds the data to + * the current namespace + * Fileformat: see saveToFile + * returns true on success + */ + virtual bool readFromFile(string filename); + + /* reads from an input XML file and adds the data to + * the current namespace + * returns true on success + */ + virtual bool readFromFileXML(string filename); +}; + + +//---------------------------------------------------- +/* prints all the data of the current namespace to the console + */ +template +void SimpleBase::printAll() +{ + ContTypeIterator iter = this->data_[this->h_namespace_].begin(); + + post("\n%s: printing namespace %s",this->dataname_.c_str(),this->h_namespace_.c_str()); + post("--------------------------------------------------"); + + bool data_here = false; + while(iter != this->data_[this->h_namespace_].end()) + { + ostringstream output(""); + + Element key((*iter)); + if(key.getLength() == 0) + { + iter++; + continue; + } + + if (key.getLength() > 1) // list + { + output << "list "; + for (int i=0; i < key.getLength(); i++) + { + if (key.getAtom()[i].a_type == A_FLOAT) + output << key.getAtom()[i].a_w.w_float << " "; + if (key.getAtom()[i].a_type == A_SYMBOL) + output << key.getAtom()[i].a_w.w_symbol->s_name << " "; + if (key.getAtom()[i].a_type == A_POINTER) + output << "(gpointer)" << key.getAtom()[i].a_w.w_gpointer << " "; + } + } + else // no list + { + if (key.getAtom()[0].a_type == A_FLOAT) + output << "float " << key.getAtom()[0].a_w.w_float << " "; + if (key.getAtom()[0].a_type == A_SYMBOL) + output << "symbol " + << key.getAtom()[0].a_w.w_symbol->s_name << " "; + if (key.getAtom()[0].a_type == A_POINTER) + output << "pointer " << key.getAtom()[0].a_w.w_gpointer << " "; + } + + post("%s",output.str().c_str()); + data_here = true; + + iter++; + } + if(!data_here) + post("no data in current namespace!"); + post("--------------------------------------------------"); +} + +//---------------------------------------------------- +/* prints all the data of the current namespace to the console + * (with the index as prefix) + */ +template +void SimpleBase::printAllIndex() +{ + ContTypeIterator iter = this->data_[this->h_namespace_].begin(); + + post("\n%s: printing namespace %s",this->dataname_.c_str(),this->h_namespace_.c_str()); + post("--------------------------------------------------"); + + bool data_here = false; int i=0; + while(iter != this->data_[this->h_namespace_].end()) + { + ostringstream output(""); + + Element key((*iter)); + if(key.getLength() == 0) + { + iter++; i++; + continue; + } + + if (key.getLength() > 1) // list + { + output << "list "; + for (int i=0; i < key.getLength(); i++) + { + if (key.getAtom()[i].a_type == A_FLOAT) + output << key.getAtom()[i].a_w.w_float << " "; + if (key.getAtom()[i].a_type == A_SYMBOL) + output << key.getAtom()[i].a_w.w_symbol->s_name << " "; + if (key.getAtom()[i].a_type == A_POINTER) + output << "(gpointer)" << key.getAtom()[i].a_w.w_gpointer << " "; + } + } + else // no list + { + if (key.getAtom()[0].a_type == A_FLOAT) + output << "float " << key.getAtom()[0].a_w.w_float << " "; + if (key.getAtom()[0].a_type == A_SYMBOL) + output << "symbol " + << key.getAtom()[0].a_w.w_symbol->s_name << " "; + if (key.getAtom()[0].a_type == A_POINTER) + output << "pointer " << key.getAtom()[0].a_w.w_gpointer << " "; + } + + post("%d: %s",i,output.str().c_str()); + data_here = true; + + iter++; i++; + } + if(!data_here) + post("no data in current namespace!"); + post("--------------------------------------------------"); +} + +//---------------------------------------------------- +/* saves all the data of the current namespace to a file + * Fileformat: + * ... - ... + * e.g.: + * f 1 f 2 - f 4 + * s foo f 12.34234 - f 3 f 5 s gege + * types: s=symbol, f=float + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ +template +bool SimpleBase::saveToFile(string filename) +{ + ofstream outfile; + ContTypeIterator iter = this->data_[this->h_namespace_].begin(); + + outfile.open(filename.c_str()); + + if(!outfile) + return false; + + while(iter != this->data_[this->h_namespace_].end()) + { + Element key((*iter)); + bool have_pointer = false; + + // check for pointers first + for (int i=0; i < key.getLength(); i++) + if (key.getAtom()[i].a_type == A_POINTER) + have_pointer = true; + + if(have_pointer) + { + post("PDContainer warning: pointers can't be saved and are ignored !!!"); + iter++; + } + else + { + + for (int i=0; i < key.getLength(); i++) + { + if (key.getAtom()[i].a_type == A_FLOAT) + outfile << "f " << key.getAtom()[i].a_w.w_float << " "; + if (key.getAtom()[i].a_type == A_SYMBOL) + outfile << "s " << key.getAtom()[i].a_w.w_symbol->s_name << " "; + } + + outfile << endl; + iter++; + + } + } + + outfile.close(); + + return true; +} + +//---------------------------------------------------- +/* saves all the data of the current namespace to a XML file + * ATTENTION: if the file exists, all the old data of + * the file is lost + * returns true on success + */ +template + bool SimpleBase::saveToFileXML(string filename) +{ + ostringstream output(""); + ContTypeIterator iter = this->data_[this->h_namespace_].begin(); + + // add XML Header: + output << "\n" + << "\n" + << "dataname_ << "\">\n"; + + + while(iter != this->data_[this->h_namespace_].end()) + { + // add Element: + Element el((*iter)); + bool have_pointer = false; + + // check for pointers first + for (int i=0; i < el.getLength(); i++) + if (el.getAtom()[i].a_type == A_POINTER) + have_pointer = true; + + if(have_pointer) + { + post("PDContainer warning: pointers can't be saved and are ignored !!!"); + iter++; + } + else + { + + output << "\n"; + + for (int i=0; i < el.getLength(); i++) + { + if (el.getAtom()[i].a_type == A_FLOAT) + output << " " << el.getAtom()[i].a_w.w_float << " \n"; + if (el.getAtom()[i].a_type == A_SYMBOL) + output << "" << el.getAtom()[i].a_w.w_symbol->s_name << " \n"; + } + + output << "\n"; + + iter++; + + } + } + + output << "\n"; + + // now write to file: + TiXmlDocument outfile( filename.c_str() ); + outfile.Parse( output.str().c_str() ); + + if ( outfile.Error() ) return false; + + outfile.SaveFile(); + + return true; +} + +//---------------------------------------------------- +/* reads the data from the file into the current + * namespace + * Fileformat: see saveToFile + * returns true on success + */ +template +bool SimpleBase::readFromFile(string filename) +{ + ifstream infile; + infile.open(filename.c_str()); + + if(!infile) + return false; + + Element key; + + string line; + bool go_on = false; + char type; + string symbol; + t_float number; + int key_count; + + while (getline(infile, line)) + { + // first parse the instream, to get the number of atoms + // (= size of the list) + + istringstream instream(line); + ostringstream key_str(""); + + go_on = false; key_count = 0; + while(!go_on) + { + instream >> type; + if (instream.eof()) + { + go_on = true; + break; + } + if (type == 's') + { + key_count++; + instream >> symbol; + key_str << "s " << symbol; + } + if (type == 'f') + { + key_count++; + instream >> number; + key_str << "f " << number; + } + if (instream.eof()) + go_on = true; + key_str << " "; + } + + // now objects, parse again the data + // into the objects and add them to the container + + t_atom *key_atom = (t_atom*)getbytes(key_count*sizeof(t_atom)); + if(key_atom == NULL) + post("Fatal Error Out Of Memory (%s-readFromFile)",this->dataname_.c_str()); + + istringstream key_istr(key_str.str()); + + for(int i = 0; i < key_count; i++) + { + key_istr >> type; + if (type == 's') + { + key_istr >> symbol; + SETSYMBOL(&key_atom[i],gensym(const_cast(symbol.c_str()))); + } + if (type == 'f') + { + key_istr >> number; + SETFLOAT(&key_atom[i],number); + } + } + + key.setAtoms(key_count,key_atom); + + // insert the data + this->data_[this->h_namespace_].insert(this->data_[this->h_namespace_].end(),key); + + freebytes(key_atom, key_count*sizeof(t_atom)); + } + + infile.close(); + + return true; +} + +//---------------------------------------------------- +/* reads the data from th XML file into the current + * namespace + * returns true on success + */ +template + bool SimpleBase::readFromFileXML(string filename) +{ + TiXmlDocument doc( filename.c_str() ); + + if( !doc.LoadFile() ) return false; + + TiXmlNode *parent = 0; + TiXmlElement *child1 = 0; + TiXmlElement *child2 = 0; + + t_atom *el_atom = 0; + Element el; + t_float f; + bool parsed=false; + + + // Get the tag and check type + parent = doc.FirstChild( "PDContainer" ); + if(!parent) return false; + + if(!parent->ToElement()) return false; + if(!parent->ToElement()->Attribute("type")) + { + post("readXML: you must specify an attribute type in !"); + return false; + } + + string type(parent->ToElement()->Attribute("type")); + + if( type != "h_vector" && type != "h_list" && type != "h_deque" && + type != "h_set" && type != "h_multiset") + { + post("readXML: wrong container type (attribute type in ) !"); + return false; + } + + if( type != this->dataname_ ) + post("readXML: importing data from %s!", type.c_str() ); + + // iterate through all the tags + for( child1 = parent->FirstChildElement("element"); child1; + child1 = child1->NextSiblingElement("element") ) + { + // get nr of atoms and allocate mem for them + // (if its a pd list) + int atoms = 0; + for( child2 = child1->FirstChildElement(); child2; + child2 = child2->NextSiblingElement() ) + atoms++; + + el_atom = (t_atom*)getbytes(atoms*sizeof(t_atom)); + if(el_atom == NULL) + { + post("Fatal Error Out Of Memory (%s-readFromFile)",this->dataname_.c_str()); + return false; + } + + // iterate through all the atoms of one + atoms = 0; + for( child2 = child1->FirstChildElement(); child2; + child2 = child2->NextSiblingElement() ) + { + string tag(child2->Value()); + + if(!child2->FirstChild()) continue; + istringstream in(child2->FirstChild()->Value()); + + if(tag == "f" || tag == "float") + { + in >> f; + SETFLOAT(&el_atom[atoms], f); + } + if(tag == "s" || tag == "symbol") + { + SETSYMBOL(&el_atom[atoms], + gensym(const_cast(in.str().c_str()))); + } + + atoms++; + } + + if(!atoms) continue; + + + // add the element to the container + el.setAtoms(atoms,el_atom); + + // insert it in the container + this->data_[this->h_namespace_].insert(this->data_[this->h_namespace_].end(),el); + + freebytes(el_atom, atoms*sizeof(t_atom)); + + parsed = true; + } + return parsed; +} + + + +#endif // _simple_base_h__ -- cgit v1.2.1