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.0"
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/sax2/SAX2XMLReader.hpp>
166 #include <xercesc/sax2/Attributes.hpp>
167 #include <xercesc/sax2/DefaultHandler.hpp>
168 #include <xercesc/framework/MemBufInputSource.hpp>
169 #include <xercesc/sax2/XMLReaderFactory.hpp>
170 #include <xercesc/util/XMLUni.hpp>
171 #include <xercesc/framework/MemBufInputSource.hpp>
172 #include <xercesc/framework/LocalFileInputSource.hpp>
173 #include <xercesc/framework/StdInInputSource.hpp>
174 #include <xercesc/framework/URLInputSource.hpp>
175 #include <xercesc/util/XMLException.hpp>
188 #undef DECLARE_EXPORT
190 #if defined(WIN32) && !defined(DOXYGEN)
192 #define DECLARE_EXPORT __declspec (dllexport)
194 #define DECLARE_EXPORT __declspec (dllimport)
196 #define MODULE_EXPORT extern "C" __declspec (dllexport)
198 #define DECLARE_EXPORT
199 #define MODULE_EXPORT extern "C"
207 class CommandMoveOperationPlan;
248 case ADD: os <<
"ADD";
return os;
249 case CHANGE: os <<
"CHANGE";
return os;
250 case REMOVE: os <<
"REMOVE";
return os;
251 case ADD_CHANGE: os <<
"ADD_CHANGE";
return os;
252 default: assert(
false);
return os;
272 case SIG_ADD: os <<
"ADD";
return os;
274 default: assert(
false);
return os;
296 for (
short c = i.
level; c>0; --c) os <<
' ';
548 const char*, PyCFunction,
int,
const char*,
bool =
true
553 (
const char*, PyCFunctionWithKeywords,
int,
const char*,
bool =
true);
632 string strName, strStartElement, strEndElement, strElement, strAttribute;
662 const string&
getName()
const {
return strName;}
734 virtual bool callback(
Object* v,
const Signal a)
const = 0;
771 static const PyTypeObject PyTypeObjectTemplate;
777 static const unsigned short methodArraySize = 5;
797 DECLARE_EXPORT void addMethod(
const char*, PyCFunction,
int,
const char*);
800 DECLARE_EXPORT void addMethod(
const char*, PyCFunctionWithKeywords,
int,
const char*);
803 void setName (
const string n)
805 string *name =
new string(
"frepple." + n);
806 table->tp_name =
const_cast<char*
>(name->c_str());
810 void setDoc (
const string n)
812 string *doc =
new string(n);
813 table->tp_doc =
const_cast<char*
>(doc->c_str());
817 void setBase(PyTypeObject* b)
823 void supportdealloc(
void (*f)(PyObject*))
825 table->tp_dealloc = f;
833 void supportgetattro()
841 void supportsetattro()
849 void supportcompare()
859 table->tp_iter = PyObject_SelfIter;
880 typedef PyObject* (*createfunc)(PyTypeObject*, PyObject*, PyObject*);
890 bool operator == (
const PythonType& i)
const
896 bool operator == (
const type_info& i)
const
898 return *cppClass == i;
956 typedef Object* (*creatorString)(
const string&);
983 bool =
false, creatorDefault = NULL);
986 MetaClass (
const string& cat,
const string& cls,
bool def =
false)
989 registerClass(cat,cls,def);
994 MetaClass (
const string& cat,
const string& cls, creatorDefault f,
995 bool def =
false) : pythonClass(NULL)
997 registerClass(cat,cls,def);
998 factoryMethodDefault = f;
1003 MetaClass (
const string& cat,
const string& cls, creatorString f,
1004 bool def =
false) : pythonClass(NULL)
1006 registerClass(cat,cls,def);
1007 factoryMethodString = f;
1070 {
const_cast<MetaClass*
>(
this)->subscribers[a].push_front(c);}
1074 {
const_cast<MetaClass*
>(
this)->subscribers[a].
remove(c);}
1086 category(NULL), pythonClass(NULL), factoryMethodDefault(NULL) {}
1097 list<Functor*> subscribers[4];
1197 readController = NULL, writeController = NULL);
1200 typedef map < hashtype, const MetaClass*, less<hashtype> >
ClassMap;
1203 typedef map < hashtype, const MetaCategory*, less<hashtype> >
CategoryMap;
1263 writeController writeFunction;
1292 for (list<Functor*>::iterator i = t.subscribers[a].begin();
1293 i != t.subscribers[a].end(); ++i)
1301 t.subscribers[a].erase(i);
1314 {
return U::callback(static_cast<T*>(v),a);}
1340 for (list<Functor*>::iterator i = t.subscribers[a].begin();
1341 i != t.subscribers[a].end(); ++i)
1345 if (f && f->instance == u)
1349 t.subscribers[a].erase(i);
1363 {
return instance ? instance->callback(static_cast<T*>(v),a) :
true;}
1394 explicit Timer() : start_time(clock()) {}
1401 double elapsed()
const {
return double(clock()-start_time)/CLOCKS_PER_SEC;}
1439 bool operator < (
const long& b)
const {
return lval < b;}
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 TimePeriod& b)
const {
return lval < b.lval;}
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;}
1475 bool operator ! ()
const {
return lval == 0L;}
1478 operator long()
const {
return lval;}
1481 operator string()
const
1535 t.toCharBuffer(str);
1584 Date(
const char* s,
bool dummy) {parse(s);}
1590 inline void getInfo(
struct tm* tm_struct)
const
1599 #ifdef HAVE_LOCALTIME_R
1600 localtime_r(&lval, tm_struct);
1602 *tm_struct = *localtime(&lval);
1609 Date(
const time_t l) : lval(l) {checkFinite(lval);}
1614 Date() : lval(infinitePast.lval) {}
1621 Date(
const char* s) {parse(s); checkFinite(lval);}
1627 int hr=0,
int min=0,
int sec=0
1631 bool operator < (
const Date& b)
const {
return lval < b.lval;}
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 void operator = (
const Date& b) {lval = b.lval;}
1653 {checkFinite(static_cast<long long>(l) + lval);}
1657 {checkFinite(- static_cast<long long>(l) + lval);}
1663 d.checkFinite(static_cast<long long>(l) + lval);
1671 d.checkFinite(- static_cast<long>(l) + lval);
1678 {
return static_cast<long>(lval - l.lval);}
1681 bool operator ! ()
const {
return lval == infinitePast.lval;}
1684 operator bool()
const {
return lval != infinitePast.lval;}
1692 operator string()
const
1705 size_t toCharBuffer(
char* str)
const
1709 return strftime(str, 30, format.c_str(), &t);
1738 long getSecondsYear()
const
1742 return t.tm_yday * 86400 + t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1746 long getSecondsMonth()
const
1750 return (t.tm_mday-1) * 86400 + t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1756 long getSecondsWeek()
const
1760 int result = t.tm_wday * 86400 + t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1761 assert(result >= 0 && result < 604800L);
1766 long getSecondsDay()
const
1770 int result = t.tm_sec + t.tm_min * 60 + t.tm_hour * 3600;
1771 assert(result >= 0 && result < 86400L);
1775 #ifndef HAVE_STRPTIME
1777 DECLARE_EXPORT char* strptime(
const char *,
const char *,
struct tm *);
1806 {
if(st>nd) {start=nd; end=st;}}
1836 {
if (st<nd) {start=st; end=nd;}
else {start=nd; end=st;}}
1846 {
return start==b.start && end==b.end;}
1850 {
return start!=b.start || end!=b.end;}
1859 void operator = (
const DateRange& dr) {start = dr.start; end = dr.end;}
1868 {
return dr.start<=end && dr.end>start;}
1873 long x = (dr.end<end ? dr.end : end)
1874 - (dr.start>start ? dr.start : start);
1886 static void setSeparator(
const string& n)
1889 separatorlength = n.size();
1914 return os << dr.
getStart() << DateRange::getSeparator() << dr.
getEnd();
2063 numParents(0), currentObject(NULL), parentObject(NULL), content(STANDARD),
2064 headerStart(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"),
2065 headerAtts(
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
2066 {m_fp = &os; indentstring[0] =
'\0';}
2070 currentObject(NULL), parentObject(NULL), content(STANDARD),
2071 headerStart(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"),
2072 headerAtts(
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
2073 {m_fp = &
logger; indentstring[0] =
'\0';}
2093 void BeginObject(
const Keyword& t,
const string& atts)
2117 template <
class T,
class U>
2119 const Keyword& attr2,
const U& val2)
2132 template <
class T,
class U,
class V>
2134 const Keyword& attr2,
const U& val2,
2135 const Keyword& attr3,
const V& val3)
2156 void writeString(
const string& c)
2158 *m_fp << indentstring << c <<
"\n";
2163 void writeElement(
const Keyword& t,
const long unsigned int val)
2170 void writeElement(
const Keyword& t,
const int val)
2177 void writeElement(
const Keyword& t,
const double val)
2186 void writeElement(
const Keyword& t,
const bool val)
2195 void writeElement(
const Keyword& t,
const string& val)
2233 const Keyword& t2,
const string& val2)
2247 const Keyword& t2,
const string& val2)
2257 void writeElement(
const Keyword& t,
const char* val)
2320 {
return const_cast<Object*
>(currentObject);}
2324 {
return const_cast<Object*
>(parentObject);}
2336 short int m_nIndent;
2342 char indentstring[41];
2345 unsigned long numObjects;
2348 unsigned int numParents;
2351 const Object *currentObject;
2354 const Object *parentObject;
2364 content_type content;
2395 of.open(chFilename.c_str(), ios::out);
2455 : hash(
Keyword::hash(n)), ch(n.c_str()) {}
2467 void reset(
const char *
const c)
2469 hash = Keyword::hash(c);
2474 void reset(
const XMLCh *
const c)
2476 hash = Keyword::hash(c);
2498 bool operator < (
const Attribute& o)
const {
return hash < o.hash;}
2501 bool operator == (
const string o)
const {
return o == ch;}
2514 virtual operator bool()
const
2520 void operator >> (
unsigned long int& val)
const {val = getUnsignedLong();}
2522 void operator >> (
long& val)
const {val = getLong();}
2524 void operator >> (
TimePeriod& val)
const {val = getTimeperiod();}
2526 void operator >> (
bool& v)
const {v=getBool();}
2528 void operator >> (
int& val)
const {val = getInt();}
2530 void operator >> (
double& val)
const {val = getDouble();}
2532 void operator >> (
Date& val)
const {val = getDate();}
2534 void operator >> (
string& val)
const {val = getString();}
2536 virtual long getLong()
const
2539 virtual unsigned long getUnsignedLong()
const
2545 virtual int getInt()
const
2548 virtual double getDouble()
const
2554 virtual string getString()
const
2557 virtual bool getBool()
const
2571 virtual operator bool()
const {
return !m_strData.empty();}
2592 void addData(
const char *pData,
size_t len) {m_strData.append(pData,len);}
2595 void setData(
const char *pData) {m_strData.assign(pData);}
2598 const char *
getData()
const {
return m_strData.c_str();}
2600 virtual long getLong()
const {
return atol(getData());}
2606 virtual int getInt()
const {
return atoi(getData());}
2736 : obj(o ? const_cast<PyObject*>(o) : Py_None) {Py_INCREF(obj);}
2739 operator PyObject*()
const {
return obj;}
2742 operator bool()
const {
return obj != NULL && obj != Py_None;}
2747 if (obj) {Py_DECREF(obj);}
2749 if (obj) {Py_INCREF(obj);}
2766 bool check(
const PythonType& c)
const
2774 inline string getString()
const
2778 else if (PyUnicode_Check(obj))
2781 PyObject* x = PyUnicode_AsEncodedString(obj,
2782 PythonInterpreter::getPythonEncoding(),
"ignore");
2783 string result = PyString_AsString(x);
2787 else if (PyString_Check(obj))
2789 return PyString_AsString(obj);
2793 PyObject* x = PyObject_Str(obj);
2794 string result = PyString_AsString(x);
2801 unsigned long getUnsignedLong()
const
2803 if (obj == Py_None)
return 0;
2804 if (PyString_Check(obj))
2806 PyObject* t = PyFloat_FromString(obj, NULL);
2808 double x = PyFloat_AS_DOUBLE(t);
2810 if (x < 0 || x > ULONG_MAX)
2812 return static_cast<unsigned long>(x);
2814 return PyLong_AsUnsignedLong(obj);
2822 inline double getDouble()
const
2824 if (obj == Py_None)
return 0;
2825 if (PyString_Check(obj))
2827 PyObject* t = PyFloat_FromString(obj, NULL);
2829 double x = PyFloat_AS_DOUBLE(t);
2833 return PyFloat_AsDouble(obj);
2837 inline int getInt()
const
2839 if (PyString_Check(obj))
2841 PyObject* t = PyFloat_FromString(obj, NULL);
2843 double x = PyFloat_AS_DOUBLE(t);
2845 if (x < INT_MIN || x > INT_MAX)
2847 return static_cast<int>(x);
2849 int result = PyInt_AsLong(obj);
2850 if (result == -1 && PyErr_Occurred())
2856 inline long getLong()
const
2858 if (PyString_Check(obj))
2860 PyObject* t = PyFloat_FromString(obj, NULL);
2862 double x = PyFloat_AS_DOUBLE(t);
2864 if (x < LONG_MIN || x > LONG_MIN)
2866 return static_cast<long>(x);
2868 int result = PyInt_AsLong(obj);
2869 if (result == -1 && PyErr_Occurred())
2875 inline bool getBool()
const
2877 return PyObject_IsTrue(obj) ?
true :
false;
2886 if (PyString_Check(obj))
2888 if (PyUnicode_Check(obj))
2891 const_cast<PyObject*&
>(obj) =
2892 PyUnicode_AsEncodedString(obj, PythonInterpreter::getPythonEncoding(),
"ignore");
2894 return TimePeriod(PyString_AsString(PyObject_Str(obj)));
2896 int result = PyInt_AsLong(obj);
2897 if (result == -1 && PyErr_Occurred())
2917 obj = PyString_FromString(val.c_str());
2923 obj = PyFloat_FromDouble(val);
2929 obj = PyInt_FromLong(val);
2935 obj = PyLong_FromLong(val);
2941 obj = PyLong_FromUnsignedLong(val);
2947 obj = val ? Py_True : Py_False;
2956 obj = PyLong_FromLong(val);
2982 if (func) {Py_INCREF(func);}
2988 if (func) {Py_DECREF(func);}
2990 if (func) {Py_INCREF(func);}
2998 operator const PyObject*()
const {
return func;}
3001 operator string()
const {
return func ? PyEval_GetFuncName(func) :
"NULL";}
3004 operator bool()
const {
return func != NULL;}
3045 const xercesc::Attributes* atts;
3071 PyObject* val = PyDict_GetItemString(kwds,k.getName().c_str());
3102 if (PyObject::ob_refcnt > 1)
3103 logger <<
"Warning: Deleting " << PyObject::ob_type->tp_name
3104 <<
" object that is still referenced "
3105 << (PyObject::ob_refcnt-1) <<
" times" << endl;
3124 inline void initType(PyTypeObject *t)
3126 PyObject_INIT(
this,t);
3153 virtual int compare(
const PyObject* other)
const
3163 virtual PyObject* iternext()
3183 virtual PyObject* str()
const
3192 DECLARE_EXPORT static PythonType* registerPythonType(
int,
const type_info*);
3216 PyObject_Init(
this, getType().type_object());
3223 static PythonType& getType()
3225 static PythonType* cachedTypePtr = NULL;
3226 if (cachedTypePtr)
return *cachedTypePtr;
3229 cachedTypePtr = registerPythonType(
sizeof(T), &
typeid(T));
3234 return *cachedTypePtr;
3300 virtual const MetaClass& getType()
const = 0;
3303 virtual size_t getSize()
const = 0;
3324 static PyObject* create
3325 (PyTypeObject* pytype, PyObject* args, PyObject* kwds)
3331 Object* x = T::reader(T::metadata, atts);
3341 PyObject *key, *value;
3343 while (PyDict_Next(kwds, &pos, &key, &value))
3349 int result = x->
setattro(attr, field);
3350 if (result && !PyErr_Occurred())
3351 PyErr_Format(PyExc_AttributeError,
3352 "attribute '%s' on '%s' can't be updated",
3353 PyString_AsString(key), x->ob_type->tp_name);
3361 PythonType::evalException();
3390 #elif defined(HAVE_PTHREAD_H)
3392 Mutex() {pthread_mutex_init(&mtx, 0);}
3393 ~
Mutex() {pthread_mutex_destroy(&mtx);}
3394 void lock() {pthread_mutex_lock(&mtx);}
3395 void unlock() {pthread_mutex_unlock(&mtx);}
3397 pthread_mutex_t mtx;
3400 Mutex() {InitializeCriticalSection(&critsec);}
3402 void lock() {EnterCriticalSection(&critsec);}
3403 void unlock() {LeaveCriticalSection(&critsec);}
3405 CRITICAL_SECTION critsec;
3432 typedef void (*callable)(
void*);
3439 maxParallel = Environment::getProcessorCores();
3449 void add(callable func,
void* args)
3451 callables.push( make_pair(func,args) );
3465 void setMaxParallel(
int b)
3468 throw DataException(
"Invalid number of parallel execution threads");
3470 maxParallel = (b>1 ? 1 : b);
3477 typedef pair<callable,void*> callableWithArgument;
3495 stack<callableWithArgument> callables;
3498 unsigned int countCallables;
3503 #if defined(HAVE_PTHREAD_H) || !defined(MT)
3504 static void* wrapper(
void *arg);
3506 static unsigned __stdcall wrapper(
void *);
3555 bool operator < (
const TreeNode& o) {
return nm < o.nm;}
3568 if (node->right != NULL)
3571 while (node->left != NULL) node = node->left;
3576 while (node == y->right)
3581 if (node->right != y) node = y;
3590 if (node->color == red && node->parent->parent == node)
3592 else if (node->left != NULL)
3595 while (y->right != NULL) y = y->right;
3601 while (node == y->left)
3632 Tree(
bool b =
false) : count(0), clearOnDestruct(b)
3636 header.parent = NULL;
3637 header.left = &header;
3638 header.right = &header;
3662 bool empty()
const {
return header.parent == NULL;}
3668 findLowerBound(newname, &found);
3671 + newname +
"': name already in use");
3682 size_t size()
const {
return count;}
3704 for (
TreeNode* x = header.parent; x; x = comp<0 ? x->left : x->right)
3706 comp = k.compare(x->nm);
3707 if (!comp)
return x;
3718 TreeNode* findLowerBound(
const string& k,
bool* f)
const
3721 for (
TreeNode* x = header.parent; x;)
3723 int comp = k.compare(x->nm);
3730 if (comp<0) x = x->left;
3731 else lower = x, x = x->right;
3751 inline void rebalance(TreeNode* x);
3754 inline void rotateLeft(TreeNode* x);
3757 inline void rotateRight(TreeNode* x);
3760 unsigned int countBlackNodes(TreeNode* node)
const
3762 unsigned int sum = 0;
3763 for ( ; node != header.parent; node=node->parent)
3764 if (node->color == black) ++sum;
3768 TreeNode* minimum(TreeNode* x)
const
3770 while (x->left) x = x->left;
3774 TreeNode* maximum(TreeNode* x)
const
3776 while (x->right) x = x->right;
3798 bool clearOnDestruct;
3836 Command() : owner(NULL), next(NULL), prev(NULL) {};
3981 bool empty()
const {
return firstCommand==NULL;}
4011 nextBookmark(NULL), prevBookmark(NULL), parent(p) {}
4021 for (
const Bookmark* p =
this; p; p = p->parent)
4022 if (p == b)
return true;
4047 cur = cur->nextBookmark;
4056 cur = cur->nextBookmark;
4090 cur = cur->prevBookmark;
4099 cur = cur->prevBookmark;
4117 Bookmark firstBookmark;
4120 Bookmark* lastBookmark;
4126 Bookmark* currentBookmark;
4132 lastBookmark = &firstBookmark;
4133 currentBookmark = &firstBookmark;
4139 for (
Bookmark* i = lastBookmark; i && i != &firstBookmark; )
4142 i = i->prevBookmark;
4217 xercesc::SAX2XMLReader* parser;
4238 const unsigned short maxdepth;
4241 stack <state> states;
4252 vector< pair<Object*,void*> > m_EHStack;
4259 vector<datapair> m_EStack;
4271 unsigned short ignore;
4274 stack<hashtype> endingHashes;
4294 bool abortOnDataException;
4310 DECLARE_EXPORT void startElement (
const XMLCh*
const,
const XMLCh*
const,
4311 const XMLCh*
const,
const xercesc::Attributes&);
4321 (
const XMLCh*
const,
const XMLCh*
const,
const XMLCh*
const);
4326 #if XERCES_VERSION_MAJOR==2
4327 DECLARE_EXPORT void characters(
const XMLCh *
const,
const unsigned int);
4329 DECLARE_EXPORT void characters(
const XMLCh *
const,
const XMLSize_t);
4334 DECLARE_EXPORT void fatalError (
const xercesc::SAXParseException&);
4341 DECLARE_EXPORT void processingInstruction (
const XMLCh *
const,
const XMLCh *
const);
4355 inline Object* getCurrentObject()
const {
return m_EHStack[m_EHStack.size()-1].first;}
4363 : parser(NULL), maxdepth(maxNestedElmnts), m_EStack(maxNestedElmnts+2),
4364 numElements(-1), ignore(0), objectEnded(false),
4365 abortOnDataException(true), attributes(NULL) {}
4403 void invalidateCurrentObject()
4405 if (!m_EHStack.empty())
4406 m_EHStack[m_EHStack.size()-1].first = NULL;
4424 int x = m_EHStack.size();
4425 return x>1 ? m_EHStack[x-2].first : NULL;
4430 {
return m_EStack[numElements>0 ? numElements : 0];}
4434 {
return m_EStack[numElements>-1 ? numElements+1 : 0];}
4441 void parse(xercesc::InputSource&,
Object*,
bool=
false);
4445 void setUserArea(
void* v)
4446 {
if (!m_EHStack.empty()) m_EHStack[m_EHStack.size()-1].second = v;}
4449 void* getUserArea()
const
4450 {
return m_EHStack.empty() ? NULL : m_EHStack[m_EHStack.size()-1].second;}
4505 xercesc::MemBufInputSource a(
4506 reinterpret_cast<const XMLByte*>(data.c_str()),
4507 static_cast<const unsigned int>(data.size()),
4510 XMLInput::parse(a,pRoot,v);
4641 static iterator
end() {
return st.end();}
4644 static iterator
begin() {
return st.begin();}
4647 static bool empty() {
return st.empty();}
4650 static size_t size() {
return st.size();}
4666 void setName(
const string& newname) {st.rename(
this, newname);}
4675 int compare(
const PyObject* other)
const
4677 if (this->ob_type == other->ob_type
4678 || this->ob_type->tp_base == other->ob_type->tp_base)
4679 return getName().compare(static_cast<const T*>(other)->getName());
4690 static T* find(
const string& k)
4693 return (i!=st.end() ?
static_cast<T*
>(i) : NULL);
4701 static T* findLowerBound(
const string& k,
bool *f = NULL)
4704 return (i!=st.end() ?
static_cast<T*
>(i) : NULL);
4711 if (i!=st.end())
return static_cast<T*>(i);
4712 if (*(cls.
category) != T::metadata)
4714 " for creating an object of category " + T::metadata.type);
4721 static T*
add(T* t) {
return static_cast<T*
>(st.insert(t));}
4727 static T*
add(T* t, T* hint) {
return static_cast<T*
>(st.insert(t,hint));}
4751 Action act = MetaClass::decodeAction(in);
4755 if (!*nameElement)
throw DataException(
"Missing name attribute");
4760 T *i = T::findLowerBound(name, &found);
4768 throw DataException(
"Object '" + name +
"' already exists");
4794 throw DataException(
"Can't find object '" + name +
"' for removal");
4801 if (found)
return i;
4813 *type ? Keyword::hash(type->
getString()) : MetaCategory::defaultHash
4817 string t(*type ? type->
getString() :
"default");
4830 if (!x->getType().raiseEvent(x,
SIG_ADD))
4845 if (empty())
return;
4847 for (iterator i = begin(); i != end(); ++i)
4884 size_t extrasize()
const {
return cat.size() + subcat.size() + descr.size();}
4907 class memberIterator;
4908 friend class memberIterator;
4930 curmember = it.curmember;
4931 member_iter = it.member_iter;
4944 curmember = curmember->next_brother;
4946 curmember =
static_cast<T*
>(curmember->increment());
4955 curmember = curmember->next_brother;
4957 curmember =
static_cast<T*
>(curmember->increment());
4963 {
return curmember == y.curmember;}
4967 {
return curmember != y.curmember;}
4971 {
return curmember ? (curmember == &*y) : (y == T::end());}
4975 {
return curmember ? (curmember != &*y) : (y != T::end());}
4985 first_child(NULL), next_brother(NULL) {}
5012 void setOwner(T* f);
5022 unsigned short getHierarchyLevel()
const;
5079 List() : first(NULL) {};
5080 bool empty()
const {
return first==NULL;}
5099 {
return nodeptr == x.
nodeptr;}
5101 {
return nodeptr != x.
nodeptr;}
5103 {nodeptr = nodeptr->nextA;
return *
this;}
5107 nodeptr = nodeptr->nextA;
5121 {
return nodeptr == x.
nodeptr;}
5123 {
return nodeptr != x.
nodeptr;}
5125 {nodeptr = nodeptr->nextA;
return *
this;}
5129 nodeptr = nodeptr->nextA;
5142 for (C* p=this->first; p; p=next)
5150 void erase(
const C* n)
5154 this->first = n->nextA;
5156 for (C* p=this->first; p; p=p->nextA)
5159 p->nextA = n->nextA;
5168 for (C* p = this->first; p; p=p->nextA) ++i;
5173 C* find(
const B* b,
Date d = Date::infinitePast)
const
5175 for (C* p=this->first; p; p=p->nextA)
5176 if (p->ptrB == b && p->effectivity.within(d))
return p;
5181 C* find(
const string& n)
const
5183 for (C* p=this->first; p; p=p->nextA)
5184 if (p->name == n)
return p;
5192 if (p == this->first)
return;
5196 for (C* ptr = this->first; ptr; ptr = ptr->nextA)
5198 if (ptr->nextA == p)
5204 ptr->nextA = p->nextA;
5229 {
return nodeptr == x.
nodeptr;}
5231 {
return nodeptr != x.
nodeptr;}
5233 {nodeptr = nodeptr->nextB;
return *
this;}
5237 nodeptr = nodeptr->nextA;
5251 {
return nodeptr == x.
nodeptr;}
5253 {
return nodeptr != x.
nodeptr;}
5255 {nodeptr = nodeptr->nextB;
return *
this;}
5259 nodeptr = nodeptr->nextA;
5268 for (C* p=this->first; p; p=next)
5280 void erase(
const C* n)
5284 this->first = n->nextB;
5286 for (C* p=this->first; p; p=p->nextB)
5289 p->nextB = n->nextB;
5298 for (C* p=this->first; p; p=p->nextB) ++i;
5303 C* find(
const A* b,
Date d = Date::infinitePast)
const
5305 for (C* p=this->first; p; p=p->nextB)
5306 if (p->ptrA == b && p->effectivity.within(d))
return p;
5311 C* find(
const string& n)
const
5313 for (C* p=this->first; p; p=p->nextB)
5314 if (p->name == n)
return p;
5322 if (p == this->first)
return;
5326 for (C* ptr = this->first; ptr; ptr = ptr->nextB)
5328 if (ptr->nextB == p)
5334 ptr->nextB = p->nextB;
5359 Node() : ptrA(NULL), ptrB(NULL), nextA(NULL), nextB(NULL), priority(1) {};
5363 : ptrA(a), ptrB(b), nextA(NULL), nextB(NULL), priority(1)
5369 while (x->nextA) x = x->nextA;
5370 x->nextA =
static_cast<C*
>(
this);
5374 const_cast<ListA&
>(al).first = static_cast<C*>(
this);
5379 while (x->nextB) x = x->nextB;
5380 x->nextB =
static_cast<C*
>(
this);
5384 const_cast<ListB&
>(bl).first = static_cast<C*>(
this);
5390 if (ptrA)
throw DataException(
"Can't update existing entity");
5396 while (x->nextA) x = x->nextA;
5397 x->nextA =
static_cast<C*
>(
this);
5401 const_cast<ListA&
>(al).first = static_cast<C*>(
this);
5407 if (ptrB)
throw DataException(
"Can't update existing entity");
5413 while (x->nextB) x = x->nextB;
5414 x->nextB =
static_cast<C*
>(
this);
5418 const_cast<ListB&
>(bl).first = static_cast<C*>(
this);
5462 #include "frepple/entity.h"
5479 static void initialize(
int argc,
char* argv[]);
5483 template <
class ME,
class ITERCLASS,
class DATACLASS>
5491 x.
setName(DATACLASS::metadata->type +
"Iterator");
5492 x.
setDoc(
"frePPLe iterator for " + DATACLASS::metadata->type);
5506 static PyObject* create(PyObject*
self, PyObject* args)
5512 virtual PyObject* iternext()
5514 if (i == DATACLASS::end())
return NULL;
5515 PyObject* result = &*i;
5531 #endif // End of FREPPLE_UTILS_H