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