28 #ifndef FREPPLE_UTILS_H
29 #define FREPPLE_UTILS_H
39 #if defined(_DEBUG) && defined(_MSC_VER)
64 #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
66 #define PY_SSIZE_T_MAX INT_MAX
67 #define PY_SSIZE_T_MIN INT_MIN
87 using namespace gnu_cxx;
115 #undef PACKAGE_BUGREPORT
117 #undef PACKAGE_STRING
118 #undef PACKAGE_TARNAME
119 #undef PACKAGE_VERSION
123 #define PACKAGE_VERSION "2.1"
128 #if defined(HAVE_PTHREAD_H)
131 #define WIN32_LEAN_AND_MEAN
135 #error Multithreading not supported on your platform
141 #ifndef HAVE_STRNCASECMP
143 # define strncasecmp _strnicmp
145 # ifdef HAVE_STRNICMP
146 # define strncasecmp(s1,s2,n) strnicmp(s1,s2,n)
149 # define strncasecmp(s1,s2,n) strnuppercmp(s1,s2,n)
159 #define ROUNDING_ERROR 0.000001
163 #define XERCES_STATIC_LIBRARY
164 #include <xercesc/util/PlatformUtils.hpp>
165 #include <xercesc/util/TransService.hpp>
166 #include <xercesc/sax2/SAX2XMLReader.hpp>
167 #include <xercesc/sax2/Attributes.hpp>
168 #include <xercesc/sax2/DefaultHandler.hpp>
169 #include <xercesc/framework/MemBufInputSource.hpp>
170 #include <xercesc/sax2/XMLReaderFactory.hpp>
171 #include <xercesc/util/XMLUni.hpp>
172 #include <xercesc/framework/MemBufInputSource.hpp>
173 #include <xercesc/framework/LocalFileInputSource.hpp>
174 #include <xercesc/framework/StdInInputSource.hpp>
175 #include <xercesc/framework/URLInputSource.hpp>
176 #include <xercesc/util/XMLException.hpp>
189 #undef DECLARE_EXPORT
191 #if defined(WIN32) && !defined(DOXYGEN)
193 #define DECLARE_EXPORT __declspec (dllexport)
195 #define DECLARE_EXPORT __declspec (dllimport)
197 #define MODULE_EXPORT extern "C" __declspec (dllexport)
199 #define DECLARE_EXPORT
200 #define MODULE_EXPORT extern "C"
208 class CommandMoveOperationPlan;
249 case ADD: os <<
"ADD";
return os;
250 case CHANGE: os <<
"CHANGE";
return os;
251 case REMOVE: os <<
"REMOVE";
return os;
252 case ADD_CHANGE: os <<
"ADD_CHANGE";
return os;
253 default: assert(
false);
return os;
273 case SIG_ADD: os <<
"ADD";
return os;
275 default: assert(
false);
return os;
297 for (
short c = i.
level; c>0; --c) os <<
' ';
549 const char*, PyCFunction,
int,
const char*,
bool =
true
554 (
const char*, PyCFunctionWithKeywords,
int,
const char*,
bool =
true);
557 static DECLARE_EXPORT void registerGlobalObject(
const char*, PyObject*,
bool =
true);
579 #if PY_MAJOR_VERSION >= 3
581 static PyObject* createModule();
633 string strName, strStartElement, strEndElement, strElement, strAttribute;
663 const string&
getName()
const {
return strName;}
735 virtual bool callback(
Object* v,
const Signal a)
const = 0;
772 static const PyTypeObject PyTypeObjectTemplate;
778 static const unsigned short methodArraySize = 5;
798 DECLARE_EXPORT void addMethod(
const char*, PyCFunction,
int,
const char*);
801 DECLARE_EXPORT void addMethod(
const char*, PyCFunctionWithKeywords,
int,
const char*);
804 void setName (
const string n)
806 string *name =
new string(
"frepple." + n);
807 table->tp_name =
const_cast<char*
>(name->c_str());
811 void setDoc (
const string n)
813 string *doc =
new string(n);
814 table->tp_doc =
const_cast<char*
>(doc->c_str());
818 void setBase(PyTypeObject* b)
824 void supportdealloc(
void (*f)(PyObject*))
826 table->tp_dealloc = f;
834 void supportgetattro()
842 void supportsetattro()
850 void supportcompare()
862 table->tp_iter = PyObject_SelfIter;
883 typedef PyObject* (*createfunc)(PyTypeObject*, PyObject*, PyObject*);
893 bool operator == (
const PythonType& i)
const
899 bool operator == (
const type_info& i)
const
901 return *cppClass == i;
959 typedef Object* (*creatorString)(
const string&);
986 bool =
false, creatorDefault = NULL);
989 MetaClass (
const string& cat,
const string& cls,
bool def =
false)
992 registerClass(cat,cls,def);
997 MetaClass (
const string& cat,
const string& cls, creatorDefault f,
998 bool def =
false) : pythonClass(NULL)
1000 registerClass(cat,cls,def);
1001 factoryMethodDefault = f;
1006 MetaClass (
const string& cat,
const string& cls, creatorString f,
1007 bool def =
false) : pythonClass(NULL)
1009 registerClass(cat,cls,def);
1010 factoryMethodString = f;
1073 {
const_cast<MetaClass*
>(
this)->subscribers[a].push_front(c);}
1077 {
const_cast<MetaClass*
>(
this)->subscribers[a].
remove(c);}
1089 category(NULL), pythonClass(NULL), factoryMethodDefault(NULL) {}
1100 list<Functor*> subscribers[4];
1200 readController = NULL, writeController = NULL);
1203 typedef map < hashtype, const MetaClass*, less<hashtype> >
ClassMap;
1206 typedef map < hashtype, const MetaCategory*, less<hashtype> >
CategoryMap;
1266 writeController writeFunction;
1295 for (list<Functor*>::iterator i = t.subscribers[a].begin();
1296 i != t.subscribers[a].end(); ++i)
1304 t.subscribers[a].erase(i);
1317 {
return U::callback(static_cast<T*>(v),a);}
1343 for (list<Functor*>::iterator i = t.subscribers[a].begin();
1344 i != t.subscribers[a].end(); ++i)
1348 if (f && f->instance == u)
1352 t.subscribers[a].erase(i);
1366 {
return instance ? instance->callback(static_cast<T*>(v),a) :
true;}
1397 explicit Timer() : start_time(clock()) {}
1404 double elapsed()
const {
return double(clock()-start_time)/CLOCKS_PER_SEC;}
1442 bool operator < (
const long& b)
const {
return lval < b;}
1445 bool operator > (
const long& b)
const {
return lval > b;}
1448 bool operator <= (
const long& b)
const {
return lval <= b;}
1451 bool operator >= (
const long& b)
const {
return lval >= b;}
1454 bool operator < (
const TimePeriod& b)
const {
return lval < b.lval;}
1457 bool operator > (
const TimePeriod& b)
const {
return lval > b.lval;}
1460 bool operator <= (
const TimePeriod& b)
const {
return lval <= b.lval;}
1463 bool operator >= (
const TimePeriod& b)
const {
return lval >= b.lval;}
1466 bool operator == (
const TimePeriod& b)
const {
return lval == b.lval;}
1469 bool operator != (
const TimePeriod& b)
const {
return lval != b.lval;}
1478 bool operator ! ()
const {
return lval == 0L;}
1481 operator long()
const {
return lval;}
1484 operator string()
const
1538 t.toCharBuffer(str);
1587 Date(
const char* s,
bool dummy) {parse(s);}
1593 inline void getInfo(
struct tm* tm_struct)
const
1602 #ifdef HAVE_LOCALTIME_R
1603 localtime_r(&lval, tm_struct);
1605 *tm_struct = *localtime(&lval);
1612 Date(
const time_t l) : lval(l) {checkFinite(lval);}
1617 Date() : lval(infinitePast.lval) {}
1624 Date(
const char* s) {parse(s); checkFinite(lval);}
1630 int hr=0,
int min=0,
int sec=0
1634 bool operator < (
const Date& b)
const {
return lval < b.lval;}
1637 bool operator > (
const Date& b)
const {
return lval > b.lval;}
1640 bool operator == (
const Date& b)
const {
return lval == b.lval;}
1643 bool operator != (
const Date& b)
const {
return lval != b.lval;}
1646 bool operator >= (
const Date& b)
const {
return lval >= b.lval;}
1649 bool operator <= (
const Date& b)
const {
return lval <= b.lval;}
1652 void operator = (
const Date& b) {lval = b.lval;}
1656 {checkFinite(static_cast<long long>(l) + lval);}
1660 {checkFinite(- static_cast<long long>(l) + lval);}
1666 d.checkFinite(static_cast<long long>(l) + lval);
1674 d.checkFinite(- static_cast<long>(l) + lval);
1681 {
return static_cast<long>(lval - l.lval);}
1684 bool operator ! ()
const {
return lval == infinitePast.lval;}
1687 operator bool()
const {
return lval != infinitePast.lval;}
1695 operator string()
const
1708 size_t toCharBuffer(
char* str)
const
1712 return strftime(str, 30, format.c_str(), &t);
1741 long getSecondsYear()
const
1745 return t.tm_yday * 86400 + t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1749 long getSecondsMonth()
const
1753 return (t.tm_mday-1) * 86400 + t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1759 long getSecondsWeek()
const
1763 int result = t.tm_wday * 86400 + t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1764 assert(result >= 0 && result < 604800L);
1769 long getSecondsDay()
const
1773 int result = t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1774 assert(result >= 0 && result < 86400L);
1778 #ifndef HAVE_STRPTIME
1780 DECLARE_EXPORT char* strptime(
const char *,
const char *,
struct tm *);
1809 {
if(st>nd) {start=nd; end=st;}}
1839 {
if (st<nd) {start=st; end=nd;}
else {start=nd; end=st;}}
1849 {
return start==b.start && end==b.end;}
1853 {
return start!=b.start || end!=b.end;}
1862 void operator = (
const DateRange& dr) {start = dr.start; end = dr.end;}
1871 {
return dr.start<=end && dr.end>start;}
1876 long x = (dr.end<end ? dr.end : end)
1877 - (dr.start>start ? dr.start : start);
1889 static void setSeparator(
const string& n)
1892 separatorlength = n.size();
1917 return os << dr.
getStart() << DateRange::getSeparator() << dr.
getEnd();
2079 numParents(0), currentObject(NULL), parentObject(NULL), content(STANDARD),
2080 headerStart(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"),
2081 headerAtts(
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
2082 {m_fp = &os; indentstring[0] =
'\0';}
2086 currentObject(NULL), parentObject(NULL), content(STANDARD),
2087 headerStart(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"),
2088 headerAtts(
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
2089 {m_fp = &
logger; indentstring[0] =
'\0';}
2109 void BeginObject(
const Keyword& t,
const string& atts)
2133 template <
class T,
class U>
2135 const Keyword& attr2,
const U& val2)
2148 template <
class T,
class U,
class V>
2150 const Keyword& attr2,
const U& val2,
2151 const Keyword& attr3,
const V& val3)
2172 void writeString(
const string& c)
2174 *m_fp << indentstring << c <<
"\n";
2179 void writeElement(
const Keyword& t,
const long unsigned int val)
2186 void writeElement(
const Keyword& t,
const int val)
2193 void writeElement(
const Keyword& t,
const double val)
2202 void writeElement(
const Keyword& t,
const bool val)
2211 void writeElement(
const Keyword& t,
const string& val)
2249 const Keyword& t2,
const string& val2)
2263 const Keyword& t2,
const string& val2)
2273 void writeElement(
const Keyword& t,
const char* val)
2336 {
return const_cast<Object*
>(currentObject);}
2340 {
return const_cast<Object*
>(parentObject);}
2355 short int m_nIndent;
2361 char indentstring[41];
2364 unsigned long numObjects;
2367 unsigned int numParents;
2370 const Object *currentObject;
2373 const Object *parentObject;
2383 content_type content;
2414 of.open(chFilename.c_str(), ios::out);
2474 : hash(
Keyword::hash(n)), ch(n.c_str()) {}
2486 void reset(
const char *
const c)
2488 hash = Keyword::hash(c);
2493 void reset(
const XMLCh *
const c)
2495 hash = Keyword::hash(c);
2517 bool operator < (
const Attribute& o)
const {
return hash < o.hash;}
2520 bool operator == (
const string o)
const {
return o == ch;}
2533 virtual operator bool()
const
2539 void operator >> (
unsigned long int& val)
const {val = getUnsignedLong();}
2541 void operator >> (
long& val)
const {val = getLong();}
2543 void operator >> (
TimePeriod& val)
const {val = getTimeperiod();}
2545 void operator >> (
bool& v)
const {v=getBool();}
2547 void operator >> (
int& val)
const {val = getInt();}
2549 void operator >> (
double& val)
const {val = getDouble();}
2551 void operator >> (
Date& val)
const {val = getDate();}
2553 void operator >> (
string& val)
const {val = getString();}
2555 virtual long getLong()
const
2558 virtual unsigned long getUnsignedLong()
const
2564 virtual int getInt()
const
2567 virtual double getDouble()
const
2573 virtual string getString()
const
2576 virtual bool getBool()
const
2590 virtual operator bool()
const {
return !m_strData.empty();}
2611 void addData(
const char *pData,
size_t len) {m_strData.append(pData,len);}
2614 void setData(
const char *pData) {m_strData.assign(pData);}
2617 const char *
getData()
const {
return m_strData.c_str();}
2619 virtual long getLong()
const {
return atol(getData());}
2625 virtual int getInt()
const {
return atoi(getData());}
2755 : obj(o ? const_cast<PyObject*>(o) : Py_None) {Py_INCREF(obj);}
2758 operator PyObject*()
const {
return obj;}
2761 operator bool()
const {
return obj != NULL && obj != Py_None;}
2766 if (obj) {Py_DECREF(obj);}
2768 if (obj) {Py_INCREF(obj);}
2785 bool check(
const PythonType& c)
const
2793 inline string getString()
const
2797 #if PY_MAJOR_VERSION >= 3
2798 else if (PyUnicode_Check(obj))
2801 PyObject* x = PyUnicode_AsEncodedString(obj,
"UTF-8",
"ignore");
2802 string result = PyBytes_AS_STRING(x);
2810 PyObject* x1 = PyObject_Repr(obj);
2811 PyObject* x2 = PyUnicode_AsEncodedString(x1,
"UTF-8",
"ignore");
2812 string result = PyBytes_AS_STRING(x2);
2818 else if (PyUnicode_Check(obj))
2821 PyObject* x = PyUnicode_AsEncodedString(obj,
"UTF-8",
"ignore");
2822 string result = PyString_AsString(x);
2826 else if (PyString_Check(obj))
2828 return PyString_AsString(obj);
2833 PyObject* x1 = PyObject_Str(obj);
2834 if (PyUnicode_Check(x1))
2836 PyObject* x2 = PyUnicode_AsEncodedString(x1,
"UTF-8",
"ignore");
2837 string result = PyString_AsString(x2);
2844 string result = PyString_AsString(x1);
2853 unsigned long getUnsignedLong()
const
2855 if (obj == Py_None)
return 0;
2856 #if PY_MAJOR_VERSION >= 3
2857 if (PyUnicode_Check(obj))
2859 PyObject* t = PyFloat_FromString(obj);
2861 if (PyString_Check(obj))
2863 PyObject* t = PyFloat_FromString(obj, NULL);
2866 double x = PyFloat_AS_DOUBLE(t);
2868 if (x < 0 || x > ULONG_MAX)
2870 return static_cast<unsigned long>(x);
2872 return PyLong_AsUnsignedLong(obj);
2880 inline double getDouble()
const
2882 if (obj == Py_None)
return 0;
2883 #if PY_MAJOR_VERSION >= 3
2884 if (PyUnicode_Check(obj))
2886 PyObject* t = PyFloat_FromString(obj);
2888 if (PyString_Check(obj))
2890 PyObject* t = PyFloat_FromString(obj, NULL);
2893 double x = PyFloat_AS_DOUBLE(t);
2897 return PyFloat_AsDouble(obj);
2901 inline int getInt()
const
2903 if (obj == Py_None)
return 0;
2904 #if PY_MAJOR_VERSION >= 3
2905 if (PyUnicode_Check(obj))
2907 PyObject* t = PyFloat_FromString(obj);
2909 if (PyString_Check(obj))
2911 PyObject* t = PyFloat_FromString(obj, NULL);
2914 double x = PyFloat_AS_DOUBLE(t);
2916 if (x < INT_MIN || x > INT_MAX)
2918 return static_cast<int>(x);
2920 #if PY_MAJOR_VERSION >= 3
2921 int result = PyLong_AsLong(obj);
2923 int result = PyInt_AsLong(obj);
2925 if (result == -1 && PyErr_Occurred())
2931 inline long getLong()
const
2933 if (obj == Py_None)
return 0;
2934 #if PY_MAJOR_VERSION >= 3
2935 if (PyUnicode_Check(obj))
2937 PyObject* t = PyFloat_FromString(obj);
2939 if (PyString_Check(obj))
2941 PyObject* t = PyFloat_FromString(obj, NULL);
2944 double x = PyFloat_AS_DOUBLE(t);
2946 if (x < LONG_MIN || x > LONG_MIN)
2948 return static_cast<long>(x);
2950 #if PY_MAJOR_VERSION >= 3
2951 long result = PyLong_AsLong(obj);
2953 long result = PyInt_AsLong(obj);
2955 if (result == -1 && PyErr_Occurred())
2961 inline bool getBool()
const
2963 return PyObject_IsTrue(obj) ?
true :
false;
2972 #if PY_MAJOR_VERSION >= 3
2973 if (PyUnicode_Check(obj))
2976 PyObject * utf8_string = PyUnicode_AsUTF8String(obj);
2978 Py_DECREF(utf8_string);
2981 long result = PyLong_AsLong(obj);
2983 if (PyString_Check(obj))
2985 if (PyUnicode_Check(obj))
2988 const_cast<PyObject*&
>(obj) =
2989 PyUnicode_AsEncodedString(obj,
"UTF-8",
"ignore");
2991 return TimePeriod(PyString_AsString(PyObject_Str(obj)));
2993 int result = PyInt_AsLong(obj);
2995 if (result == -1 && PyErr_Occurred())
3016 obj = PyUnicode_FromString(val.c_str());
3022 obj = PyFloat_FromDouble(val);
3028 #if PY_MAJOR_VERSION >= 3
3029 obj = PyLong_FromLong(val);
3031 obj = PyInt_FromLong(val);
3038 obj = PyLong_FromLong(val);
3044 obj = PyLong_FromUnsignedLong(val);
3050 obj = val ? Py_True : Py_False;
3059 obj = PyLong_FromLong(val);
3085 if (func) {Py_INCREF(func);}
3091 if (func) {Py_DECREF(func);}
3093 if (func) {Py_INCREF(func);}
3101 operator const PyObject*()
const {
return func;}
3104 operator string()
const {
return func ? PyEval_GetFuncName(func) :
"NULL";}
3107 operator bool()
const {
return func != NULL;}
3148 const xercesc::Attributes* atts;
3174 PyObject* val = PyDict_GetItemString(kwds,k.getName().c_str());
3205 if (PyObject::ob_refcnt > 1)
3206 logger <<
"Warning: Deleting "
3207 << (PyObject::ob_type->tp_name && PyObject::ob_type ? PyObject::ob_type->tp_name :
"NULL")
3208 <<
" object that is still referenced "
3209 << (PyObject::ob_refcnt-1) <<
" times" << endl;
3228 inline void initType(PyTypeObject *t)
3230 PyObject_INIT(
this,t);
3257 virtual int compare(
const PyObject* other)
const
3266 virtual PyObject* iternext()
3286 virtual PyObject* str()
const
3295 DECLARE_EXPORT static PythonType* registerPythonType(
int,
const type_info*);
3319 PyObject_Init(
this, getType().type_object());
3326 static PythonType& getType()
3328 static PythonType* cachedTypePtr = NULL;
3329 if (cachedTypePtr)
return *cachedTypePtr;
3332 cachedTypePtr = registerPythonType(
sizeof(T), &
typeid(T));
3337 return *cachedTypePtr;
3403 virtual const MetaClass& getType()
const = 0;
3406 virtual size_t getSize()
const = 0;
3427 static PyObject* create
3428 (PyTypeObject* pytype, PyObject* args, PyObject* kwds)
3434 Object* x = T::reader(T::metadata, atts);
3443 PyObject *key, *value;
3445 while (PyDict_Next(kwds, &pos, &key, &value))
3448 #if PY_MAJOR_VERSION >= 3
3449 PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
3450 Attribute attr(PyBytes_AsString(key_utf8));
3451 Py_DECREF(key_utf8);
3457 int result = x->
setattro(attr, field);
3458 if (result && !PyErr_Occurred())
3459 PyErr_Format(PyExc_AttributeError,
3460 #
if PY_MAJOR_VERSION >= 3
3461 "attribute '%S' on '%s' can't be updated",
3462 key, Py_TYPE(x)->tp_name);
3464 "attribute '%s' on '%s' can't be updated",
3465 PyString_AsString(key), Py_TYPE(x)->tp_name);
3474 PythonType::evalException();
3503 #elif defined(HAVE_PTHREAD_H)
3505 Mutex() {pthread_mutex_init(&mtx, 0);}
3506 ~
Mutex() {pthread_mutex_destroy(&mtx);}
3507 void lock() {pthread_mutex_lock(&mtx);}
3508 void unlock() {pthread_mutex_unlock(&mtx);}
3510 pthread_mutex_t mtx;
3513 Mutex() {InitializeCriticalSection(&critsec);}
3515 void lock() {EnterCriticalSection(&critsec);}
3516 void unlock() {LeaveCriticalSection(&critsec);}
3518 CRITICAL_SECTION critsec;
3545 typedef void (*callable)(
void*);
3552 maxParallel = Environment::getProcessorCores();
3562 void add(callable func,
void* args)
3564 callables.push( make_pair(func,args) );
3578 void setMaxParallel(
int b)
3581 throw DataException(
"Invalid number of parallel execution threads");
3583 maxParallel = (b>1 ? 1 : b);
3590 typedef pair<callable,void*> callableWithArgument;
3608 stack<callableWithArgument> callables;
3611 unsigned int countCallables;
3616 #if defined(HAVE_PTHREAD_H) || !defined(MT)
3617 static void* wrapper(
void *arg);
3619 static unsigned __stdcall wrapper(
void *);
3668 bool operator < (
const TreeNode& o) {
return nm < o.nm;}
3681 if (node->right != NULL)
3684 while (node->left != NULL) node = node->left;
3689 while (node == y->right)
3694 if (node->right != y) node = y;
3703 if (node->color == red && node->parent->parent == node)
3705 else if (node->left != NULL)
3708 while (y->right != NULL) y = y->right;
3714 while (node == y->left)
3745 Tree(
bool b =
false) : count(0), clearOnDestruct(b)
3749 header.parent = NULL;
3750 header.left = &header;
3751 header.right = &header;
3775 bool empty()
const {
return header.parent == NULL;}
3781 findLowerBound(newname, &found);
3784 + newname +
"': name already in use");
3795 size_t size()
const {
return count;}
3817 for (
TreeNode* x = header.parent; x; x = comp<0 ? x->left : x->right)
3819 comp = k.compare(x->nm);
3820 if (!comp)
return x;
3831 TreeNode* findLowerBound(
const string& k,
bool* f)
const
3834 for (
TreeNode* x = header.parent; x;)
3836 int comp = k.compare(x->nm);
3843 if (comp<0) x = x->left;
3844 else lower = x, x = x->right;
3864 inline void rebalance(TreeNode* x);
3867 inline void rotateLeft(TreeNode* x);
3870 inline void rotateRight(TreeNode* x);
3873 unsigned int countBlackNodes(TreeNode* node)
const
3875 unsigned int sum = 0;
3876 for ( ; node != header.parent; node=node->parent)
3877 if (node->color == black) ++sum;
3881 TreeNode* minimum(TreeNode* x)
const
3883 while (x->left) x = x->left;
3887 TreeNode* maximum(TreeNode* x)
const
3889 while (x->right) x = x->right;
3911 bool clearOnDestruct;
3949 Command() : owner(NULL), next(NULL), prev(NULL) {};
4094 bool empty()
const {
return firstCommand==NULL;}
4124 nextBookmark(NULL), prevBookmark(NULL), parent(p) {}
4134 for (
const Bookmark* p =
this; p; p = p->parent)
4135 if (p == b)
return true;
4160 cur = cur->nextBookmark;
4169 cur = cur->nextBookmark;
4203 cur = cur->prevBookmark;
4212 cur = cur->prevBookmark;
4230 Bookmark firstBookmark;
4233 Bookmark* lastBookmark;
4239 Bookmark* currentBookmark;
4245 lastBookmark = &firstBookmark;
4246 currentBookmark = &firstBookmark;
4252 for (
Bookmark* i = lastBookmark; i && i != &firstBookmark; )
4255 i = i->prevBookmark;
4330 static xercesc::XMLTranscoder* utf8_encoder;
4333 xercesc::SAX2XMLReader* parser;
4354 const unsigned short maxdepth;
4357 stack <state> states;
4368 vector< pair<Object*,void*> > m_EHStack;
4375 vector<datapair> m_EStack;
4387 unsigned short ignore;
4390 stack<hashtype> endingHashes;
4410 bool abortOnDataException;
4419 static char encodingbuffer[];
4429 DECLARE_EXPORT void startElement (
const XMLCh*
const,
const XMLCh*
const,
4430 const XMLCh*
const,
const xercesc::Attributes&);
4440 (
const XMLCh*
const,
const XMLCh*
const,
const XMLCh*
const);
4445 #if XERCES_VERSION_MAJOR==2
4446 DECLARE_EXPORT void characters(
const XMLCh *
const,
const unsigned int);
4448 DECLARE_EXPORT void characters(
const XMLCh *
const,
const XMLSize_t);
4453 DECLARE_EXPORT void fatalError (
const xercesc::SAXParseException&);
4460 DECLARE_EXPORT void processingInstruction (
const XMLCh *
const,
const XMLCh *
const);
4474 inline Object* getCurrentObject()
const {
return m_EHStack[m_EHStack.size()-1].first;}
4519 void invalidateCurrentObject()
4521 if (!m_EHStack.empty())
4522 m_EHStack[m_EHStack.size()-1].first = NULL;
4540 int x = m_EHStack.size();
4541 return x>1 ? m_EHStack[x-2].first : NULL;
4546 {
return m_EStack[numElements>0 ? numElements : 0];}
4550 {
return m_EStack[numElements>-1 ? numElements+1 : 0];}
4557 void parse(xercesc::InputSource&,
Object*,
bool=
false);
4561 void setUserArea(
void* v)
4562 {
if (!m_EHStack.empty()) m_EHStack[m_EHStack.size()-1].second = v;}
4565 void* getUserArea()
const
4566 {
return m_EHStack.empty() ? NULL : m_EHStack[m_EHStack.size()-1].second;}
4592 static char* transcodeUTF8(
const XMLCh*);
4627 xercesc::MemBufInputSource a(
4628 reinterpret_cast<const XMLByte*>(data.c_str()),
4629 static_cast<const unsigned int>(data.size()),
4632 XMLInput::parse(a,pRoot,v);
4763 static iterator
end() {
return st.end();}
4766 static iterator
begin() {
return st.begin();}
4769 static bool empty() {
return st.empty();}
4772 static size_t size() {
return st.size();}
4788 void setName(
const string& newname) {st.rename(
this, newname);}
4797 int compare(
const PyObject* other)
const
4799 return getName().compare(static_cast<const T*>(other)->getName());
4804 static T* find(
const string& k)
4807 return (i!=st.end() ?
static_cast<T*
>(i) : NULL);
4815 static T* findLowerBound(
const string& k,
bool *f = NULL)
4818 return (i!=st.end() ?
static_cast<T*
>(i) : NULL);
4825 if (i!=st.end())
return static_cast<T*>(i);
4826 if (*(cls.
category) != T::metadata)
4828 " for creating an object of category " + T::metadata.type);
4835 static T*
add(T* t) {
return static_cast<T*
>(st.insert(t));}
4841 static T*
add(T* t, T* hint) {
return static_cast<T*
>(st.insert(t,hint));}
4865 Action act = MetaClass::decodeAction(in);
4869 if (!*nameElement)
throw DataException(
"Missing name attribute");
4874 T *i = T::findLowerBound(name, &found);
4882 throw DataException(
"Object '" + name +
"' already exists");
4908 throw DataException(
"Can't find object '" + name +
"' for removal");
4915 if (found)
return i;
4927 *type ? Keyword::hash(type->
getString()) : MetaCategory::defaultHash
4931 string t(*type ? type->
getString() :
"default");
4944 if (!x->getType().raiseEvent(x,
SIG_ADD))
4959 if (empty())
return;
4961 for (iterator i = begin(); i != end(); ++i)
4998 size_t extrasize()
const {
return cat.size() + subcat.size() + descr.size();}
5021 class memberIterator;
5022 friend class memberIterator;
5044 curmember = it.curmember;
5045 member_iter = it.member_iter;
5058 curmember = curmember->next_brother;
5060 curmember =
static_cast<T*
>(curmember->increment());
5069 curmember = curmember->next_brother;
5071 curmember =
static_cast<T*
>(curmember->increment());
5077 {
return curmember == y.curmember;}
5081 {
return curmember != y.curmember;}
5085 {
return curmember ? (curmember == &*y) : (y == T::end());}
5089 {
return curmember ? (curmember != &*y) : (y != T::end());}
5099 first_child(NULL), next_brother(NULL) {}
5126 void setOwner(T* f);
5136 unsigned short getHierarchyLevel()
const;
5193 List() : first(NULL) {};
5194 bool empty()
const {
return first==NULL;}
5213 {
return nodeptr == x.
nodeptr;}
5215 {
return nodeptr != x.
nodeptr;}
5217 {nodeptr = nodeptr->nextA;
return *
this;}
5221 nodeptr = nodeptr->nextA;
5235 {
return nodeptr == x.
nodeptr;}
5237 {
return nodeptr != x.
nodeptr;}
5239 {nodeptr = nodeptr->nextA;
return *
this;}
5243 nodeptr = nodeptr->nextA;
5256 for (C* p=this->first; p; p=next)
5264 void erase(
const C* n)
5268 this->first = n->nextA;
5270 for (C* p=this->first; p; p=p->nextA)
5273 p->nextA = n->nextA;
5282 for (C* p = this->first; p; p=p->nextA) ++i;
5287 C* find(
const B* b,
Date d = Date::infinitePast)
const
5289 for (C* p=this->first; p; p=p->nextA)
5290 if (p->ptrB == b && p->effectivity.within(d))
return p;
5295 C* find(
const string& n)
const
5297 for (C* p=this->first; p; p=p->nextA)
5298 if (p->name == n)
return p;
5306 if (p == this->first)
return;
5310 for (C* ptr = this->first; ptr; ptr = ptr->nextA)
5312 if (ptr->nextA == p)
5318 ptr->nextA = p->nextA;
5343 {
return nodeptr == x.
nodeptr;}
5345 {
return nodeptr != x.
nodeptr;}
5347 {nodeptr = nodeptr->nextB;
return *
this;}
5351 nodeptr = nodeptr->nextA;
5365 {
return nodeptr == x.
nodeptr;}
5367 {
return nodeptr != x.
nodeptr;}
5369 {nodeptr = nodeptr->nextB;
return *
this;}
5373 nodeptr = nodeptr->nextA;
5382 for (C* p=this->first; p; p=next)
5394 void erase(
const C* n)
5398 this->first = n->nextB;
5400 for (C* p=this->first; p; p=p->nextB)
5403 p->nextB = n->nextB;
5412 for (C* p=this->first; p; p=p->nextB) ++i;
5417 C* find(
const A* b,
Date d = Date::infinitePast)
const
5419 for (C* p=this->first; p; p=p->nextB)
5420 if (p->ptrA == b && p->effectivity.within(d))
return p;
5425 C* find(
const string& n)
const
5427 for (C* p=this->first; p; p=p->nextB)
5428 if (p->name == n)
return p;
5436 if (p == this->first)
return;
5440 for (C* ptr = this->first; ptr; ptr = ptr->nextB)
5442 if (ptr->nextB == p)
5448 ptr->nextB = p->nextB;
5473 Node() : ptrA(NULL), ptrB(NULL), nextA(NULL), nextB(NULL), priority(1) {};
5477 : ptrA(a), ptrB(b), nextA(NULL), nextB(NULL), priority(1)
5483 while (x->nextA) x = x->nextA;
5484 x->nextA =
static_cast<C*
>(
this);
5488 const_cast<ListA&
>(al).first = static_cast<C*>(
this);
5493 while (x->nextB) x = x->nextB;
5494 x->nextB =
static_cast<C*
>(
this);
5498 const_cast<ListB&
>(bl).first = static_cast<C*>(
this);
5504 if (ptrA)
throw DataException(
"Can't update existing entity");
5510 while (x->nextA) x = x->nextA;
5511 x->nextA =
static_cast<C*
>(
this);
5515 const_cast<ListA&
>(al).first = static_cast<C*>(
this);
5521 if (ptrB)
throw DataException(
"Can't update existing entity");
5527 while (x->nextB) x = x->nextB;
5528 x->nextB =
static_cast<C*
>(
this);
5532 const_cast<ListB&
>(bl).first = static_cast<C*>(
this);
5576 #include "frepple/entity.h"
5597 template <
class ME,
class ITERCLASS,
class DATACLASS>
5605 x.
setName(DATACLASS::metadata->type +
"Iterator");
5606 x.
setDoc(
"frePPLe iterator for " + DATACLASS::metadata->type);
5620 static PyObject* create(PyObject*
self, PyObject* args)
5626 virtual PyObject* iternext()
5628 if (i == DATACLASS::end())
return NULL;
5629 PyObject* result = &*i;
5645 #endif // End of FREPPLE_UTILS_H