# 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.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 #include "stdgeorges.h"
00027 
00028 #include "nel/misc/i_xml.h"
00029 #include "nel/misc/common.h"
00030 #include "nel/misc/path.h"
00031 
00032 #include "form.h"
00033 #include "form_loader.h"
00034 
00035 using namespace NLMISC;
00036 
00037 namespace NLGEORGES
00038 {
00039 
00040 // ***************************************************************************
00041 // Misc
00042 // ***************************************************************************
00043 
00044 void warning (bool exception, const char *format, ... )
00045 {
00046         // Make a buffer string
00047         va_list args;
00048         va_start( args, format );
00049         char buffer[1024];
00050         sint ret = vsnprintf( buffer, 1024, format, args );
00051         va_end( args );
00052 
00053         // Set the warning
00054         if (exception)
00055         {
00056                 // Make an error message
00057                 char tmp[1024];
00058                 smprintf (tmp, 1024, "NeL::Georges %s", buffer);
00059                 throw EXmlParsingError (tmp);
00060         }
00061         else
00062                 nlwarning ("NeL::Georges %s", buffer);
00063 }
00064 
00065 // ***************************************************************************
00066 // UForm
00067 // ***************************************************************************
00068 
00069 UForm::~UForm ()
00070 {
00071 }
00072 
00073 // ***************************************************************************
00074 
00075 UFormElm& CForm::getRootNode ()
00076 {
00077         return Elements;
00078 }
00079 
00080 // ***************************************************************************
00081 
00082 const UFormElm& CForm::getRootNode () const
00083 {
00084         return Elements;
00085 }
00086 
00087 // ***************************************************************************
00088 // CForm
00089 // ***************************************************************************
00090 
00091 CForm::CForm () : Elements (this, NULL, NULL, 0xffffffff)
00092 {
00093         uint i;
00094         for (i=0; i<HeldElementCount; i++)
00095         {
00096                 HeldElements[i] = new CFormElmStruct (this, NULL, NULL, 0xffffffff);
00097         }
00098 }
00099 
00100 // ***************************************************************************
00101 
00102 CForm::~CForm ()
00103 {
00104         uint i;
00105         for (i=0; i<HeldElementCount; i++)
00106         {
00107                 delete HeldElements[i];
00108         }
00109 }
00110 
00111 // ***************************************************************************
00112 
00113 void CForm::write (xmlDocPtr doc, const char *filename, bool georges4CVS)
00114 {
00115         // Save the filename
00116         _Filename = CFile::getFilename (filename);
00117 
00118         // Create the first node
00119         xmlNodePtr node = xmlNewDocNode (doc, NULL, (const xmlChar*)"FORM", NULL);
00120         xmlDocSetRootElement (doc, node);
00121 
00122         // List of parent
00123         for (uint parent=0; parent<ParentList.size (); parent++)
00124         {
00125                 // Parent name not empty ?
00126                 if (!(ParentList[parent].ParentFilename.empty()))
00127                 {
00128                         // Add a parent node
00129                         xmlNodePtr parentNode = xmlNewChild ( node, NULL, (const xmlChar*)"PARENT", NULL );
00130                         xmlSetProp (parentNode, (const xmlChar*)"Filename", (const xmlChar*)ParentList[parent].ParentFilename.c_str());
00131                 }
00132         }
00133 
00134         // Write elements
00135         Elements.write (node, this, NULL, true);
00136 
00137         // Write held elements
00138         uint i;
00139         for (i=0; i<HeldElementCount; i++)
00140         {
00141                 HeldElements[i]->write (node, this, NULL, true);
00142         }
00143 
00144         // Header
00145         Header.write (node, georges4CVS);
00146 }
00147 
00148 // ***************************************************************************
00149 
00150 void CForm::readParent (const char *parent, CFormLoader &loader)
00151 {
00152         // Load the parent
00153         CForm *theParent = (CForm*)loader.loadForm (parent);
00154         if (theParent != NULL)
00155         {
00156                 // Set the parent
00157                 if (!insertParent (getParentCount (), parent, theParent))
00158                 {
00159                         // Make an error message
00160                         std::string parentName = parent;
00161 
00162                         // Delete the value
00163                         xmlFree ((void*)parent);
00164 
00165                         // Throw exception
00166                         warning (true, "readParent", "Can't set the parent FORM named (%s). Check if it is the same form or if it use a differnt formDfn.", parentName.c_str ());
00167                 }
00168         }
00169         else
00170         {
00171                 // Make an error message
00172                 std::string parentName = parent;
00173 
00174                 // Delete the value
00175                 xmlFree ((void*)parent);
00176 
00177                 // Throw exception
00178                 warning (true, "readParent", "Can't load the parent FORM named (%s).", parentName.c_str ());
00179         }
00180 }
00181 
00182 // ***************************************************************************
00183 
00184 void CForm::read (xmlNodePtr node, CFormLoader &loader, CFormDfn *dfn, const char *filename)
00185 {
00186         // Save the filename
00187         _Filename = CFile::getFilename (filename);
00188 
00189         // Reset form
00190         clean ();
00191 
00192         // Check node name
00193         if ( ((const char*)node->name == NULL) || (strcmp ((const char*)node->name, "FORM") != 0) )
00194         {
00195                 // Make an error message
00196                 warning (true, "read", "XML Syntax error in block line %d, node (%s) should be FORM.", 
00197                         (int)node->content, node->name);
00198         }
00199 
00200         // Get first struct node
00201         xmlNodePtr child = CIXml::getFirstChildNode (node, "STRUCT");
00202         if (child == NULL)
00203         {
00204                 // Throw exception
00205                 warning (true, "read", "Syntax error in block line %d, node (%s) should have a STRUCT child node.", 
00206                         (int)node->content, node->name);
00207         }
00208 
00209         // Read the struct
00210         Elements.read (child, loader, dfn, this);
00211 
00212         // Get next struct node
00213         child = CIXml::getNextChildNode (node, "STRUCT");
00214         uint index = 0;
00215         while ( (child != NULL) && (index < HeldElementCount))
00216         {
00217                 HeldElements[index]->read (child, loader, dfn, this);
00218                 index++;
00219         }
00220         while (index < HeldElementCount)
00221         {
00222                 // Build the Form
00223                 HeldElements[index]->build (dfn);
00224                 index++;
00225         }
00226 
00227         // Get the old parent parameter
00228         const char *parent = (const char*)xmlGetProp (node, (xmlChar*)"Parent");
00229         if (parent)
00230         {
00231                 // Add a parent, xmlFree is done by readParent
00232                 readParent (parent, loader);
00233         }
00234 
00235         // Read the new parent nodes
00236         uint parentCount = CIXml::countChildren (node, "PARENT");
00237 
00238         // Reserve some parents
00239         ParentList.reserve (ParentList.size () + parentCount);
00240 
00241         // Enum children node
00242         child = CIXml::getFirstChildNode (node, "PARENT");
00243         while (child)
00244         {
00245                 parent = (const char*)xmlGetProp (child, (xmlChar*)"Filename");
00246 
00247                 // Add a parent, xmlFree is done by readParent
00248                 readParent (parent, loader);
00249 
00250                 // Next node <PARENT>
00251                 child = CIXml::getNextChildNode (child, "PARENT");
00252         }
00253 
00254         // Read the header
00255         Header.read (node);
00256 }
00257 
00258 // ***************************************************************************
00259 
00260 const std::string &CForm::getComment () const
00261 {
00262         return Header.Comments;
00263 }
00264 
00265 // ***************************************************************************
00266 
00267 bool CForm::insertParent (uint before, const char *filename, CForm *parent)
00268 {
00269         // Set or reset ?
00270         nlassert (parent)
00271 
00272         // Must have the same DFN
00273         if (parent->Elements.FormDfn == Elements.FormDfn)
00274         {
00275                 // Set members
00276                 std::vector<CParent>::iterator ite = ParentList.insert (ParentList.begin() + before);
00277                 ite->Parent = parent;
00278                 ite->ParentFilename = filename;
00279 
00280                 return true;
00281         }
00282         else
00283         {
00284                 // Output an error
00285                 warning (false, "insertParent", "Can't insert parent form (%s) that has not the same DFN.", filename);
00286         }
00287 
00288         return false;
00289 }
00290 
00291 // ***************************************************************************
00292 
00293 void CForm::removeParent (uint parent)
00294 {
00295         ParentList.erase (ParentList.begin() + parent);
00296 }
00297 
00298 // ***************************************************************************
00299 
00300 CForm *CForm::getParent (uint parent) const
00301 {
00302         return ParentList[parent].Parent;
00303 }
00304 
00305 // ***************************************************************************
00306 
00307 const std::string &CForm::getParentFilename (uint parent) const
00308 {
00309         return ParentList[parent].ParentFilename;
00310 }
00311 
00312 // ***************************************************************************
00313 
00314 uint CForm::getParentCount () const
00315 {
00316         return ParentList.size ();
00317 }
00318 
00319 // ***************************************************************************
00320 
00321 void CForm::clean ()
00322 {
00323         clearParents ();
00324 }
00325 
00326 // ***************************************************************************
00327 
00328 void CForm::clearParents ()
00329 {
00330         ParentList.clear ();
00331 }
00332 
00333 // ***************************************************************************
00334 
00335 const std::string &CForm::getFilename () const
00336 {
00337         return _Filename;
00338 }
00339 
00340 // ***************************************************************************
00341 
00342 void CForm::warning (bool exception, const char *function, const char *format, ... ) const
00343 {
00344         // Make a buffer string
00345         va_list args;
00346         va_start( args, format );
00347         char buffer[1024];
00348         sint ret = vsnprintf( buffer, 1024, format, args );
00349         va_end( args );
00350 
00351         // Set the warning
00352         NLGEORGES::warning (exception, "(CForm::%s) in form (%s) : %s", function, _Filename.c_str (), buffer);
00353 }
00354 
00355 // ***************************************************************************
00356 
00357 } // NLGEORGES
00358