00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdgeorges.h"
00026
00027 #include "nel/misc/o_xml.h"
00028 #include "nel/misc/i_xml.h"
00029
00030 #include "form.h"
00031 #include "form_elm.h"
00032 #include "form_loader.h"
00033 #include "type.h"
00034
00035 using namespace NLMISC;
00036 using namespace std;
00037
00038 namespace NLGEORGES
00039 {
00040
00041
00042
00043
00044
00045
00046
00047 void warning (bool exception, const char *format, ... );
00048
00049
00050
00051 bool CFormElm::isArray () const
00052 {
00053 return false;
00054 }
00055
00056
00057
00058 bool CFormElm::getArraySize (uint &) const
00059 {
00060 warning (false, "getArraySize", "This node is not an array.");
00061 return false;
00062 }
00063
00064
00065
00066 bool CFormElm::getArrayNode (const UFormElm ** , uint ) const
00067 {
00068 warning (false, "getArrayNode", "This node is not an array.");
00069 return false;
00070 }
00071
00072
00073
00074 bool CFormElm::getArrayNode (UFormElm ** , uint )
00075 {
00076 warning (false, "getArrayNode", "This node is not an array.");
00077 return false;
00078 }
00079
00080
00081
00082 bool CFormElm::getArrayNodeName (std::string &, uint ) const
00083 {
00084 warning (false, "getArrayNodeName", "This node is not an array.");
00085 return false;
00086 }
00087
00088
00089
00090 bool CFormElm::getArrayValue (std::string &, uint , TEval , TWhereIsValue * ) const
00091 {
00092 warning (false, "getArrayNode", "This node is not an array.");
00093 return false;
00094 }
00095
00096
00097
00098 bool CFormElm::getArrayValue (sint8 &, uint , TEval , TWhereIsValue * ) const
00099 {
00100 warning (false, "getArrayValue", "This node is not an array.");
00101 return false;
00102 }
00103
00104
00105
00106 bool CFormElm::getArrayValue (uint8 &, uint , TEval , TWhereIsValue * ) const
00107 {
00108 warning (false, "getArrayValue", "This node is not an array.");
00109 return false;
00110 }
00111
00112
00113
00114 bool CFormElm::getArrayValue (sint16 &, uint , TEval , TWhereIsValue * ) const
00115 {
00116 warning (false, "getArrayValue", "This node is not an array.");
00117 return false;
00118 }
00119
00120
00121
00122 bool CFormElm::getArrayValue (uint16 &, uint , TEval , TWhereIsValue * ) const
00123 {
00124 warning (false, "getArrayValue", "This node is not an array.");
00125 return false;
00126 }
00127
00128
00129
00130 bool CFormElm::getArrayValue (sint32 &, uint , TEval , TWhereIsValue * ) const
00131 {
00132 warning (false, "getArrayValue", "This node is not an array.");
00133 return false;
00134 }
00135
00136
00137
00138 bool CFormElm::getArrayValue (uint32 &, uint , TEval , TWhereIsValue * ) const
00139 {
00140 warning (false, "getArrayValue", "This node is not an array.");
00141 return false;
00142 }
00143
00144
00145
00146 bool CFormElm::getArrayValue (float &, uint , TEval , TWhereIsValue * ) const
00147 {
00148 warning (false, "getArrayValue", "This node is not an array.");
00149 return false;
00150 }
00151
00152
00153
00154 bool CFormElm::getArrayValue (double &, uint , TEval , TWhereIsValue * ) const
00155 {
00156 warning (false, "getArrayValue", "This node is not an array.");
00157 return false;
00158 }
00159
00160
00161
00162 bool CFormElm::getArrayValue (bool &, uint , TEval , TWhereIsValue * ) const
00163 {
00164 warning (false, "getArrayValue", "This node is not an array.");
00165 return false;
00166 }
00167
00168
00169
00170 bool CFormElm::getArrayValue (NLMISC::CRGBA &, uint , TEval , TWhereIsValue * ) const
00171 {
00172 warning (false, "getArrayValue", "This node is not an array.");
00173 return false;
00174 }
00175
00176
00177
00178 bool CFormElm::isStruct () const
00179 {
00180 return false;
00181 }
00182
00183
00184
00185 bool CFormElm::isVirtualStruct () const
00186 {
00187 return false;
00188 }
00189
00190
00191
00192 bool CFormElm::getDfnName (std::string & ) const
00193 {
00194 return false;
00195 }
00196
00197
00198
00199 bool CFormElm::getStructSize (uint &) const
00200 {
00201 warning (false, "getStructSize", "This node is not a struct.");
00202 return false;
00203 }
00204
00205
00206
00207 bool CFormElm::getStructNodeName (uint , string &) const
00208 {
00209 warning (false, "getStructNodeName", "This node is not a struct.");
00210 return false;
00211 }
00212
00213
00214
00215 bool CFormElm::getStructNode (uint , const UFormElm ** ) const
00216 {
00217 warning (false, "getStructNode", "This node is not a struct.");
00218 return false;
00219 }
00220
00221
00222
00223 bool CFormElm::getStructNode (uint , UFormElm ** )
00224 {
00225 warning (false, "getStructNode", "This node is not a struct.");
00226 return false;
00227 }
00228
00229
00230
00231 bool CFormElm::isAtom () const
00232 {
00233 return false;
00234 }
00235
00236
00237
00238 bool CFormElm::getValue (string &, TEval ) const
00239 {
00240 warning (false, "getValue", "This node is not an atom.");
00241 return false;
00242 }
00243
00244
00245
00246 bool CFormElm::getValue (sint8 &, TEval ) const
00247 {
00248 warning (false, "getValue", "This node is not an atom.");
00249 return false;
00250 }
00251
00252
00253
00254 bool CFormElm::getValue (uint8 &, TEval ) const
00255 {
00256 warning (false, "getValue", "This node is not an atom.");
00257 return false;
00258 }
00259
00260
00261
00262 bool CFormElm::getValue (sint16 &, TEval ) const
00263 {
00264 warning (false, "getValue", "This node is not an atom.");
00265 return false;
00266 }
00267
00268
00269
00270 bool CFormElm::getValue (uint16 &, TEval ) const
00271 {
00272 warning (false, "getValue", "This node is not an atom.");
00273 return false;
00274 }
00275
00276
00277
00278 bool CFormElm::getValue (sint32 &, TEval ) const
00279 {
00280 warning (false, "getValue", "This node is not an atom.");
00281 return false;
00282 }
00283
00284
00285
00286 bool CFormElm::getValue (uint32 &, TEval ) const
00287 {
00288 warning (false, "getValue", "This node is not an atom.");
00289 return false;
00290 }
00291
00292
00293
00294 bool CFormElm::getValue (float &, TEval ) const
00295 {
00296 warning (false, "getValue", "This node is not an atom.");
00297 return false;
00298 }
00299
00300
00301
00302 bool CFormElm::getValue (double &, TEval ) const
00303 {
00304 warning (false, "getValue", "This node is not an atom.");
00305 return false;
00306 }
00307
00308
00309
00310 bool CFormElm::getValue (bool &, TEval ) const
00311 {
00312 warning (false, "getValue", "This node is not an atom.");
00313 return false;
00314 }
00315
00316
00317
00318 bool CFormElm::getValue (NLMISC::CRGBA &, TEval ) const
00319 {
00320 warning (false, "getValue", "This node is not an atom.");
00321 return false;
00322 }
00323
00324
00325
00326 CFormElm::CFormElm (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex)
00327 {
00328 Form = form;
00329 ParentNode = parentNode;
00330 ParentDfn = parentDfn;
00331 ParentIndex = parentIndex;
00332 Round = 0xffffffff;
00333 }
00334
00335
00336
00337 CFormElm::~CFormElm ()
00338 {
00339 clean();
00340 }
00341
00342
00343
00344 bool CFormElm::isUsed (const CForm *form) const
00345 {
00346 return form == Form;
00347 }
00348
00349
00350
00351 CForm *CFormElm::getForm () const
00352 {
00353 return Form;
00354 }
00355
00356
00357
00358 bool CFormElm::getNodeByName (UFormElm **result, const char *name, TWhereIsNode *where, bool verbose, uint32 round)
00359 {
00360 const UFormElm *resultConst = NULL;
00361 if (((const UFormElm*)this)->getNodeByName (&resultConst, name, where, verbose, round))
00362 {
00363 *result = const_cast<UFormElm*> (resultConst);
00364 return true;
00365 }
00366 return false;
00367 }
00368
00369
00370
00371 bool CFormElm::getNodeByName (const UFormElm **result, const char *name, TWhereIsNode *where, bool verbose, uint32 round) const
00372 {
00373
00374 const CFormDfn *parentDfn;
00375 const CFormDfn *nodeDfn;
00376 const CType *nodeType;
00377 CFormElm *node;
00378 uint indexDfn;
00379 bool array;
00380 bool parentVDfnArray;
00381 UFormDfn::TEntryType type;
00382
00383
00384 if (getNodeByName (name, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, verbose, round))
00385 {
00386
00387 *result = node;
00388
00389
00390 if (where && node)
00391 {
00392 *where = (node->getForm () == Form) ? NodeForm : NodeParentForm;
00393 }
00394
00395
00396 return true;
00397 }
00398
00399 return false;
00400 }
00401
00402
00403
00404 bool CFormElm::getValueByName (string& result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00405 {
00406
00407 const CFormDfn *parentDfn;
00408 const CFormDfn *nodeDfn;
00409 const CType *nodeType;
00410 CFormElm *node;
00411 uint parentIndex;
00412 bool array;
00413 bool parentVDfnArray;
00414 UFormDfn::TEntryType type;
00415
00416
00417 if (getNodeByName (name, &parentDfn, parentIndex, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, round))
00418 {
00419
00420 if (type == UFormDfn::EntryType)
00421 {
00422
00423 const CFormElmAtom *atom = node ? safe_cast<const CFormElmAtom*> (node) : NULL;
00424
00425
00426 nlassert (nodeType);
00427 return (nodeType->getValue (result, Form, atom, *parentDfn, parentIndex, evaluate, (uint32*)where, round, name));
00428 }
00429 else
00430 {
00431
00432 warning (false, "getValueByName", "The node (%s) is not an atom element. Can't return a value.", name);
00433 }
00434 }
00435 else
00436 {
00437
00438 warning (false, "getValueByName", "Can't find the node (%s).", name);
00439 }
00440
00441
00442 return false;
00443 }
00444
00445
00446
00447 bool CFormElm::getValueByName (sint8 &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00448 {
00449
00450 string value;
00451 if (getValueByName (value, name, evaluate, where, round))
00452 {
00453 return convertValue (result, value.c_str ());
00454 }
00455
00456 return false;
00457 }
00458
00459
00460
00461 bool CFormElm::getValueByName (uint8 &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00462 {
00463
00464 string value;
00465 if (getValueByName (value, name, evaluate, where, round))
00466 {
00467 return convertValue (result, value.c_str ());
00468 }
00469
00470 return false;
00471 }
00472
00473
00474
00475 bool CFormElm::getValueByName (sint16 &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00476 {
00477
00478 string value;
00479 if (getValueByName (value, name, evaluate, where, round))
00480 {
00481 return convertValue (result, value.c_str ());
00482 }
00483
00484 return false;
00485 }
00486
00487
00488
00489 bool CFormElm::getValueByName (uint16 &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00490 {
00491
00492 string value;
00493 if (getValueByName (value, name, evaluate, where, round))
00494 {
00495 return convertValue (result, value.c_str ());
00496 }
00497
00498 return false;
00499 }
00500
00501
00502
00503 bool CFormElm::getValueByName (sint32 &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00504 {
00505
00506 string value;
00507 if (getValueByName (value, name, evaluate, where, round))
00508 {
00509 return convertValue (result, value.c_str ());
00510 }
00511
00512 return false;
00513 }
00514
00515
00516
00517 bool CFormElm::getValueByName (uint32 &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00518 {
00519
00520 string value;
00521 if (getValueByName (value, name, evaluate, where, round))
00522 {
00523 return convertValue (result, value.c_str ());
00524 }
00525
00526 return false;
00527 }
00528
00529
00530
00531 bool CFormElm::getValueByName (float &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00532 {
00533
00534 string value;
00535 if (getValueByName (value, name, evaluate, where, round))
00536 {
00537 return convertValue (result, value.c_str ());
00538 }
00539
00540 return false;
00541 }
00542
00543
00544
00545 bool CFormElm::getValueByName (double &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00546 {
00547
00548 string value;
00549 if (getValueByName (value, name, evaluate, where, round))
00550 {
00551 return convertValue (result, value.c_str ());
00552 }
00553
00554 return false;
00555 }
00556
00557
00558
00559 bool CFormElm::getValueByName (bool &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00560 {
00561
00562 string value;
00563 if (getValueByName (value, name, evaluate, where, round))
00564 {
00565 return convertValue (result, value.c_str ());
00566 }
00567
00568 return false;
00569 }
00570
00571
00572
00573 bool CFormElm::getValueByName (NLMISC::CRGBA &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00574 {
00575
00576 string value;
00577 if (getValueByName (value, name, evaluate, where, round))
00578 {
00579 return convertValue (result, value.c_str ());
00580 }
00581
00582 return false;
00583 }
00584
00585
00586
00587 UFormElm *CFormElm::getParent () const
00588 {
00589 return ParentNode;
00590 }
00591
00592
00593
00594 bool CFormElm::createNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00595 const CFormDfn **nodeDfn, const CType **nodeType,
00596 CFormElm **node, UFormDfn::TEntryType &type,
00597 bool &array, bool &created)
00598 {
00599 *parentDfn = ParentDfn;
00600 indexDfn = ParentIndex;
00601 *nodeDfn = NULL;
00602 *nodeType = NULL;
00603 *node = this;
00604 bool parentVDfnArray;
00605 return getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Create, created, parentVDfnArray, true, NLGEORGES_FIRST_ROUND);
00606 }
00607
00608
00609
00610 bool CFormElm::deleteNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00611 const CFormDfn **nodeDfn, const CType **nodeType,
00612 CFormElm **node, UFormDfn::TEntryType &type,
00613 bool &array)
00614 {
00615 *parentDfn = ParentDfn;
00616 indexDfn = ParentIndex;
00617 *nodeDfn = NULL;
00618 *nodeType = NULL;
00619 *node = this;
00620 bool created;
00621 bool parentVDfnArray;
00622 return getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Delete, created, parentVDfnArray, true, NLGEORGES_FIRST_ROUND);
00623 }
00624
00625
00626
00627 bool CFormElm::getNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00628 const CFormDfn **nodeDfn, const CType **nodeType,
00629 CFormElm **node, UFormDfn::TEntryType &type,
00630 bool &array, bool &parentVDfnArray, bool verbose, uint32 round) const
00631 {
00632 *parentDfn = ParentDfn;
00633 indexDfn = ParentIndex;
00634 *nodeDfn = NULL;
00635 *nodeType = NULL;
00636 *node = (CFormElm*)this;
00637 bool created;
00638 return getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Return, created, parentVDfnArray, verbose, round);
00639 }
00640
00641
00642
00643 bool CFormElm::arrayInsertNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00644 const CFormDfn **nodeDfn, const CType **nodeType,
00645 CFormElm **node, UFormDfn::TEntryType &type,
00646 bool &array, bool verbose, uint arrayIndex) const
00647 {
00648
00649 *parentDfn = ParentDfn;
00650 indexDfn = ParentIndex;
00651 *nodeDfn = NULL;
00652 *nodeType = NULL;
00653 *node = (CFormElm*)this;
00654 bool created;
00655 bool parentVDfnArray;
00656 if (getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Create, created, parentVDfnArray, verbose, NLGEORGES_FIRST_ROUND))
00657 {
00658
00659 nlassert ((*node) && ((*node)->Form == Form));
00660
00661
00662 CFormElm *parentNode = (*node)->ParentNode;
00663 if (parentNode->isArray ())
00664 {
00665
00666 CFormElmArray *array = safe_cast<CFormElmArray*>(parentNode);
00667
00668
00669 if (arrayIndex<array->Elements.size ())
00670 {
00671
00672 array->Elements.insert (array->Elements.begin() + arrayIndex, CFormElmArray::CElement());
00673
00674
00675
00676
00677 CFormElm *newelm = NULL;
00678 switch (type)
00679 {
00680 case UFormDfn::EntryType:
00681 {
00682
00683 CFormElmAtom *atom = new CFormElmAtom (Form, array, *parentDfn, indexDfn);
00684 newelm = atom;
00685 }
00686 break;
00687 case UFormDfn::EntryDfn:
00688 {
00689 CFormElmStruct *_struct = new CFormElmStruct (Form, array, *parentDfn, indexDfn);
00690 _struct->build (*nodeDfn);
00691 newelm = _struct;
00692 }
00693 break;
00694 case UFormDfn::EntryVirtualDfn:
00695
00696
00697 break;
00698 default:
00699 nlstop;
00700 }
00701
00702 nlassert (newelm);
00703
00704
00705 array->Elements[arrayIndex].Element = newelm;
00706
00707
00708 return true;
00709 }
00710 }
00711 }
00712 return false;
00713 }
00714
00715
00716
00717 bool CFormElm::arrayDeleteNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00718 const CFormDfn **nodeDfn, const CType **nodeType,
00719 CFormElm **node, UFormDfn::TEntryType &type,
00720 bool &array, bool verbose, uint arrayIndex) const
00721 {
00722
00723 *parentDfn = ParentDfn;
00724 indexDfn = ParentIndex;
00725 *nodeDfn = NULL;
00726 *nodeType = NULL;
00727 *node = (CFormElm*)this;
00728 bool created;
00729 bool parentVDfnArray;
00730 if (getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Create, created, parentVDfnArray, verbose, NLGEORGES_FIRST_ROUND))
00731 {
00732
00733 nlassert ((*node) && ((*node)->Form == Form));
00734
00735
00736 CFormElm *parentNode = (*node)->ParentNode;
00737 if (parentNode->isArray ())
00738 {
00739
00740 CFormElmArray *array = safe_cast<CFormElmArray*>(parentNode);
00741
00742
00743 if (arrayIndex<array->Elements.size ())
00744 {
00745
00746 if (array->Elements[arrayIndex].Element)
00747 delete array->Elements[arrayIndex].Element;
00748
00749
00750 array->Elements.erase (array->Elements.begin () + arrayIndex);
00751
00752
00753 return true;
00754 }
00755 }
00756 }
00757 return false;
00758 }
00759
00760
00761
00762 bool CFormElm::getInternalNodeByName (CForm *form, const char *name, const CFormDfn **parentDfn, uint &indexDfn, const CFormDfn **nodeDfn, const CType **nodeType, CFormElm **node, UFormDfn::TEntryType &type, bool &array, TNodeAction action, bool &created, bool &parentVDfnArray, bool verbose, uint32 round)
00763 {
00764
00765 created = false;
00766 parentVDfnArray = false;
00767
00768
00769 nlassert ( (*parentDfn) || (*node) );
00770
00771
00772 char error[512];
00773
00774
00775 if (*parentDfn)
00776 {
00777
00778 const CFormDfn::CEntry &theEntry = (*parentDfn)->getEntry (indexDfn);
00779
00780
00781 type = theEntry.getType ();
00782 *nodeType = theEntry.getTypePtr ();
00783 if (type == UFormDfn::EntryVirtualDfn)
00784 {
00785 if (*node)
00786 *nodeDfn = safe_cast <CFormElmVirtualStruct*> (*node)->FormDfn;
00787 else
00788 *nodeDfn = NULL;
00789 }
00790 else
00791 *nodeDfn = theEntry.getDfnPtr ();
00792 array = theEntry.getArrayFlag ();
00793 }
00794 else if (*node)
00795 {
00796 nlassert (!(*node)->isArray ());
00797 indexDfn = 0xffffffff;
00798 *nodeType = (*node)->isAtom () ? safe_cast<CFormElmAtom*>(*node)->Type : NULL;
00799 *nodeDfn = (*node)->isStruct () ? (const CFormDfn *)(safe_cast<CFormElmStruct*>(*node)->FormDfn) : NULL;
00800 type = (*node)->isAtom () ? UFormDfn::EntryType : (*node)->isVirtualStruct () ? UFormDfn::EntryVirtualDfn : UFormDfn::EntryDfn;
00801 array = false;
00802 }
00803
00804
00805 if (action == Create)
00806 {
00807 nlassert (*node);
00808 nlassert ((*node)->getForm () == form);
00809 }
00810
00811
00812 CFormElm *backupFirstElm = *node;
00813
00814
00815
00816
00817 const char *startToken = name;
00818 const char *endToken;
00819
00820
00821 string token;
00822
00823
00824 string currentName;
00825 if (*node)
00826 (*node)->getFormName (currentName);
00827
00828
00829 uint errorIndex;
00830
00831
00832 uint code;
00833
00834
00835 bool inArrayIndex = false;
00836
00837
00838 uint arrayIndex;
00839
00840
00841 bool wantArrayIndex = false;
00842
00843
00844 CFormElmStruct *lastStructElm = ((*node)->ParentNode && (*node)->ParentNode->isStruct ()) ? safe_cast<CFormElmStruct*> ((*node)->ParentNode) : NULL;
00845 uint lastStructIndex = 0;
00846 if (lastStructElm)
00847 {
00848
00849 for (; lastStructIndex<lastStructElm->Elements.size (); lastStructIndex++)
00850 {
00851
00852 if (lastStructElm->Elements[lastStructIndex].Element == (*node))
00853 break;
00854 }
00855
00856
00857 nlassert (lastStructIndex<lastStructElm->Elements.size ());
00858 }
00859
00860
00861 while ((endToken = tokenize (startToken, token, errorIndex, code)))
00862 {
00863
00864 if (!inArrayIndex)
00865 {
00866
00867 switch (code)
00868 {
00869 case TokenString:
00870 {
00871
00872 if (wantArrayIndex)
00873 {
00874
00875 smprintf (error, 512, "Token (%s) should be an array index.", token.c_str());
00876 goto exit;
00877 }
00878
00879
00880 if ( ((type == UFormDfn::EntryDfn) || (type == UFormDfn::EntryVirtualDfn)) )
00881 {
00882
00883 if ( (type == UFormDfn::EntryVirtualDfn) && (*nodeDfn == NULL) )
00884 {
00885
00886 if ( (type == UFormDfn::EntryVirtualDfn) && (*node == NULL) )
00887 parentVDfnArray = true;
00888
00889
00890 if (action == Create)
00891 {
00892
00893 nlassert (*node && lastStructElm);
00894
00895
00896 CFormElmVirtualStruct *vStruct = safe_cast<CFormElmVirtualStruct*> (*node);
00897
00898
00899 string formName;
00900 vStruct->getFormName (formName, NULL);
00901
00902
00903 for (uint parent=0; parent<form->getParentCount (); parent++)
00904 {
00905
00906 CForm *parentPtr = form->getParent (parent);
00907 nlassert (parentPtr);
00908
00909
00910 UFormElm *uelm;
00911 if (parentPtr->getRootNode ().getNodeByName (&uelm, formName.c_str (), NULL, verbose, round+1) && uelm)
00912 {
00913
00914 if (uelm->isVirtualStruct ())
00915 {
00916
00917 CFormElmVirtualStruct *vStructParent = safe_cast<CFormElmVirtualStruct*> (uelm);
00918
00919
00920 vStruct->DfnFilename = vStructParent->DfnFilename;
00921
00922
00923 vStruct->build (vStructParent->FormDfn);
00924
00925
00926 *nodeDfn = vStruct->FormDfn;
00927
00928
00929 break;
00930 }
00931 else
00932 {
00933
00934 smprintf (error, 512, "Internal node parsing error.");
00935 goto exit;
00936 }
00937 }
00938 }
00939 }
00940
00941
00942 if (*nodeDfn == NULL)
00943 {
00944
00945 smprintf (error, 512, "Empty virtual struct element. Can't look into it while it is not defined.");
00946 goto exit;
00947 }
00948 }
00949
00950
00951 nlassert (*nodeDfn);
00952
00953
00954
00955
00956
00957 vector<const CFormDfn*> arrayDfn;
00958 arrayDfn.reserve ((*nodeDfn)->countParentDfn ());
00959 (*nodeDfn)->getParentDfn (arrayDfn);
00960
00961
00962 uint i;
00963 uint formElm = 0;
00964 for (i=0; i<arrayDfn.size(); i++)
00965 {
00966
00967 const CFormDfn &dfn = *(arrayDfn[i]);
00968
00969
00970 uint element;
00971 for (element=0; element<dfn.Entries.size(); element++)
00972 {
00973
00974 if (dfn.Entries[element].Name == token)
00975 {
00976
00977 *parentDfn = &dfn;
00978 indexDfn = element;
00979 *nodeDfn = dfn.Entries[element].Dfn;
00980 *nodeType = dfn.Entries[element].Type;
00981 type = dfn.Entries[element].TypeElement;
00982 array = dfn.Entries[element].Array;
00983 wantArrayIndex = array;
00984
00985
00986 if (*node)
00987 {
00988
00989 CFormElmStruct *nodeStruct = safe_cast<CFormElmStruct*> (*node);
00990 CFormElm *nextElt = nodeStruct->Elements[formElm].Element;
00991
00992
00993 *node = nextElt;
00994
00995
00996 if ( (action == Create) && (*node == NULL) )
00997 {
00998
00999 if (array)
01000 {
01001
01002 CFormElmArray *atom = new CFormElmArray (form, *nodeDfn, *nodeType, nodeStruct, *parentDfn, indexDfn);
01003 *node = atom;
01004 }
01005 else
01006 {
01007
01008 switch (type)
01009 {
01010 case UFormDfn::EntryType:
01011 {
01012
01013 CFormElmAtom *atom = new CFormElmAtom (form, nodeStruct, *parentDfn, indexDfn);
01014 *node = atom;
01015 }
01016 break;
01017 case UFormDfn::EntryDfn:
01018 {
01019 CFormElmStruct *_struct = new CFormElmStruct (form, nodeStruct, *parentDfn, indexDfn);
01020 _struct->build (*nodeDfn);
01021 *node = _struct;
01022 }
01023 break;
01024 case UFormDfn::EntryVirtualDfn:
01025 *node = new CFormElmVirtualStruct (form, nodeStruct, *parentDfn, indexDfn);
01026 break;
01027 default:
01028 nlstop;
01029 }
01030 }
01031
01032
01033 created = true;
01034
01035
01036 nodeStruct->Elements[formElm].Element = *node;
01037 }
01038
01039
01040 if ((*node) && (*node)->isVirtualStruct ())
01041 {
01042
01043 nlassert (*nodeDfn == NULL);
01044
01045
01046 *nodeDfn = safe_cast<const CFormElmVirtualStruct*> (*node)->FormDfn;
01047 }
01048
01049
01050 lastStructElm = nodeStruct;
01051 lastStructIndex = formElm;
01052 }
01053 else
01054 {
01055
01056
01057
01058
01059 *node = NULL;
01060 }
01061
01062 break;
01063 }
01064 formElm++;
01065 }
01066
01067
01068 if (element!=dfn.Entries.size())
01069 break;
01070 }
01071
01072
01073 if (i==arrayDfn.size())
01074 {
01075
01076 smprintf (error, 512, "Struct does not contain element named (%s).", token.c_str());
01077 goto exit;
01078 }
01079 }
01080 else
01081 {
01082
01083 smprintf (error, 512, "Not a struct element. Can't open the node (%s).", token.c_str());
01084 goto exit;
01085 }
01086 }
01087 break;
01088 case TokenPoint:
01089 {
01090
01091 if (wantArrayIndex)
01092 {
01093
01094 smprintf (error, 512, "Token (%s) should be an array index.", token.c_str());
01095 goto exit;
01096 }
01097
01098
01099 if ((type != UFormDfn::EntryDfn) && (type != UFormDfn::EntryVirtualDfn))
01100 {
01101
01102 smprintf (error, 512, "Not a struct element. Can't open the node (%s).", token.c_str());
01103 goto exit;
01104 }
01105 }
01106 break;
01107 case TokenArrayBegin:
01108 {
01109
01110 if (!array)
01111 {
01112
01113 smprintf (error, 512, "Not an array element. Can't open the node (%s).", token.c_str());
01114 goto exit;
01115 }
01116 inArrayIndex = true;
01117 arrayIndex = 0xffffffff;
01118 }
01119 break;
01120 default:
01121 {
01122
01123 smprintf (error, 512, "Syntax error at keyword (%s).", token.c_str ());
01124 goto exit;
01125 }
01126 break;
01127 }
01128 }
01129 else
01130 {
01131 switch (code)
01132 {
01133 case TokenString:
01134 {
01135
01136 if (sscanf (token.c_str(), "%d", &arrayIndex)!=1)
01137 {
01138
01139 smprintf (error, 512, "Keyword (%s) is not an array index.", token.c_str());
01140 goto exit;
01141 }
01142
01143
01144 if (*node == NULL)
01145 parentVDfnArray = true;
01146
01147
01148 if (*node)
01149 {
01150
01151 uint arraySize;
01152 nlverify ((*node)->getArraySize (arraySize));
01153 if (arrayIndex>=arraySize)
01154 {
01155
01156 if (action == Create)
01157 {
01158
01159 nlassert ((*node)->Form == form);
01160
01161
01162 CFormElmArray *array = safe_cast<CFormElmArray*>(*node);
01163 uint oldSize = array->Elements.size ();
01164 array->Elements.resize (arrayIndex+1);
01165
01166
01167 uint i;
01168 for (i=oldSize; i<array->Elements.size (); i++)
01169 {
01170
01171 CFormElm *newelm = NULL;
01172 switch (type)
01173 {
01174 case UFormDfn::EntryType:
01175 {
01176
01177 CFormElmAtom *atom = new CFormElmAtom (form, array, *parentDfn, indexDfn);
01178 newelm = atom;
01179 }
01180 break;
01181 case UFormDfn::EntryDfn:
01182 {
01183 CFormElmStruct *_struct = new CFormElmStruct (form, array, *parentDfn, indexDfn);
01184 _struct->build (*nodeDfn);
01185 newelm = _struct;
01186 }
01187 break;
01188 case UFormDfn::EntryVirtualDfn:
01189
01190
01191 break;
01192 default:
01193 nlstop;
01194 }
01195
01196 nlassert (newelm);
01197
01198
01199 created = true;
01200
01201
01202 array->Elements[i].Element = newelm;
01203 }
01204 }
01205 else
01206 {
01207
01208 smprintf (error, 512, "Out of array bounds (%d >= %d).", arrayIndex, arraySize);
01209 goto exit;
01210 }
01211 }
01212 }
01213 else
01214 {
01215
01216 smprintf (error, 512, "Array is not defined.");
01217 goto exit;
01218 }
01219 }
01220 break;
01221 case TokenArrayEnd:
01222 {
01223
01224 wantArrayIndex = false;
01225
01226
01227 if (arrayIndex == 0xffffffff)
01228 {
01229
01230 smprintf (error, 512, "Missing array index.");
01231 }
01232 else
01233 {
01234
01235 nlassert (*parentDfn);
01236
01237
01238 CFormElmArray *parentNode = safe_cast<CFormElmArray*> (*node);
01239
01240
01241 *node = parentNode->Elements[arrayIndex].Element;
01242
01243
01244 *nodeDfn = (*parentDfn)->getEntry (indexDfn).getDfnPtr ();
01245
01246
01247 *nodeType = (*parentDfn)->getEntry (indexDfn).getTypePtr ();
01248
01249
01250 type = (*parentDfn)->getEntry (indexDfn).getType ();
01251
01252
01253 array = false;
01254
01255
01256 inArrayIndex = false;
01257
01258
01259 if ( (action == Create) && ( *node == NULL) )
01260 {
01261 switch (type)
01262 {
01263 case UFormDfn::EntryType:
01264 {
01265
01266 CFormElmAtom *atom = new CFormElmAtom (form, parentNode, *parentDfn, indexDfn);
01267 *node = atom;
01268 }
01269 break;
01270 case UFormDfn::EntryDfn:
01271 {
01272 CFormElmStruct *_struct = new CFormElmStruct (form, parentNode, *parentDfn, indexDfn);
01273 _struct->build (*nodeDfn);
01274 *node = _struct;
01275 }
01276 break;
01277 case UFormDfn::EntryVirtualDfn:
01278
01279
01280 break;
01281 default:
01282 nlstop;
01283 }
01284
01285 nlassert (*node);
01286
01287
01288 created = true;
01289
01290
01291 parentNode->Elements[arrayIndex].Element = *node;
01292 }
01293
01294
01295 if ((*node) && (*node)->isVirtualStruct ())
01296 {
01297
01298 nlassert (*nodeDfn == NULL);
01299
01300
01301 *nodeDfn = safe_cast<const CFormElmVirtualStruct*> (*node)->FormDfn;
01302 }
01303 }
01304 }
01305 break;
01306 default:
01307 {
01308
01309 smprintf (error, 512, "Keyword (%s) is not an array index.", token.c_str());
01310 goto exit;
01311 }
01312 }
01313 }
01314
01315
01316 currentName += token;
01317 startToken = endToken;
01318 }
01319 exit:;
01320
01321
01322 bool errorAppend = endToken != NULL;
01323
01324
01325 if (!errorAppend)
01326 {
01327
01328 if ( (action == Delete) && (*node) )
01329 {
01330
01331 CFormElm *parent = safe_cast<CFormElm*> ((*node)->getParent ());
01332
01333
01334 if (parent && !parent->isArray ())
01335 {
01336
01337 parent->unlink (*node);
01338
01339
01340 delete (*node);
01341 *node = parent;
01342 parent = (CFormElm*) (parent->getParent ());
01343
01344
01345 while (parent && !(*node)->isUsed (form) && !parent->isArray ())
01346 {
01347
01348 parent->unlink (*node);
01349
01350
01351 delete (*node);
01352 *node = parent;
01353 parent = (CFormElm*) (parent->getParent ());
01354 }
01355
01356
01357 *node = NULL;
01358 }
01359 }
01360 }
01361
01362
01363 if ( ((*node) == NULL) && (action == Return) && backupFirstElm )
01364 {
01365
01366 string formName;
01367 backupFirstElm->getFormName (formName);
01368 uint formNameSize = formName.size ();
01369 if ((formNameSize > 0) && (formName[formNameSize-1] != '.') && (formName[formNameSize-1] != '['))
01370 formName += ".";
01371 formName += name;
01372
01373
01374 bool defaultValue = false;
01375 const CFormDfn *defaultParentDfnParent=0;
01376 uint defaultIndexDfnParent=0;
01377 const CFormDfn *defaultNodeDfnParent=0;
01378 const CType *defaultNodeTypeParent=0;
01379 CFormElm *defaultNodeParent=0;
01380 UFormDfn::TEntryType defaultTypeParent = UFormDfn::EntryType;
01381 bool defaultArrayParent=false;
01382 bool defaultCreatedParent=false;
01383 bool defaultParentVDfnArray=false;
01384
01385
01386 for (uint parent=0; parent<form->getParentCount (); parent++)
01387 {
01388
01389 CForm *parentPtr = form->getParent (parent);
01390 nlassert (parentPtr);
01391
01392
01393 const CFormDfn *parentDfnParent = NULL;
01394 uint indexDfnParent = 0xffffffff;
01395 const CFormDfn *nodeDfnParent = NULL;
01396 const CType *nodeTypeParent = NULL;
01397 CFormElm *nodeParent = (CFormElm*)&parentPtr->getRootNode ();
01398 UFormDfn::TEntryType typeParent;
01399 bool arrayParent;
01400 bool createdParent;
01401 bool parentVDfnArray;
01402 if (getInternalNodeByName (parentPtr, formName.c_str (), &parentDfnParent, indexDfnParent, &nodeDfnParent, &nodeTypeParent, &nodeParent, typeParent, arrayParent, action, createdParent, parentVDfnArray, false, round+1))
01403 {
01404
01405 if (nodeParent)
01406 {
01407
01408 *parentDfn = parentDfnParent;
01409 indexDfn = indexDfnParent;
01410 *nodeDfn = nodeDfnParent;
01411 *nodeType = nodeTypeParent;
01412 *node = nodeParent;
01413 type = typeParent;
01414 array = arrayParent;
01415 created = createdParent;
01416
01417 return true;
01418 }
01419 else
01420 {
01421
01422 if (!defaultValue)
01423 {
01424 defaultParentDfnParent = parentDfnParent;
01425 defaultIndexDfnParent = indexDfnParent;
01426 defaultNodeDfnParent = nodeDfnParent;
01427 defaultNodeTypeParent = nodeTypeParent;
01428 defaultNodeParent = nodeParent;
01429 defaultTypeParent = typeParent;
01430 defaultArrayParent = arrayParent;
01431 defaultCreatedParent = createdParent;
01432 defaultParentVDfnArray = parentVDfnArray;
01433 defaultValue = true;
01434 }
01435 }
01436 }
01437 }
01438
01439
01440 if (defaultValue)
01441 {
01442 *parentDfn = defaultParentDfnParent;
01443 indexDfn = defaultIndexDfnParent;
01444 *nodeDfn = defaultNodeDfnParent;
01445 *nodeType = defaultNodeTypeParent;
01446 *node = defaultNodeParent;
01447 type = defaultTypeParent;
01448 array = defaultArrayParent;
01449 created = defaultCreatedParent;
01450 return true;
01451 }
01452 }
01453
01454
01455 if (*node)
01456 {
01457 if (round > NLGEORGES_MAX_RECURSION)
01458 {
01459
01460 string formName;
01461 (*node)->getFormName (formName);
01462 warning (false, formName.c_str (), form->getFilename ().c_str(), "getInternalNodeByName", "Recursive call on the same node (%s), look for loop references or inheritances.", name);
01463 return false;
01464 }
01465 }
01466
01467 if (verbose && errorAppend)
01468 {
01469 nlassert (*error);
01470
01471
01472 warning (false, currentName.c_str (), form->getFilename ().c_str(), "getInternalNodeByName", "Getting the node (%s) : %s", name, error);
01473 }
01474
01475 return !errorAppend;
01476 }
01477
01478
01479
01480 const char* CFormElm::tokenize (const char *name, string &str, uint &, uint &code)
01481 {
01482 if (*name == 0)
01483 {
01484 return NULL;
01485 }
01486
01487 if (*name == '[')
01488 {
01489 code = TokenArrayBegin;
01490 str = "[";
01491 return name+1;
01492 }
01493
01494 if (*name == ']')
01495 {
01496 code = TokenArrayEnd;
01497 str = "]";
01498 return name+1;
01499 }
01500
01501 if (*name == '.')
01502 {
01503 code = TokenPoint;
01504 str = ".";
01505 return name+1;
01506 }
01507
01508 str = "";
01509 while ( (*name != '.') && (*name != '[') && (*name != ']') && (*name != 0) )
01510 {
01511
01512 str += *name;
01513 name++;
01514 }
01515
01516 code = TokenString;
01517 return name;
01518 }
01519
01520
01521
01522 void CFormElm::unlink (CFormElm * )
01523 {
01524
01525 nlstop;
01526 }
01527
01528
01529
01530 bool CFormElm::setValueByName (const char *value, const char *name, bool *created)
01531 {
01532
01533 const CFormDfn *parentDfn;
01534 const CFormDfn *nodeDfn;
01535 const CType *nodeType;
01536 CFormElm *node;
01537 uint indexDfn;
01538 bool array;
01539 bool _created;
01540 UFormDfn::TEntryType type;
01541
01542
01543 if (createNodeByName (name, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, _created))
01544 {
01545
01546 if (type == UFormDfn::EntryType)
01547 {
01548
01549 CFormElmAtom *atom = node ? safe_cast<CFormElmAtom*> (node) : NULL;
01550
01551
01552 nlassert (nodeType);
01553 atom->setValue (value);
01554
01555
01556 if (created)
01557 *created = _created;
01558 return true;
01559 }
01560 else
01561 {
01562
01563 warning (false, "setValueByName", "The node (%s) is not an atom element. Can't set the value.", name);
01564 }
01565 }
01566 else
01567 {
01568
01569 warning (false, "setValueByName", "Can't created / set the node (%s).", name);
01570
01571
01572 if (created)
01573 *created = false;
01574 }
01575
01576
01577 return false;
01578 }
01579
01580
01581
01582 bool CFormElm::setValueByName (sint8 value, const char *name, bool *created)
01583 {
01584 return setValueByName (toString (value).c_str (), name, created);
01585 }
01586
01587
01588
01589 bool CFormElm::setValueByName (uint8 value, const char *name, bool *created)
01590 {
01591 return setValueByName (toString (value).c_str (), name, created);
01592 }
01593
01594
01595
01596 bool CFormElm::setValueByName (sint16 value, const char *name, bool *created)
01597 {
01598 return setValueByName (toString (value).c_str (), name, created);
01599 }
01600
01601
01602
01603 bool CFormElm::setValueByName (uint16 value, const char *name, bool *created)
01604 {
01605 return setValueByName (toString (value).c_str (), name, created);
01606 }
01607
01608
01609
01610 bool CFormElm::setValueByName (sint32 value, const char *name, bool *created)
01611 {
01612 return setValueByName (toString (value).c_str (), name, created);
01613 }
01614
01615
01616
01617 bool CFormElm::setValueByName (uint32 value, const char *name, bool *created)
01618 {
01619 return setValueByName (toString (value).c_str (), name, created);
01620 }
01621
01622
01623
01624 bool CFormElm::setValueByName (float value, const char *name, bool *created)
01625 {
01626 return setValueByName (toString (value).c_str (), name, created);
01627 }
01628
01629
01630
01631 bool CFormElm::setValueByName (double value, const char *name, bool *created)
01632 {
01633 return setValueByName (toString (value).c_str (), name, created);
01634 }
01635
01636
01637
01638 bool CFormElm::setValueByName (bool value, const char *name, bool *created)
01639 {
01640 return setValueByName (toString (value).c_str (), name, created);
01641 }
01642
01643
01644
01645 bool CFormElm::setValueByName (NLMISC::CRGBA value, const char *name, bool *created)
01646 {
01647 char tmp[512];
01648 smprintf (tmp, 512, "%d,%d,%d", value.R, value.G, value.B);
01649 return setValueByName (tmp, name, created);
01650 }
01651
01652
01653
01654 void CFormElm::warning (bool exception, const char *formName, const char *formFileName, const char *function, const char *format, ... )
01655 {
01656
01657 va_list args;
01658 va_start( args, format );
01659 char buffer[1024];
01660 vsnprintf( buffer, 1024, format, args );
01661 va_end( args );
01662
01663
01664 NLGEORGES::warning (exception, "(CFormElm::%s) on node (%s) in form (%s) : %s", function, formName, formFileName, buffer);
01665 }
01666
01667
01668
01669 void CFormElm::warning (bool exception, const char *function, const char *format, ... ) const
01670 {
01671 va_list args;
01672 va_start( args, format );
01673
01674 string formName;
01675 getFormName (formName);
01676 warning (exception, formName.c_str (), getForm ()->getFilename ().c_str (), function, format, args);
01677
01678 va_end( args );
01679 }
01680
01681
01682
01683
01684
01685 CFormElmStruct::CFormElmStruct (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElm (form, parentNode, parentDfn, parentIndex)
01686 {
01687 FormDfn = NULL;
01688 }
01689
01690
01691
01692 CFormElmStruct::~CFormElmStruct ()
01693 {
01694
01695 }
01696
01697
01698
01699 void CFormElmStruct::clean ()
01700 {
01701
01702 uint elm;
01703 for (elm =0; elm<Elements.size(); elm++)
01704 {
01705 if (Elements[elm].Element)
01706 delete Elements[elm].Element;
01707 Elements[elm].Element = NULL;
01708 }
01709 }
01710
01711
01712
01713 bool CFormElmStruct::isStruct () const
01714 {
01715 return true;
01716 }
01717
01718
01719
01720 bool CFormElmStruct::getStructSize (uint &size) const
01721 {
01722 size = Elements.size();
01723 return true;
01724 }
01725
01726
01727
01728 bool CFormElmStruct::getStructNodeName (uint element, string &result) const
01729 {
01730 if (element<Elements.size())
01731 {
01732 result = Elements[element].Name;
01733 return true;
01734 }
01735 else
01736 {
01737 warning (false, "getStructNodeName", "Index (%d) out of bound (%d).", element, Elements.size() );
01738 return false;
01739 }
01740 }
01741
01742
01743
01744 bool CFormElmStruct::getStructNode (uint element, const UFormElm **result) const
01745 {
01746 if (element<Elements.size())
01747 {
01748 *result = Elements[element].Element;
01749 return true;
01750 }
01751 else
01752 {
01753 warning (false, "getStructNode", "Index (%d) out of bound (%d).", element, Elements.size() );
01754 return false;
01755 }
01756 }
01757
01758
01759
01760 UFormDfn *CFormElmStruct::getStructDfn ()
01761 {
01762 return (CFormDfn*)FormDfn;
01763 }
01764
01765
01766
01767 bool CFormElmStruct::getStructNode (uint element, UFormElm **result)
01768 {
01769 if (element<Elements.size())
01770 {
01771 *result = Elements[element].Element;
01772 return true;
01773 }
01774 else
01775 {
01776 warning (false, "getStructNode", "Index (%d) out of bound (%d).", element, Elements.size() );
01777 return false;
01778 }
01779 }
01780
01781
01782
01783 xmlNodePtr CFormElmStruct::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
01784 {
01785
01786 if (isUsed (form) || forceWrite)
01787 {
01788
01789 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"STRUCT", NULL);
01790
01791
01792 if (structName != NULL)
01793 {
01794
01795 xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
01796 }
01797
01798
01799 uint elm;
01800 for (elm=0; elm<Elements.size(); elm++)
01801 {
01802
01803 if (Elements[elm].Element)
01804 Elements[elm].Element->write (node, form, Elements[elm].Name.c_str());
01805 }
01806
01807
01808 return node;
01809 }
01810 return NULL;
01811 }
01812
01813
01814
01815 void CFormElmStruct::read (xmlNodePtr node, CFormLoader &loader, const CFormDfn *dfn, CForm *form)
01816 {
01817
01818 FormDfn = (CFormDfn*)dfn;
01819
01820
01821 build (dfn);
01822
01823
01824 uint dfnCount = dfn->countParentDfn ();
01825
01826
01827 std::vector<const CFormDfn*> dfnArray;
01828 dfnArray.reserve (dfnCount);
01829 dfn->getParentDfn (dfnArray);
01830
01831
01832 uint dfnId;
01833 uint elmIndex=0;
01834 for (dfnId=0; dfnId<dfnCount; dfnId++)
01835 {
01836
01837 uint elm;
01838 for (elm=0; elm<dfnArray[dfnId]->Entries.size(); elm++)
01839 {
01840
01841
01842
01843
01844 xmlNodePtr child = NULL;
01845
01846
01847 if (node)
01848 child = node->children;
01849
01850 while (child)
01851 {
01852
01853 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
01854 if (name && (dfnArray[dfnId]->Entries[elm].getName () == name) )
01855 {
01856
01857 bool atom=false;
01858 bool array=false;
01859 bool _struct=false;
01860 bool vStruct=false;
01861
01862
01863 if (strcmp ((const char*)child->name, "ATOM") == 0)
01864 {
01865 atom = true;
01866 }
01867
01868 else if (strcmp ((const char*)child->name, "STRUCT") == 0)
01869 {
01870 _struct = true;
01871 }
01872
01873 else if (strcmp ((const char*)child->name, "VSTRUCT") == 0)
01874 {
01875 vStruct = true;
01876 }
01877
01878 else if (strcmp ((const char*)child->name, "ARRAY") == 0)
01879 {
01880 array = true;
01881 }
01882
01883
01884 if (atom || _struct || vStruct || array)
01885 {
01886
01887 if (
01888 (atom && (dfnArray[dfnId]->Entries[elm].getType ()==UFormDfn::EntryType) && (!dfnArray[dfnId]->Entries[elm].getArrayFlag ()) ) ||
01889 (array && dfnArray[dfnId]->Entries[elm].getArrayFlag () && ( (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryType) || (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn) ) ) ||
01890 (_struct && (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn) && (!dfnArray[dfnId]->Entries[elm].getArrayFlag ()) ) ||
01891 (vStruct && (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryVirtualDfn) && (!dfnArray[dfnId]->Entries[elm].getArrayFlag ()) )
01892 )
01893 {
01894
01895 xmlFree((void*) name);
01896 break;
01897 }
01898 else
01899 {
01900
01901 warning (false, "read", "In block line %d, node (%s) type in DFN have changed.",
01902 (ptrdiff_t)child->content, child->name);
01903 }
01904 }
01905 else
01906 {
01907 if (name)
01908 {
01909
01910 xmlFree ((void*)name);
01911 }
01912
01913
01914 warning (true, "read", "XML Syntax error in block line %d, node (%s) name should be STRUCT, ATOM or ARRAY.",
01915 (ptrdiff_t)child->content, child->name);
01916 }
01917 }
01918
01919 if (name)
01920 {
01921
01922 xmlFree ((void*)name);
01923 }
01924
01925
01926 child = child->next;
01927 }
01928
01929
01930 if (child)
01931 {
01932
01933 if (dfnArray[dfnId]->Entries[elm].getArrayFlag ())
01934 {
01935
01936 CFormElmArray *newElm = NULL;
01937 if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryType)
01938 {
01939
01940 newElm = new CFormElmArray (form, NULL, dfnArray[dfnId]->Entries[elm].getTypePtr (), this, dfnArray[dfnId], elm);
01941 }
01942
01943 else if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn)
01944 {
01945 newElm = new CFormElmArray (form, dfnArray[dfnId]->Entries[elm].getDfnPtr (), NULL, this, dfnArray[dfnId], elm);
01946 }
01947
01948
01949 nlassert (newElm);
01950 Elements[elmIndex].Element = newElm;
01951 newElm->read (child, loader, form);
01952 }
01953 else if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryType)
01954 {
01955
01956 CFormElmAtom *newElm = new CFormElmAtom (form, this, dfnArray[dfnId], elm);
01957 Elements[elmIndex].Element = newElm;
01958 newElm->read (child, loader, dfnArray[dfnId]->Entries[elm].getTypePtr (), form);
01959 }
01960 else if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn)
01961 {
01962
01963 CFormElmStruct *newElm = new CFormElmStruct (form, this, dfnArray[dfnId], elm);
01964 Elements[elmIndex].Element = newElm;
01965 newElm->read (child, loader, dfnArray[dfnId]->Entries[elm].getDfnPtr (), form);
01966 }
01967 else
01968 {
01969
01970 nlassert (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryVirtualDfn);
01971
01972
01973 CFormElmVirtualStruct *newElm = new CFormElmVirtualStruct (form, this, dfnArray[dfnId], elm);
01974 Elements[elmIndex].Element = newElm;
01975 newElm->read (child, loader, form);
01976 }
01977 }
01978 else
01979 Elements[elmIndex].Element = NULL;
01980
01981 elmIndex++;
01982 }
01983 }
01984 }
01985
01986
01987
01988 bool CFormElmStruct::isUsed (const CForm *form) const
01989 {
01990 for (uint i=0; i<Elements.size(); i++)
01991 {
01992 if (Elements[i].Element && Elements[i].Element->isUsed (form))
01993 return true;
01994 }
01995 return false;
01996 }
01997
01998
01999
02000 void CFormElmStruct::build (const CFormDfn *dfn)
02001 {
02002
02003 clean ();
02004
02005
02006 FormDfn = (CFormDfn*)dfn;
02007
02008
02009 vector<const CFormDfn*> arrayDfn;
02010 arrayDfn.reserve (dfn->countParentDfn ());
02011 dfn->getParentDfn (arrayDfn);
02012
02013
02014 uint elementCount = 0;
02015 uint dfnIndex;
02016 for (dfnIndex=0; dfnIndex<arrayDfn.size(); dfnIndex++)
02017 {
02018 elementCount += arrayDfn[dfnIndex]->getNumEntry();
02019 }
02020
02021
02022 Elements.resize (elementCount);
02023
02024 elementCount = 0;
02025 for (dfnIndex=0; dfnIndex<arrayDfn.size(); dfnIndex++)
02026 {
02027
02028 for (uint elm=0; elm<arrayDfn[dfnIndex]->Entries.size(); elm++)
02029 {
02030
02031 Elements[elementCount].Name = arrayDfn[dfnIndex]->Entries[elm].Name;
02032 elementCount++;
02033 }
02034 }
02035 }
02036
02037
02038
02039 void CFormElmStruct::unlink (CFormElm *child)
02040 {
02041 uint i;
02042 for (i=0; i<Elements.size (); i++)
02043 {
02044 if (Elements[i].Element == child)
02045 {
02046 Elements[i].Element = NULL;
02047 break;
02048 }
02049 }
02050
02051
02052 nlassert (i != Elements.size ());
02053 }
02054
02055
02056
02057 void CFormElmStruct::getFormName (std::string &result, const CFormElm *child) const
02058 {
02059
02060 if (child == NULL)
02061 {
02062 result = "";
02063 result.reserve (50);
02064 }
02065
02066
02067 if (ParentNode)
02068 ParentNode->getFormName (result, this);
02069
02070
02071 if (child)
02072 {
02073
02074 uint i;
02075 for (i=0; i<Elements.size (); i++)
02076 {
02077
02078 if (Elements[i].Element == child)
02079 {
02080
02081 result += ".";
02082 result += Elements[i].Name;
02083 break;
02084 }
02085 }
02086
02087
02088 if (i==Elements.size ())
02089 {
02090 warning (false, "getFormName", "Child node not found.");
02091 }
02092 }
02093 }
02094
02095
02096
02097 void CFormElmStruct::warning (bool exception, const char *function, const char *format, ... ) const
02098 {
02099
02100 va_list args;
02101 va_start( args, format );
02102 char buffer[1024];
02103 vsnprintf( buffer, 1024, format, args );
02104 va_end( args );
02105
02106
02107 string formName;
02108 getFormName (formName, NULL);
02109 NLGEORGES::warning (exception, "(CFormElmStruct::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
02110 }
02111
02112
02113
02114 void CFormElmStruct::getDependencies (std::set<std::string> &dependencies) const
02115 {
02116
02117 if (FormDfn)
02118 FormDfn->getDependencies (dependencies);
02119
02120
02121 for (uint i=0; i<Elements.size (); i++)
02122 {
02123 if (Elements[i].Element)
02124 Elements[i].Element->getDependencies (dependencies);
02125 }
02126 }
02127
02128
02129
02130
02131
02132 CFormElmVirtualStruct::CFormElmVirtualStruct (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElmStruct (form, parentNode, parentDfn, parentIndex)
02133 {
02134 }
02135
02136
02137
02138 xmlNodePtr CFormElmVirtualStruct::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
02139 {
02140
02141 if (isUsed (form) || forceWrite)
02142 {
02143
02144 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"VSTRUCT", NULL);
02145
02146
02147 xmlSetProp (node, (const xmlChar*)"DfnName", (const xmlChar*)DfnFilename.c_str());
02148
02149
02150 if (structName != NULL)
02151 {
02152
02153 xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02154 }
02155
02156
02157 uint elm;
02158 for (elm=0; elm<Elements.size(); elm++)
02159 {
02160
02161 if (Elements[elm].Element)
02162 Elements[elm].Element->write (node, form, Elements[elm].Name.c_str());
02163 }
02164
02165
02166 return node;
02167 }
02168 return NULL;
02169 }
02170
02171
02172
02173 void CFormElmVirtualStruct::read (xmlNodePtr node, CFormLoader &loader, CForm *form)
02174 {
02175
02176 const char *filename = (const char*)xmlGetProp (node, (xmlChar*)"DfnName");
02177 if (filename)
02178 {
02179
02180 DfnFilename = filename;
02181
02182
02183 xmlFree ((void*)filename);
02184
02185
02186 FormDfn = loader.loadFormDfn (DfnFilename.c_str (), false);
02187 if (!FormDfn)
02188 {
02189
02190 warning (true, "read", "Can't find DFN filename (%s).", DfnFilename.c_str ());
02191 }
02192 }
02193 else
02194 {
02195
02196 warning (true, "read", "XML Syntax error in virtual struct in block line %d, should have a DfnName property.",
02197 (ptrdiff_t)node->content, node->name);
02198 }
02199
02200
02201 CFormElmStruct::read (node, loader, FormDfn, form);
02202 }
02203
02204
02205
02206 bool CFormElmVirtualStruct::isVirtualStruct () const
02207 {
02208 return true;
02209 }
02210
02211
02212
02213 bool CFormElmVirtualStruct::getDfnName (std::string &dfnName ) const
02214 {
02215 dfnName = DfnFilename;
02216 return true;
02217 }
02218
02219
02220
02221 bool CFormElmVirtualStruct::isUsed (const CForm * ) const
02222 {
02223 return true;
02224 }
02225
02226
02227
02228 void CFormElmVirtualStruct::warning (bool exception, const char *function, const char *format, ... ) const
02229 {
02230
02231 va_list args;
02232 va_start( args, format );
02233 char buffer[1024];
02234 vsnprintf( buffer, 1024, format, args );
02235 va_end( args );
02236
02237
02238 string formName;
02239 getFormName (formName, NULL);
02240 NLGEORGES::warning (exception, "(CFormElmVirtualStruct::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
02241 }
02242
02243
02244
02245
02246
02247 CFormElmArray::CFormElmArray (CForm *form, const CFormDfn *formDfn, const CType *type, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElm (form, parentNode, parentDfn, parentIndex)
02248 {
02249 FormDfn = (CFormDfn*)formDfn;
02250 Type = type;
02251 }
02252
02253
02254
02255 CFormElmArray::~CFormElmArray ()
02256 {
02257
02258 }
02259
02260
02261
02262 void CFormElmArray::clean ()
02263 {
02264
02265 uint elm;
02266 for (elm =0; elm<Elements.size(); elm++)
02267 {
02268 if (Elements[elm].Element)
02269 delete Elements[elm].Element;
02270 }
02271 Elements.clear ();
02272 }
02273
02274
02275
02276 bool CFormElmArray::isArray () const
02277 {
02278 return true;
02279 }
02280
02281
02282
02283 bool CFormElmArray::getArraySize (uint &size) const
02284 {
02285 size = Elements.size ();
02286 return true;
02287 }
02288
02289
02290
02291 bool CFormElmArray::getArrayNode (const UFormElm **result, uint arrayIndex) const
02292 {
02293 if (arrayIndex<Elements.size())
02294 {
02295 *result = Elements[arrayIndex].Element;
02296 return true;
02297 }
02298 else
02299 {
02300 warning (false, "getArrayNode", "Index (%d) out of bound (%d).", arrayIndex, Elements.size() );
02301 return false;
02302 }
02303 }
02304
02305
02306
02307 bool CFormElmArray::getArrayNodeName (std::string &result, uint arrayIndex) const
02308 {
02309 if (arrayIndex<Elements.size())
02310 {
02311 if (Elements[arrayIndex].Name.empty ())
02312 result = "#" + toString (arrayIndex);
02313 else
02314 result = Elements[arrayIndex].Name;
02315 return true;
02316 }
02317 else
02318 {
02319 warning (false, "getArrayNodeName", "Index (%d) out of bound (%d).", arrayIndex, Elements.size() );
02320 return false;
02321 }
02322 }
02323
02324
02325
02326 bool CFormElmArray::getArrayNode (UFormElm **result, uint arrayIndex)
02327 {
02328 if (arrayIndex<Elements.size())
02329 {
02330 *result = Elements[arrayIndex].Element;
02331 return true;
02332 }
02333 else
02334 {
02335 warning (false, "getArrayNode", "Index (%d) out of bound (%d).", arrayIndex, Elements.size() );
02336 return false;
02337 }
02338 }
02339
02340
02341
02342
02343 bool CFormElmArray::getArrayValue (std::string &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02344 {
02345 if (arrayIndex >= Elements.size())
02346 {
02347 warning (false, "getArrayValue", "Access out of bound, trying to access array index %u, array size is %u.", arrayIndex, Elements.size());
02348 }
02349 else if (Type)
02350 {
02351 return (Type->getValue (result, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL));
02352 }
02353 else
02354 {
02355 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02356 }
02357
02358 return false;
02359 }
02360
02361
02362
02363 bool CFormElmArray::getArrayValue (sint8 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02364 {
02365 if (Type)
02366 {
02367 string str;
02368 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02369 {
02370 return convertValue (result, str.c_str ());
02371 }
02372 }
02373 else
02374 {
02375 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02376 }
02377
02378 return false;
02379 }
02380
02381
02382
02383 bool CFormElmArray::getArrayValue (uint8 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02384 {
02385 if (Type)
02386 {
02387 string str;
02388 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02389 {
02390 return convertValue (result, str.c_str ());
02391 }
02392 }
02393 else
02394 {
02395 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02396 }
02397
02398 return false;
02399 }
02400
02401
02402
02403 bool CFormElmArray::getArrayValue (sint16 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02404 {
02405 if (Type)
02406 {
02407 string str;
02408 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02409 {
02410 return convertValue (result, str.c_str ());
02411 }
02412 }
02413 else
02414 {
02415 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02416 }
02417
02418 return false;
02419 }
02420
02421
02422
02423 bool CFormElmArray::getArrayValue (uint16 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02424 {
02425 if (Type)
02426 {
02427 string str;
02428 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02429 {
02430 return convertValue (result, str.c_str ());
02431 }
02432 }
02433 else
02434 {
02435 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02436 }
02437
02438 return false;
02439 }
02440
02441
02442
02443 bool CFormElmArray::getArrayValue (sint32 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02444 {
02445 if (Type)
02446 {
02447 string str;
02448 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02449 {
02450 return convertValue (result, str.c_str ());
02451 }
02452 }
02453 else
02454 {
02455 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02456 }
02457
02458 return false;
02459 }
02460
02461
02462
02463 bool CFormElmArray::getArrayValue (uint32 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02464 {
02465 if (Type)
02466 {
02467 string str;
02468 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02469 {
02470 return convertValue (result, str.c_str ());
02471 }
02472 }
02473 else
02474 {
02475 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02476 }
02477
02478 return false;
02479 }
02480
02481
02482
02483 bool CFormElmArray::getArrayValue (float &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02484 {
02485 if (Type)
02486 {
02487 string str;
02488 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02489 {
02490 return convertValue (result, str.c_str ());
02491 }
02492 }
02493 else
02494 {
02495 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02496 }
02497
02498 return false;
02499 }
02500
02501
02502
02503 bool CFormElmArray::getArrayValue (double &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02504 {
02505 if (Type)
02506 {
02507 string str;
02508 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02509 {
02510 return convertValue (result, str.c_str ());
02511 }
02512 }
02513 else
02514 {
02515 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02516 }
02517
02518 return false;
02519 }
02520
02521
02522
02523 bool CFormElmArray::getArrayValue (bool &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02524 {
02525 if (Type)
02526 {
02527 string str;
02528 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02529 {
02530 return convertValue (result, str.c_str ());
02531 }
02532 }
02533 else
02534 {
02535 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02536 }
02537
02538 return false;
02539 }
02540
02541
02542
02543 bool CFormElmArray::getArrayValue (NLMISC::CRGBA &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02544 {
02545 if (Type)
02546 {
02547 string str;
02548 if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02549 {
02550 return convertValue (result, str.c_str ());
02551 }
02552 }
02553 else
02554 {
02555 warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02556 }
02557
02558 return false;
02559 }
02560
02561
02562
02563 xmlNodePtr CFormElmArray::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
02564 {
02565
02566 if (isUsed (form) || forceWrite)
02567 {
02568
02569 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"ARRAY", NULL);
02570
02571
02572 if (structName != NULL)
02573 {
02574
02575 xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02576 }
02577
02578
02579 uint elm;
02580 for (elm=0; elm<Elements.size(); elm++)
02581 {
02582
02583 if (Elements[elm].Element)
02584 Elements[elm].Element->write (node, form, Elements[elm].Name.empty ()?NULL:Elements[elm].Name.c_str (), true);
02585 }
02586
02587
02588 return node;
02589 }
02590
02591 return NULL;
02592 }
02593
02594
02595
02596 void CFormElmArray::read (xmlNodePtr node, CFormLoader &loader, CForm *form)
02597 {
02598
02599 clean ();
02600
02601
02602 if (node)
02603 {
02604
02605 if (Type)
02606 {
02607 nlassert (FormDfn == NULL);
02608
02609
02610 uint childCount = CIXml::countChildren (node, "ATOM");
02611
02612
02613 Elements.resize (childCount);
02614
02615
02616 uint childNum=0;
02617 xmlNodePtr child = CIXml::getFirstChildNode (node, "ATOM");
02618 while (child)
02619 {
02620
02621 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
02622
02623
02624 CFormElmAtom *newElt = new CFormElmAtom (form, this, ParentDfn, ParentIndex);
02625 Elements[childNum].Element = newElt;
02626 if (name)
02627 {
02628 Elements[childNum].Name = name;
02629 xmlFree ((void*)name);
02630 }
02631 newElt->read (child, loader, Type, form);
02632
02633
02634 child = CIXml::getNextChildNode (child, "ATOM");
02635 childNum++;
02636 }
02637 }
02638 else
02639 {
02640 nlassert (FormDfn);
02641 nlassert (Type == NULL);
02642
02643
02644 uint childCount = CIXml::countChildren (node, "STRUCT");
02645
02646
02647 Elements.resize (childCount);
02648
02649
02650 uint childNum=0;
02651 xmlNodePtr child = CIXml::getFirstChildNode (node, "STRUCT");
02652 while (child)
02653 {
02654
02655 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
02656
02657
02658 CFormElmStruct *newElt = new CFormElmStruct (form, this, ParentDfn, ParentIndex);
02659 Elements[childNum].Element = newElt;
02660 if (name)
02661 {
02662 Elements[childNum].Name = name;
02663 xmlFree ((void*)name);
02664 }
02665 newElt->read (child, loader, FormDfn, form);
02666
02667
02668 child = CIXml::getNextChildNode (child, "STRUCT");
02669 childNum++;
02670 }
02671 }
02672 }
02673 }
02674
02675
02676
02677 bool CFormElmArray::setParent (CFormElm * )
02678 {
02679 return true;
02680 }
02681
02682
02683
02684 void CFormElmArray::unlink (CFormElm *child)
02685 {
02686 uint i;
02687 for (i=0; i<Elements.size (); i++)
02688 {
02689 if (Elements[i].Element == child)
02690 {
02691 Elements[i].Element = NULL;
02692 break;
02693 }
02694 }
02695
02696
02697 nlassert (i != Elements.size ());
02698 }
02699
02700
02701
02702 bool CFormElmArray::isUsed (const CForm *form) const
02703 {
02704
02705
02706
02707
02708
02709 return form == Form;
02710 }
02711
02712
02713
02714 void CFormElmArray::getFormName (std::string &result, const CFormElm *child) const
02715 {
02716
02717 if (child == NULL)
02718 {
02719 result = "";
02720 result.reserve (50);
02721 }
02722
02723
02724 if (ParentNode)
02725 ParentNode->getFormName (result, this);
02726
02727
02728 if (child)
02729 {
02730
02731 uint i;
02732 for (i=0; i<Elements.size (); i++)
02733 {
02734
02735 if (Elements[i].Element == child)
02736 {
02737 char name[512];
02738 smprintf (name, 512, "[%d]", i);
02739
02740
02741 result += name;
02742 break;
02743 }
02744 }
02745
02746
02747 if (i==Elements.size ())
02748 {
02749 warning (false, "getFormName", "Child node not found.");
02750 }
02751 }
02752 }
02753
02754
02755
02756 void CFormElmArray::warning (bool exception, const char *function, const char *format, ... ) const
02757 {
02758
02759 va_list args;
02760 va_start( args, format );
02761 char buffer[1024];
02762 vsnprintf( buffer, 1024, format, args );
02763 va_end( args );
02764
02765
02766 string formName;
02767 getFormName (formName, NULL);
02768 NLGEORGES::warning (exception, "(CFormElmArray::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
02769 }
02770
02771
02772
02773 void CFormElmArray::getDependencies (std::set<std::string> &dependencies) const
02774 {
02775 if (FormDfn)
02776 {
02777
02778 FormDfn->getDependencies (dependencies);
02779
02780
02781 for (uint i=0; i<Elements.size (); i++)
02782 {
02783 Elements[i].Element->getDependencies (dependencies);
02784 }
02785 }
02786
02787 if (Type)
02788 {
02789
02790 Type->getDependencies (dependencies);
02791 }
02792 }
02793
02794
02795
02796
02797
02798 CFormElmAtom::CFormElmAtom (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElm (form, parentNode, parentDfn, parentIndex)
02799 {
02800 Type = NULL;
02801 }
02802
02803
02804
02805 bool CFormElmAtom::isAtom () const
02806 {
02807 return true;
02808 }
02809
02810
02811
02812 void CFormElmAtom::getDependencies (std::set<std::string> &) const
02813 {
02814 }
02815
02816
02817
02818 bool CFormElmAtom::getValue (string &result, TEval evaluate) const
02819 {
02820 nlassert (Type);
02821
02822
02823 return Type->getValue (result, Form, this, *ParentDfn, ParentIndex, evaluate, NULL, NLGEORGES_FIRST_ROUND, "");
02824 }
02825
02826
02827
02828 bool CFormElmAtom::getValue (sint8 &result, TEval evaluate) const
02829 {
02830
02831 string value;
02832 if (getValue (value, evaluate))
02833 {
02834 return convertValue (result, value.c_str ());
02835 }
02836
02837 return false;
02838 }
02839
02840
02841
02842 bool CFormElmAtom::getValue (uint8 &result, TEval evaluate) const
02843 {
02844
02845 string value;
02846 if (getValue (value, evaluate))
02847 {
02848 return convertValue (result, value.c_str ());
02849 }
02850
02851 return false;
02852 }
02853
02854
02855
02856 bool CFormElmAtom::getValue (sint16 &result, TEval evaluate) const
02857 {
02858
02859 string value;
02860 if (getValue (value, evaluate))
02861 {
02862 return convertValue (result, value.c_str ());
02863 }
02864
02865 return false;
02866 }
02867
02868
02869
02870 bool CFormElmAtom::getValue (uint16 &result, TEval evaluate) const
02871 {
02872
02873 string value;
02874 if (getValue (value, evaluate))
02875 {
02876 return convertValue (result, value.c_str ());
02877 }
02878
02879 return false;
02880 }
02881
02882
02883
02884 bool CFormElmAtom::getValue (sint32 &result, TEval evaluate) const
02885 {
02886
02887 string value;
02888 if (getValue (value, evaluate))
02889 {
02890 return convertValue (result, value.c_str ());
02891 }
02892
02893 return false;
02894 }
02895
02896
02897
02898 bool CFormElmAtom::getValue (uint32 &result, TEval evaluate) const
02899 {
02900
02901 string value;
02902 if (getValue (value, evaluate))
02903 {
02904 return convertValue (result, value.c_str ());
02905 }
02906
02907 return false;
02908 }
02909
02910
02911
02912 bool CFormElmAtom::getValue (float &result, TEval evaluate) const
02913 {
02914
02915 string value;
02916 if (getValue (value, evaluate))
02917 {
02918 return convertValue (result, value.c_str ());
02919 }
02920
02921 return false;
02922 }
02923
02924
02925
02926 bool CFormElmAtom::getValue (double &result, TEval evaluate) const
02927 {
02928
02929 string value;
02930 if (getValue (value, evaluate))
02931 {
02932 return convertValue (result, value.c_str ());
02933 }
02934
02935 return false;
02936 }
02937
02938
02939
02940 bool CFormElmAtom::getValue (bool &result, TEval evaluate) const
02941 {
02942
02943 string value;
02944 if (getValue (value, evaluate))
02945 {
02946 return convertValue (result, value.c_str ());
02947 }
02948
02949 return false;
02950 }
02951
02952
02953
02954 bool CFormElmAtom::getValue (NLMISC::CRGBA &result, TEval evaluate) const
02955 {
02956
02957 string value;
02958 if (getValue (value, evaluate))
02959 {
02960 return convertValue (result, value.c_str ());
02961 }
02962
02963 return false;
02964 }
02965
02966
02967
02968 xmlNodePtr CFormElmAtom::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
02969 {
02970
02971 if (isUsed (form) || forceWrite)
02972 {
02973
02974 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"ATOM", NULL);
02975
02976
02977 if (structName != NULL)
02978 {
02979
02980 xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02981 }
02982
02983
02984 if (!Value.empty ())
02985 {
02986 if (COXml::isStringValidForProperties (Value.c_str ()))
02987 xmlSetProp (node, (const xmlChar*)"Value", (const xmlChar*)Value.c_str());
02988 else
02989 {
02990 xmlNodePtr textNode = xmlNewText ((const xmlChar *)Value.c_str ());
02991 xmlAddChild (node, textNode);
02992 }
02993 }
02994
02995
02996 return node;
02997 }
02998 return NULL;
02999 }
03000
03001
03002
03003 void CFormElmAtom::read (xmlNodePtr node, CFormLoader &, const CType *type, CForm * )
03004 {
03005
03006 Type = type;
03007
03008
03009 if (node)
03010 {
03011
03012 const char *value = (const char*)xmlGetProp (node, (xmlChar*)"Value");
03013 if (value)
03014 {
03015
03016 setValue (value);
03017
03018
03019 xmlFree ((void*)value);
03020 }
03021 else
03022 {
03023
03024 const char *valueText = (const char*)xmlNodeGetContent (node);
03025 if (valueText)
03026 {
03027 setValue (valueText);
03028
03029
03030 xmlFree ((void*)valueText);
03031 }
03032 }
03033 }
03034 }
03035
03036
03037
03038 void CFormElmAtom::setValue (const char *value)
03039 {
03040 Value = value;
03041 }
03042
03043
03044
03045 void CFormElmAtom::getFormName (std::string &result, const CFormElm *child) const
03046 {
03047
03048 nlassert (child == NULL);
03049 result = "";
03050 result.reserve (50);
03051
03052
03053 if (ParentNode)
03054 ParentNode->getFormName (result, this);
03055 }
03056
03057
03058
03059 void CFormElmAtom::warning (bool exception, const char *function, const char *format, ... ) const
03060 {
03061
03062 va_list args;
03063 va_start( args, format );
03064 char buffer[1024];
03065 vsnprintf( buffer, 1024, format, args );
03066 va_end( args );
03067
03068
03069 string formName;
03070 getFormName (formName, NULL);
03071 NLGEORGES::warning (exception, "(CFormElmAtom::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
03072 }
03073
03074
03075
03076 }