# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

form_elm.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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 // class CFormElm
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         // The parent Dfn
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         // Search for the node
00393         if (getNodeByName (name, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, verbose, round))
00394         {
00395                 // Set the result
00396                 *result = node;
00397 
00398                 // Where ?
00399                 if (where && node)
00400                 {
00401                         *where = (node->getForm () == Form) ? NodeForm : NodeParentForm;
00402                 }
00403 
00404                 // Ok 
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         // The parent Dfn
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         // Search for the node
00429         if (getNodeByName (name, &parentDfn, parentIndex, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, round))
00430         {
00431                 // End, return the current index
00432                 if (type == UFormDfn::EntryType)
00433                 {
00434                         // The atom
00435                         const CFormElmAtom *atom = node ? safe_cast<const CFormElmAtom*> (node) : NULL;
00436 
00437                         // Evale
00438                         nlassert (nodeType);
00439                         return (nodeType->getValue (result, Form, atom, *parentDfn, parentIndex, evaluate, (uint32*)where, round, name));
00440                 }
00441                 else
00442                 {
00443                         // Error message
00444                         warning (false, "getValueByName", "The node (%s) is not an atom element. Can't return a value.", name);
00445                 }
00446         }
00447         else
00448         {
00449                 // Error message
00450                 warning (false, "getValueByName", "Can't find the node (%s).", name);
00451         }
00452 
00453         // Error
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the node by name
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                 // Must be in the same form
00701                 nlassert ((*node) && ((*node)->Form == Form));
00702 
00703                 // Get its parent
00704                 CFormElm *parentNode = (*node)->ParentNode;
00705                 if (parentNode->isArray ())
00706                 {
00707                         // Cast pointer
00708                         CFormElmArray *array = safe_cast<CFormElmArray*>(parentNode);
00709 
00710                         // Valid index ?
00711                         if (arrayIndex<array->Elements.size ())
00712                         {
00713                                 // Insert the element
00714                                 array->Elements.insert (array->Elements.begin() + arrayIndex);
00715 
00716                                 // Create a new element
00717 
00718                                 // The new element
00719                                 CFormElm *newelm = NULL;
00720                                 switch (type)
00721                                 {
00722                                 case UFormDfn::EntryType:
00723                                         {
00724                                                 // Create an atom
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                                         // todo array of virtual struct
00738                                         //newelm = new CFormElmVirtualStruct (Form, array, *parentDfn, indexDfn);
00739                                         break;
00740                                 default:
00741                                         nlstop
00742                                 }
00743 
00744                                 nlassert (newelm);
00745 
00746                                 // Set the element pointer
00747                                 array->Elements[arrayIndex].Element = newelm;
00748 
00749                                 // Ok 
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         // Get the node by name
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                 // Must be in the same form
00775                 nlassert ((*node) && ((*node)->Form == Form));
00776 
00777                 // Get its parent
00778                 CFormElm *parentNode = (*node)->ParentNode;
00779                 if (parentNode->isArray ())
00780                 {
00781                         // Cast pointer
00782                         CFormElmArray *array = safe_cast<CFormElmArray*>(parentNode);
00783 
00784                         // Valid index ?
00785                         if (arrayIndex<array->Elements.size ())
00786                         {
00787                                 // Insert the element
00788                                 if (array->Elements[arrayIndex].Element)
00789                                         delete array->Elements[arrayIndex].Element;
00790 
00791                                 // Erase the entry
00792                                 array->Elements.erase (array->Elements.begin () + arrayIndex);
00793 
00794                                 // Ok 
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         // *** Init output variables
00807         created = false;
00808         parentVDfnArray = false;
00809         
00810         // ParentDfn or Node..
00811         nlassert ( (*parentDfn) || (*node) );
00812 
00813         // Error message
00814         char error[512];
00815 
00816         // Parent exist ?
00817         if (*parentDfn)
00818         {
00819                 // Get the entry
00820                 const CFormDfn::CEntry &theEntry = (*parentDfn)->getEntry (indexDfn);
00821 
00822                 // Get the type
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         // Check node pointer
00847         if (action == Create)
00848         {
00849                 nlassert (*node);
00850                 nlassert ((*node)->getForm () == form);
00851         }
00852 
00853         // Backup current node
00854         CFormElm *backupFirstElm = *node;
00855 
00856         // *** Parsing variables
00857 
00858         // Current token start and end
00859         const char *startToken = name;
00860         const char *endToken;
00861 
00862         // Current token start
00863         string token;
00864 
00865         // Current form name
00866         string currentName;
00867         if (*node)
00868                 (*node)->getFormName (currentName);
00869 
00870         // Error
00871         uint errorIndex;
00872 
00873         // Token code
00874         uint code;
00875 
00876         // Are we parsing an array ?
00877         bool inArrayIndex = false;
00878 
00879         // Index in the array
00880         uint arrayIndex;
00881 
00882         // Bool next token must be an array index
00883         bool wantArrayIndex = false;
00884 
00885         // Last struct elm
00886         CFormElmStruct *lastStructElm = ((*node)->ParentNode && (*node)->ParentNode->isStruct ()) ? safe_cast<CFormElmStruct*> ((*node)->ParentNode) : NULL;
00887         uint lastStructIndex = 0;
00888         if (lastStructElm)
00889         {
00890                 // Look for node in the parent
00891                 for (; lastStructIndex<lastStructElm->Elements.size (); lastStructIndex++)
00892                 {
00893                         // The same node ?
00894                         if (lastStructElm->Elements[lastStructIndex].Element == (*node))
00895                                 break;
00896                 }
00897 
00898                 // Must have been found
00899                 nlassert (lastStructIndex<lastStructElm->Elements.size ());
00900         }
00901 
00902         // While there is tokens
00903         while (endToken = tokenize (startToken, token, errorIndex, code))
00904         {
00905                 // Ready an array index ?
00906                 if (!inArrayIndex)
00907                 {
00908                         // For each code
00909                         switch (code)
00910                         {
00911                         case TokenString:
00912                                 {
00913                                         // Need an array index array ?
00914                                         if (wantArrayIndex)
00915                                         {
00916                                                 // Error message
00917                                                 smprintf (error, 512, "Token (%s) should be an array index.", token.c_str());
00918                                                 goto exit;
00919                                         }
00920 
00921                                         // Are we a struct ?
00922                                         if ( ((type == UFormDfn::EntryDfn) || (type == UFormDfn::EntryVirtualDfn)) /*&& (!array)*/ )
00923                                         {
00924                                                 // Check the virtual DFN is not empty..
00925                                                 if ( (type == UFormDfn::EntryVirtualDfn) && (*nodeDfn == NULL) )
00926                                                 {
00927                                                         // Is it a parent virtual DFN ?
00928                                                         if ( (type == UFormDfn::EntryVirtualDfn) && (*node == NULL) )
00929                                                                 parentVDfnArray = true;
00930 
00931                                                         // Create mode ?
00932                                                         if (action == Create)
00933                                                         {
00934                                                                 // Should have a valid node
00935                                                                 nlassert (*node && lastStructElm);
00936 
00937                                                                 // Get the current virtual dfn
00938                                                                 CFormElmVirtualStruct *vStruct = safe_cast<CFormElmVirtualStruct*> (*node);
00939 
00940                                                                 // Get the form name of the current node
00941                                                                 string formName;
00942                                                                 vStruct->getFormName (formName, NULL);
00943 
00944                                                                 // Get the parent node if available
00945                                                                 for (uint parent=0; parent<form->getParentCount (); parent++)
00946                                                                 {
00947                                                                         // Get the parent
00948                                                                         CForm *parentPtr = form->getParent (parent);
00949                                                                         nlassert (parentPtr);
00950 
00951                                                                         // Get the virtual node by name
00952                                                                         UFormElm *uelm;
00953                                                                         if (parentPtr->getRootNode ().getNodeByName (&uelm, formName.c_str (), NULL, verbose, round) && uelm)
00954                                                                         {
00955                                                                                 // Value node ?
00956                                                                                 if (uelm->isVirtualStruct ())
00957                                                                                 {
00958                                                                                         // Get a virtual struct pointer
00959                                                                                         CFormElmVirtualStruct *vStructParent = safe_cast<CFormElmVirtualStruct*> (uelm);
00960 
00961                                                                                         // Copy the DFN filename
00962                                                                                         vStruct->DfnFilename = vStructParent->DfnFilename;
00963 
00964                                                                                         // Build it
00965                                                                                         vStruct->build (vStructParent->FormDfn);
00966 
00967                                                                                         // Set the current DFN
00968                                                                                         *nodeDfn = vStruct->FormDfn;
00969 
00970                                                                                         // Stop looking for parent
00971                                                                                         break;
00972                                                                                 }
00973                                                                                 else
00974                                                                                 {
00975                                                                                         // Error message
00976                                                                                         smprintf (error, 512, "Internal node parsing error.");
00977                                                                                         goto exit;
00978                                                                                 }
00979                                                                         }
00980                                                                 }
00981                                                         }
00982 
00983                                                         // Still no DFN ?
00984                                                         if (*nodeDfn == NULL)
00985                                                         {
00986                                                                 // Error message
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                                                 // Must hjave a nodeDfn here
00993                                                 nlassert (*nodeDfn);
00994 
00995                                                 // Look for the element
00996                                                 uint elementCount = (*nodeDfn)->getNumEntry ();
00997 
00998                                                 // Get the parents
00999                                                 vector<const CFormDfn*> arrayDfn;
01000                                                 arrayDfn.reserve ((*nodeDfn)->countParentDfn ());
01001                                                 (*nodeDfn)->getParentDfn (arrayDfn);
01002 
01003                                                 // For each parent
01004                                                 uint i;
01005                                                 uint formElm = 0;
01006                                                 for (i=0; i<arrayDfn.size(); i++)
01007                                                 {
01008                                                         // The dfn
01009                                                         const CFormDfn &dfn = *(arrayDfn[i]);
01010 
01011                                                         // For each elements
01012                                                         uint element;
01013                                                         for (element=0; element<dfn.Entries.size(); element++)
01014                                                         {
01015                                                                 // Good name ?
01016                                                                 if (dfn.Entries[element].Name == token)
01017                                                                 {
01018                                                                         // Good one.
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                                                                         // Next node
01028                                                                         if (*node)
01029                                                                         {
01030                                                                                 // Get next node
01031                                                                                 CFormElmStruct *nodeStruct = safe_cast<CFormElmStruct*> (*node);
01032                                                                                 CFormElm *nextElt = nodeStruct->Elements[formElm].Element;
01033                                                                                 
01034                                                                                 // If no next node, watch for parent node
01035                                                                                 *node = nextElt;
01036 
01037                                                                                 // Create node
01038                                                                                 if ( (action == Create) && (*node == NULL) )
01039                                                                                 {
01040                                                                                         // Is an array ?
01041                                                                                         if (array)
01042                                                                                         {
01043                                                                                                 // Create an atom
01044                                                                                                 CFormElmArray *atom = new CFormElmArray (form, *nodeDfn, *nodeType, nodeStruct, *parentDfn, indexDfn);
01045                                                                                                 *node = atom;
01046                                                                                         }
01047                                                                                         else
01048                                                                                         {
01049                                                                                                 // What kind of node ?
01050                                                                                                 switch (type)
01051                                                                                                 {
01052                                                                                                 case UFormDfn::EntryType:
01053                                                                                                         {
01054                                                                                                                 // Create an atom
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                                                                                         // Node created
01075                                                                                         created = true;
01076 
01077                                                                                         // Set the node in parent
01078                                                                                         nodeStruct->Elements[formElm].Element = *node;
01079                                                                                 }
01080 
01081                                                                                 // Is a virtual DFN ?
01082                                                                                 if ((*node) && (*node)->isVirtualStruct ())
01083                                                                                 {
01084                                                                                         // Should be NULL
01085                                                                                         nlassert (*nodeDfn == NULL);
01086 
01087                                                                                         // Set the current dfn
01088                                                                                         *nodeDfn = safe_cast<const CFormElmVirtualStruct*> (*node)->FormDfn;
01089                                                                                 }
01090 
01091                                                                                 // Save last struct
01092                                                                                 lastStructElm = nodeStruct;
01093                                                                                 lastStructIndex = formElm;
01094                                                                         }
01095                                                                         else
01096                                                                         {
01097                                                                                 // Save last struct
01098                                                                                 CFormElmStruct *lastStructElm = NULL;
01099                                                                                 uint lastStructIndex = 0xffffffff;
01100 
01101                                                                                 *node = NULL;
01102                                                                         }
01103 
01104                                                                         break;
01105                                                                 }
01106                                                                 formElm++;
01107                                                         }
01108 
01109                                                         // Breaked ?
01110                                                         if (element!=dfn.Entries.size())
01111                                                                 break;
01112                                                 }
01113 
01114                                                 // Breaked ?
01115                                                 if (i==arrayDfn.size())
01116                                                 {
01117                                                         // Not found
01118                                                         smprintf (error, 512, "Struct does not contain element named (%s).", token.c_str());
01119                                                         goto exit;
01120                                                 }
01121                                         }
01122                                         else
01123                                         {
01124                                                 // Error message
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                                         // Need an array index array ?
01133                                         if (wantArrayIndex)
01134                                         {
01135                                                 // Error message
01136                                                 smprintf (error, 512, "Token (%s) should be an array index.", token.c_str());
01137                                                 goto exit;
01138                                         }
01139 
01140                                         // Are we a struct ?
01141                                         if ((type != UFormDfn::EntryDfn) && (type != UFormDfn::EntryVirtualDfn))
01142                                         {
01143                                                 // Error message
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                                         // Are we an array ?
01152                                         if (!array)
01153                                         {
01154                                                 // Error message
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                                         // Error message
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                                         // To int
01178                                         if (sscanf (token.c_str(), "%d", &arrayIndex)!=1)
01179                                         {
01180                                                 // Error message
01181                                                 smprintf (error, 512, "Keyword (%s) is not an array index.", token.c_str());
01182                                                 goto exit;
01183                                         }
01184 
01185                                         // Is it a parent virtual DFN ?
01186                                         if (*node == NULL)
01187                                                 parentVDfnArray = true;
01188 
01189                                         // Should have an array defined
01190                                         if (*node)
01191                                         {
01192                                                 // Check index
01193                                                 uint arraySize;
01194                                                 nlverify ((*node)->getArraySize (arraySize));
01195                                                 if (arrayIndex>=arraySize)
01196                                                 {
01197                                                         // Create mode ?
01198                                                         if (action == Create)
01199                                                         {
01200                                                                 // Must be in the same form
01201                                                                 nlassert ((*node)->Form == form);
01202 
01203                                                                 // The array pointer
01204                                                                 CFormElmArray *array = safe_cast<CFormElmArray*>(*node);
01205                                                                 uint oldSize = array->Elements.size ();
01206                                                                 array->Elements.resize (arrayIndex+1);
01207 
01208                                                                 // Insert empty element
01209                                                                 uint i;
01210                                                                 for (i=oldSize; i<array->Elements.size (); i++)
01211                                                                 {
01212                                                                         // The new element
01213                                                                         CFormElm *newelm = NULL;
01214                                                                         switch (type)
01215                                                                         {
01216                                                                         case UFormDfn::EntryType:
01217                                                                                 {
01218                                                                                         // Create an atom
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                                                                                 // todo array of virtual struct
01232                                                                                 //newelm = new CFormElmVirtualStruct (form, array, *parentDfn, indexDfn);
01233                                                                                 break;
01234                                                                         default:
01235                                                                                 nlstop
01236                                                                         }
01237 
01238                                                                         nlassert (newelm);
01239 
01240                                                                         // Node created
01241                                                                         created = true;
01242 
01243                                                                         // Set the element pointer
01244                                                                         array->Elements[i].Element = newelm;
01245                                                                 }
01246                                                         }
01247                                                         else
01248                                                         {
01249                                                                 // Error message
01250                                                                 smprintf (error, 512, "Out of array bounds (%d >= %d).", arrayIndex, arraySize);
01251                                                                 goto exit;
01252                                                         }
01253                                                 }
01254                                         }
01255                                         else
01256                                         {
01257                                                 // Error message
01258                                                 smprintf (error, 512, "Array is not defined.");
01259                                                 goto exit;
01260                                         }
01261                                 }
01262                                 break;
01263                         case TokenArrayEnd:
01264                                 {
01265                                         // No need of an array index any more
01266                                         wantArrayIndex = false;
01267 
01268                                         // Index found ?
01269                                         if (arrayIndex == 0xffffffff)
01270                                         {
01271                                                 // Error message
01272                                                 smprintf (error, 512, "Missing array index.");
01273                                         }
01274                                         else
01275                                         {
01276                                                 // Let the parent DFN
01277                                                 nlassert (*parentDfn)
01278 
01279                                                 // New current node
01280                                                 CFormElmArray *parentNode = safe_cast<CFormElmArray*> (*node);
01281 
01282                                                 // Get the element
01283                                                 *node = parentNode->Elements[arrayIndex].Element;
01284 
01285                                                 // Is a dfn ?
01286                                                 *nodeDfn = (*parentDfn)->getEntry (indexDfn).getDfnPtr ();
01287 
01288                                                 // Is a type ?
01289                                                 *nodeType = (*parentDfn)->getEntry (indexDfn).getTypePtr ();
01290 
01291                                                 // Type ?
01292                                                 type = (*parentDfn)->getEntry (indexDfn).getType ();
01293                                                 
01294                                                 // Can't be an array of array
01295                                                 array = false;
01296 
01297                                                 // Not any more in index
01298                                                 inArrayIndex = false;
01299 
01300                                                 // What kind of node ?
01301                                                 if ( (action == Create) && ( *node == NULL) )
01302                                                 {
01303                                                         switch (type)
01304                                                         {
01305                                                         case UFormDfn::EntryType:
01306                                                                 {
01307                                                                         // Create an atom
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                                                                 // todo array of virtual struct
01321                                                                 // *node = new CFormElmVirtualStruct (form, parentNode, *parentDfn, indexDfn);
01322                                                                 break;
01323                                                         default:
01324                                                                 nlstop
01325                                                         }
01326 
01327                                                         nlassert (*node);
01328 
01329                                                         // Node created
01330                                                         created = true;
01331 
01332                                                         // Set the element pointer
01333                                                         parentNode->Elements[arrayIndex].Element = *node;
01334                                                 }
01335 
01336                                                 // Is a virtual DFN ?
01337                                                 if ((*node) && (*node)->isVirtualStruct ())
01338                                                 {
01339                                                         // Should be NULL
01340                                                         nlassert (*nodeDfn == NULL);
01341 
01342                                                         // Set the current dfn
01343                                                         *nodeDfn = safe_cast<const CFormElmVirtualStruct*> (*node)->FormDfn;
01344                                                 }
01345                                         }
01346                                 }
01347                                 break;
01348                         default:
01349                                 {
01350                                         // Error message
01351                                         smprintf (error, 512, "Keyword (%s) is not an array index.", token.c_str());
01352                                         goto exit;
01353                                 }
01354                         }
01355                 }
01356 
01357                 // Concat current adress
01358                 currentName += token;
01359                 startToken = endToken;
01360         }
01361 exit:;
01362 
01363         // Error ?
01364         bool errorAppend = endToken != NULL;
01365 
01366         // Continue ?
01367         if (!errorAppend)
01368         {
01369                 // Delete the node ?
01370                 if ( (action == Delete) && (*node) )
01371                 {
01372                         // Get its parent
01373                         CFormElm *parent = safe_cast<CFormElm*> ((*node)->getParent ());
01374 
01375                         // Don't erase the root structure
01376                         if (parent && !parent->isArray ())
01377                         {
01378                                 // Unlink the primitive from its parent
01379                                 parent->unlink (*node);
01380 
01381                                 // Erase the node
01382                                 delete (*node);
01383                                 *node = parent;
01384                                 parent = (CFormElm*) (parent->getParent ());
01385 
01386                                 // For each parent
01387                                 while (parent && !(*node)->isUsed (form) && !parent->isArray ())
01388                                 {
01389                                         // Unlink the primitive from its parent
01390                                         parent->unlink (*node);
01391 
01392                                         // Erase it and get next parent
01393                                         delete (*node);
01394                                         *node = parent;
01395                                         parent = (CFormElm*) (parent->getParent ());
01396                                 }
01397 
01398                                 // No more node
01399                                 *node = NULL;
01400                         }
01401                 }
01402         }
01403 
01404         // Node not found in get node ? Look in parents !
01405         if ( ((*node) == NULL) && (action == Return) && backupFirstElm )
01406         {
01407                 // Get the path name
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                 // Backup first parent default value
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                 // Look in parent form
01428                 for (uint parent=0; parent<form->getParentCount (); parent++)
01429                 {
01430                         // Get the parent
01431                         CForm *parentPtr = form->getParent (parent);
01432                         nlassert (parentPtr);
01433 
01434                         // Get the node by name in the parent
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                                 // Node found ?
01447                                 if (nodeParent)
01448                                 {
01449                                         // Found copy return values
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                                         // Backup the first parent default value found
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                 // Default value available ?
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         // Recurce warning !
01497         if (*node)
01498         {
01499                 if ((*node)->Round == round)
01500                 {
01501                         // Turn around..
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                 // Get the best form name
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                 // Add a char
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         // No children
01569         nlstop;
01570 }
01571 
01572 // ***************************************************************************
01573 
01574 bool CFormElm::setValueByName (const char *value, const char *name, bool *created)
01575 {
01576         // The parent Dfn
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         // Search for the node
01587         if (createNodeByName (name, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, _created))
01588         {
01589                 // Is this a type ?
01590                 if (type == UFormDfn::EntryType)
01591                 {
01592                         // The atom
01593                         CFormElmAtom *atom = node ? safe_cast<CFormElmAtom*> (node) : NULL;
01594 
01595                         // Evale
01596                         nlassert (nodeType);
01597                         atom->setValue (value);
01598 
01599                         // Created flag
01600                         if (created)
01601                                 *created = _created;
01602                         return true;
01603                 }
01604                 else
01605                 {
01606                         // Error message
01607                         warning (false, "setValueByName", "The node (%s) is not an atom element. Can't set the value.", name);
01608                 }
01609         }
01610         else
01611         {
01612                 // Error message
01613                 warning (false, "setValueByName", "Can't created / set the node (%s).", name);
01614 
01615                 // Created flag
01616                 if (created)
01617                         *created = false;
01618         }
01619 
01620         // Error
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         // Make a buffer string
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         // Set the warning
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 // class CFormElmStruct
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         // For each element of the array
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         // Is used ?
01823         if (isUsed (form) || forceWrite)
01824         {
01825                 // *** Header
01826                 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"STRUCT", NULL);
01827 
01828                 // Element name
01829                 if (structName != NULL)
01830                 {
01831                         // Struct name
01832                         xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
01833                 }
01834 
01835                 // For each elements of the structure
01836                 uint elm;
01837                 for (elm=0; elm<Elements.size(); elm++)
01838                 {
01839                         // Create a node if it exist
01840                         if (Elements[elm].Element)
01841                                 Elements[elm].Element->write (node, form, Elements[elm].Name.c_str());
01842                 }
01843 
01844                 // Return the new node
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         // Get the smart pointer on the dfn
01855         FormDfn = (CFormDfn*)dfn;
01856 
01857         // Build the Form
01858         build (dfn);
01859 
01860         // Count parent
01861         uint dfnCount = dfn->countParentDfn ();
01862 
01863         // Array of Dfn
01864         std::vector<const CFormDfn*> dfnArray;
01865         dfnArray.reserve (dfnCount);
01866         dfn->getParentDfn (dfnArray);
01867 
01868         // For each Dfn
01869         uint dfnId;
01870         uint elmIndex=0;
01871         for (dfnId=0; dfnId<dfnCount; dfnId++)
01872         {
01873                 // Lookup for the name in the DFN
01874                 uint elm;
01875                 for (elm=0; elm<dfnArray[dfnId]->Entries.size(); elm++)
01876                 {
01877                         // Found ?
01878                         bool found = false;
01879 
01880                         // Read the struct
01881                         xmlNodePtr child = NULL;
01882 
01883                         // Node can be NULL
01884                         if (node)
01885                                 child = node->children;
01886 
01887                         while (child)
01888                         {
01889                                 // Good node ?
01890                                 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
01891                                 if (name && (dfnArray[dfnId]->Entries[elm].getName () == name) )
01892                                 {
01893                                         // Type
01894                                         bool atom=false;
01895                                         bool array=false;
01896                                         bool _struct=false;
01897                                         bool vStruct=false;
01898 
01899                                         // Is an atom ?
01900                                         if (strcmp ((const char*)child->name, "ATOM") == 0)
01901                                         {
01902                                                 atom = true;
01903                                         }
01904                                         // Is a struct ?
01905                                         else if (strcmp ((const char*)child->name, "STRUCT") == 0)
01906                                         {
01907                                                 _struct = true;
01908                                         }
01909                                         // Is a struct ?
01910                                         else if (strcmp ((const char*)child->name, "VSTRUCT") == 0)
01911                                         {
01912                                                 vStruct = true;
01913                                         }
01914                                         // Is an array ?
01915                                         else if (strcmp ((const char*)child->name, "ARRAY") == 0)
01916                                         {
01917                                                 array = true;
01918                                         }
01919 
01920                                         // Continue ?
01921                                         if (atom || _struct || vStruct || array)
01922                                         {
01923                                                 // Same type ?
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                                                         // Ok keep it
01932                                                         break;
01933                                                 }
01934                                                 else
01935                                                 {
01936                                                         // Make a warning message
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                                                         // Delete the value
01946                                                         xmlFree ((void*)name);
01947                                                 }
01948 
01949                                                 // Throw exception
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                                         // Delete the value
01958                                         xmlFree ((void*)name);
01959                                 }
01960 
01961                                 // Next child
01962                                 child = child->next;
01963                         }
01964 
01965                         // Found ?
01966                         if (child)
01967                         {
01968                                 // Create a new element
01969                                 if (dfnArray[dfnId]->Entries[elm].getArrayFlag ())
01970                                 {
01971                                         // Array of type
01972                                         CFormElmArray *newElm = NULL;
01973                                         if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryType)
01974                                         {
01975                                                 // Load the new element
01976                                                 newElm = new CFormElmArray (form, NULL, dfnArray[dfnId]->Entries[elm].getTypePtr (), this, dfnArray[dfnId], elm);
01977                                         }
01978                                         // Array of struct
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                                         // Should be created
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                                         // Load the new element
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                                         // Load the new element
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 // if dfnArray[dfnId]->Entries[elm].getType () == CFormDfn::CEntry::EntryVirtualDfn)
02004                                 {
02005                                         // Should be a struct
02006                                         nlassert (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryVirtualDfn);
02007 
02008                                         // Load the new element
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         // Clean the form
02039         clean ();
02040 
02041         // Set the DFN
02042         FormDfn = (CFormDfn*)dfn;
02043         
02044         // Get the parents
02045         vector<const CFormDfn*> arrayDfn;
02046         arrayDfn.reserve (dfn->countParentDfn ());
02047         dfn->getParentDfn (arrayDfn);
02048 
02049         // Count element
02050         uint elementCount = 0;
02051         uint dfnIndex;
02052         for (dfnIndex=0; dfnIndex<arrayDfn.size(); dfnIndex++)
02053         {
02054                 elementCount += arrayDfn[dfnIndex]->getNumEntry();
02055         }
02056 
02057         // Resize the element array
02058         Elements.resize (elementCount);
02059 
02060         elementCount = 0;
02061         for (dfnIndex=0; dfnIndex<arrayDfn.size(); dfnIndex++)
02062         {
02063                 // For each element
02064                 for (uint elm=0; elm<arrayDfn[dfnIndex]->Entries.size(); elm++)
02065                 {
02066                         // Copy the name
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         // Element not found!
02088         nlassert (i != Elements.size ());
02089 }
02090 
02091 // ***************************************************************************
02092 
02093 void CFormElmStruct::getFormName (std::string &result, const CFormElm *child) const
02094 {
02095         // Reset the result
02096         if (child == NULL)
02097         {
02098                 result = "";
02099                 result.reserve (50);
02100         }
02101 
02102         // Get parent form name
02103         if (ParentNode)
02104                 ParentNode->getFormName (result, this);
02105 
02106         // Get node name
02107         if (child)
02108         {
02109                 // Look for the child
02110                 uint i;
02111                 for (i=0; i<Elements.size (); i++)
02112                 {
02113                         // This one ?
02114                         if (Elements[i].Element == child)
02115                         {
02116                                 // Add the field name
02117                                 result += ".";
02118                                 result += Elements[i].Name;
02119                                 break;
02120                         }
02121                 }
02122 
02123                 // Draw some warning
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         // Make a buffer string
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         // Set the warning
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 // class CFormElmVirtualStruct
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         // Is used ?
02161         if (isUsed (form) || forceWrite)
02162         {
02163                 // *** Header
02164                 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"VSTRUCT", NULL);
02165 
02166                 // Write the DFN filename in the node
02167                 xmlSetProp (node, (const xmlChar*)"DfnName", (const xmlChar*)DfnFilename.c_str());
02168 
02169                 // Element name
02170                 if (structName != NULL)
02171                 {
02172                         // Struct name
02173                         xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02174                 }
02175 
02176                 // For each elements of the structure
02177                 uint elm;
02178                 for (elm=0; elm<Elements.size(); elm++)
02179                 {
02180                         // Create a node if it exist
02181                         if (Elements[elm].Element)
02182                                 Elements[elm].Element->write (node, form, Elements[elm].Name.c_str());
02183                 }
02184 
02185                 // Return the new node
02186                 return node;
02187         }
02188         return NULL;
02189 }
02190 
02191 // ***************************************************************************
02192 
02193 void CFormElmVirtualStruct::read (xmlNodePtr node, CFormLoader &loader, CForm *form)
02194 {
02195         // Get the DFN filename
02196         const char *filename = (const char*)xmlGetProp (node, (xmlChar*)"DfnName");
02197         if (filename)
02198         {
02199                 // Set the name
02200                 DfnFilename = filename;
02201 
02202                 // Delete the value
02203                 xmlFree ((void*)filename);
02204 
02205                 // Load the dfn
02206                 FormDfn = loader.loadFormDfn (DfnFilename.c_str (), false);
02207                 if (!FormDfn)
02208                 {
02209                         // Throw exception
02210                         warning (true, "read", "Can't find DFN filename (%s).", DfnFilename.c_str ());
02211                 }
02212         }
02213         else
02214         {
02215                 // Throw exception
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         // Read the parent
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         // Make a buffer string
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         // Set the warning
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 // class CFormElmArray
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         // For each element of the array
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         // Arrau is used ?
02582         if (isUsed (form) || forceWrite)
02583         {
02584                 // *** Header
02585                 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"ARRAY", NULL);
02586 
02587                 // Element name
02588                 if (structName != NULL)
02589                 {
02590                         // Struct name
02591                         xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02592                 }
02593 
02594                 // For each elements of the structure
02595                 uint elm;
02596                 for (elm=0; elm<Elements.size(); elm++)
02597                 {
02598                         // Create a node
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                 // Return the new node
02604                 return node;
02605         }
02606 
02607         return NULL;
02608 }
02609 
02610 // ***************************************************************************
02611 
02612 void CFormElmArray::read (xmlNodePtr node, CFormLoader &loader, CForm *form)
02613 {
02614         // Clean the form
02615         clean ();
02616 
02617         // Count child
02618         if (node)
02619         {
02620                 // Type of DFN array
02621                 if (Type)
02622                 {
02623                         nlassert (FormDfn == NULL);
02624 
02625                         // Count children
02626                         uint childCount = CIXml::countChildren (node, "ATOM");
02627 
02628                         // Resize the table
02629                         Elements.resize (childCount);
02630 
02631                         // For each children
02632                         uint childNum=0;
02633                         xmlNodePtr child = CIXml::getFirstChildNode (node, "ATOM");
02634                         while (child)
02635                         {
02636                                 // Get node name
02637                                 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
02638 
02639                                 // Create a new node
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                                 // Next child
02650                                 child = CIXml::getNextChildNode (child, "ATOM");
02651                                 childNum++;
02652                         }
02653                 }
02654                 else
02655                 {
02656                         nlassert (FormDfn);
02657                         nlassert (Type == NULL);
02658 
02659                         // Count children
02660                         uint childCount = CIXml::countChildren (node, "STRUCT");
02661 
02662                         // Resize the table
02663                         Elements.resize (childCount);
02664 
02665                         // For each children
02666                         uint childNum=0;
02667                         xmlNodePtr child = CIXml::getFirstChildNode (node, "STRUCT");
02668                         while (child)
02669                         {
02670                                 // Get node name
02671                                 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
02672 
02673                                 // Create a new node
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                                 // Next child
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         // Element not found!
02713         nlassert (i != Elements.size ());
02714 }
02715 
02716 // ***************************************************************************
02717 
02718 bool CFormElmArray::isUsed (const CForm *form) const
02719 {       
02720         /*for (uint i=0; i<Elements.size(); i++)
02721         {
02722                 if (Elements[i] && Elements[i]->isUsed (form))
02723                         return true;
02724         }*/
02725         return form == Form;
02726 }
02727 
02728 // ***************************************************************************
02729 
02730 void CFormElmArray::getFormName (std::string &result, const CFormElm *child) const
02731 {
02732         // Reset the result
02733         if (child == NULL)
02734         {
02735                 result = "";
02736                 result.reserve (50);
02737         }
02738 
02739         // Get parent form name
02740         if (ParentNode)
02741                 ParentNode->getFormName (result, this);
02742 
02743         // Get node name
02744         if (child)
02745         {
02746                 // Look for the child
02747                 uint i;
02748                 for (i=0; i<Elements.size (); i++)
02749                 {
02750                         // This one ?
02751                         if (Elements[i].Element == child)
02752                         {
02753                                 char name[512];
02754                                 smprintf (name, 512, "[%d]", i);
02755 
02756                                 // Add the field name
02757                                 result += name;
02758                                 break;
02759                         }
02760                 }
02761 
02762                 // Draw some warning
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         // Make a buffer string
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         // Set the warning
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 // CFormElmAtom
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         // Evale
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Get the string value
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         // Atom is used ?
02958         if (isUsed (form) || forceWrite)
02959         {
02960                 // *** Header
02961                 xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"ATOM", NULL);
02962 
02963                 // Element name
02964                 if (structName != NULL)
02965                 {
02966                         // Struct name
02967                         xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02968                 }
02969 
02970                 // The value
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                 // Return the new node
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         // Set the type
02993         Type = type;
02994 
02995         // Set the value ?
02996         if (node)
02997         {
02998                 // Get the value
02999                 const char *value = (const char*)xmlGetProp (node, (xmlChar*)"Value");
03000                 if (value)
03001                 {
03002                         // Active value
03003                         setValue (value);
03004 
03005                         // Delete the value
03006                         xmlFree ((void*)value);
03007                 }
03008                 else
03009                 {
03010                         // Get content
03011                         const char *valueText = (const char*)xmlNodeGetContent (node);
03012                         if (valueText)
03013                         {
03014                                 setValue (valueText);
03015 
03016                                 // Delete the value
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         // Must be NULL
03035         nlassert (child == NULL);
03036         result = "";
03037         result.reserve (50);
03038 
03039         // Get parent form name
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         // Make a buffer string
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         // Set the warning
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 } // NLGEORGES