]> SALOME platform Git repositories - modules/hexablock.git/blob - src/HEXABLOCK/HexXmlTree.cxx
Salome HOME
99995dd2eea1d4cea7d233cabc6c4f721dd64a29
[modules/hexablock.git] / src / HEXABLOCK / HexXmlTree.cxx
1
2 // C++ : ParserXml
3
4 // Copyright (C) 2009-2012  CEA/DEN, EDF R&D
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HexXmlTree.hxx"
24
25 BEGIN_NAMESPACE_HEXA
26
27 enum { HEND_FILE = -2, HEND_LINE = -1, CRLF = 13 };
28
29 // ====================================================== Constructeur 
30 XmlTree::XmlTree (const string& nom, XmlTree* dad)
31 {
32    item_name     = nom;
33    item_vide     = "";
34    xml_parent    = dad;
35    nbr_attributs = 0;
36    nbr_items     = 0;
37
38    fic_buffer  = "";
39    len_buffer  = 0;
40    xml_file    = NULL;
41    nro_ligne   = 0;
42    fic_pos     = 1988;
43
44    xml_flow  = NULL;
45    pos_flow  = 0;
46    xml_ended = true;
47 }
48 // ====================================================== Destructeur
49 XmlTree::~XmlTree ()
50 {
51 }
52 // ====================================================== findChild
53 XmlTree* XmlTree::findChild (const string& nom)
54 {
55    for (int nro = 0 ; nro<nbr_items ; nro++)
56        {
57        if (nom == tab_items [nro]->item_name)
58            return tab_items [nro];
59        }
60    return NULL;
61 }
62 // ====================================================== findAttribute
63 int XmlTree::findAttribute (const string& nom)
64 {
65    for (int nro = 0 ; nro<nbr_attributs ; nro++)
66        {
67        if (nom == tab_attributs [nro])
68           return nro;
69        }
70    return NOTHING;
71 }
72 // ====================================================== findValue
73 const string& XmlTree::findValue (const string& nom)
74 {
75    for (int nro = 0 ; nro<nbr_attributs ; nro++)
76        {
77        if (nom == tab_attributs [nro])
78           return  tab_values    [nro];
79        }
80    return item_vide;
81 }
82 // ====================================================== parseFile
83 int XmlTree::parseFile (const string& ficnom)
84 {
85    fic_buffer  = "";
86    len_buffer  = 0;
87    nro_ligne   = 0;
88    fic_pos     = 1988;
89    xml_flow    = NULL;
90    pos_flow    = 0;
91    xml_ended   = true;
92
93    xml_file = fopen (ficnom.c_str(), "r");
94    if (xml_file==NULL)
95       {
96       cout << " **** Fichier XML '" << ficnom << "' inaccessible" 
97            << endl;
98       return HERR;
99       }
100
101    int ier = parseXml ();
102    return ier;
103 }
104 // ====================================================== parseFlow
105 int XmlTree::parseFlow (cpchar flux)
106 {
107    fic_buffer  = "";
108    len_buffer  = 0;
109    nro_ligne   = 0;
110    fic_pos     = 1988;
111
112    xml_flow    = flux;
113    pos_flow    = 0;
114
115    int ier = parseXml ();
116    return ier;
117 }
118 // ====================================================== parseXml
119 int XmlTree::parseXml ()
120 {
121    xml_ended  = false;
122
123    enum EnumEtat { M_PREMS, M_BALISE_OUVERTE, M_NEUTRE };
124    EnumEtat etat =  M_PREMS;
125
126    XmlTree* node = this;
127    EnumItem item_lu;
128    string   nom, valeur, foo;
129    while ((item_lu=readItem (nom)) != M_NONE)
130       {
131       switch (item_lu) 
132          {
133          case M_BEGIN :
134               item_lu = getItem (nom, M_IDENT);
135               if (etat==M_PREMS) 
136                  setName (nom);
137               else
138                  node = node -> addChild  (nom);
139               etat = M_BALISE_OUVERTE;
140               break;
141
142          case M_END   :
143               if (etat != M_BALISE_OUVERTE) 
144                  putError (" balise ouverte");
145               etat = M_NEUTRE;
146               break;
147
148          case M_BEGIN_CLOSE :
149               if (etat == M_BALISE_OUVERTE) 
150                  putError (" balise ouverte");
151               getItem (nom, M_IDENT);
152               getItem (foo, M_END);
153               node = node -> getParent ();
154               break;
155
156          case M_CLOSE :
157               if (etat != M_BALISE_OUVERTE) 
158                  putError (" balise deja fermee");
159               node = node -> getParent ();
160               etat = M_NEUTRE;
161               break;
162
163          case M_IDENT :
164               getItem (valeur, M_EQUALS);
165               getItem (valeur, M_STRING);
166               node -> addAttribut (nom, valeur);
167               break;
168
169          case M_COMMENT : goTo ("-->");
170               break;
171
172          case M_PROLOG  : goTo ("?>");
173               break;
174
175          default :
176          case M_EQUALS :
177          case M_STRING :
178          case M_END_COMMENT :
179          case M_END_PROLOG :
180               putError ("Item incorrect");
181          }
182       }
183    return HOK;
184 }
185 // ====================================================== getItem
186 EnumItem XmlTree::getItem (string& value, EnumItem waited)
187 {
188    EnumItem item = readItem (value);
189
190    if (item == waited) 
191       return item;
192    putError ("Erreur de sequence");
193    return item;
194 }
195 // ====================================================== readItem
196 EnumItem XmlTree::readItem (string& value)
197 {
198    value  = "";
199
200    while (true)
201          {
202          if (fic_pos>=len_buffer)
203             {
204             int ier=readLine ();
205             if (ier==HEND_FILE) 
206                return M_NONE;
207             }
208          else
209             {
210             char  car = fic_buffer [fic_pos++];
211
212             if (car=='=')
213                return M_EQUALS;
214             else if (car=='>')
215                return M_END;
216             else if (car=='"')
217                {
218                getString (value);
219                return M_STRING;
220                }
221             else if (isalpha (car))
222                {
223                getIdent (value);
224                return M_IDENT;
225                }
226
227             char ncar = fic_pos >= len_buffer ? ' ' : fic_buffer [fic_pos];
228             if (car=='/' && ncar == '>')
229                {
230                fic_pos++;
231                return M_CLOSE;
232                }
233             else if (car=='<')
234                {
235                if (ncar=='/') 
236                   {
237                   fic_pos++;
238                   return M_BEGIN_CLOSE;
239                   }
240                else if (ncar=='?') 
241                   {
242                   fic_pos++;
243                   return M_PROLOG;
244                   }
245                else if (ncar=='!') 
246                   {
247                   fic_pos++;
248                   return M_COMMENT;
249                   }
250                else
251                   return M_BEGIN;
252                }
253             }
254          }
255 }
256 // ====================================================== getIdent
257 int XmlTree::getIdent (string& ident)
258 {
259    ident = "";
260
261    for (int nc=fic_pos-1; nc<len_buffer ; nc++)
262        {
263        char car = fic_buffer[nc];
264        if (isalnum (car) || car =='_')
265            {
266            ident.push_back (car);
267            }
268        else
269            {
270            fic_pos = nc;
271            return HOK;
272            }
273        }
274
275    fic_pos = len_buffer;
276    return HOK;
277 }
278 // ====================================================== goTo
279 int XmlTree::goTo (cpchar ouca)
280 {
281    int nbc = strlen (ouca) - 1;
282    int pos = 0;
283    int car = ' ';
284
285    while ((car = getChar ()) != EOF)
286        {
287        if (car!=ouca[pos])
288           pos = 0;
289        else if (pos<nbc)
290           pos++;
291        else 
292           return HOK;
293        }
294
295    return HERR;
296 }
297 // ====================================================== getString
298 int XmlTree::getString (string& chaine)
299 {
300    chaine  = "";
301    int car = ' ';
302
303    while ((car = getChar ()) != EOF)
304        {
305        if (car=='"') 
306           return HOK;
307        chaine.push_back (car); 
308        }
309
310    return HERR;
311 }
312 // ====================================================== getChar
313 int XmlTree::getChar ()
314 {
315    while (true)
316          {
317          if (fic_pos<len_buffer)
318             {
319             fic_pos++;
320             return fic_buffer [fic_pos-1];
321             }
322          int ier = readLine ();
323          if (ier==HEND_FILE)
324             return EOF;
325          else
326             return EOL;
327          }
328 }
329 // ====================================================== readLine
330 int XmlTree::readLine ()
331 {
332    nro_ligne++;
333    fic_buffer = "";
334    fic_pos    = 0;
335
336    if (xml_ended)
337        return HEND_FILE;
338
339    len_buffer = 0;
340    int ier = HEND_LINE;
341    while (ier==HEND_LINE)
342          {
343          int carac = xml_flow != NULL ? xml_flow [pos_flow++] 
344                                       : fgetc (xml_file);
345
346          if (carac==EOL || carac==CRLF)
347             {
348             ier = HOK;
349             }
350          else if (carac!=EOF && carac!=EOS)
351             {
352             fic_buffer.push_back (carac); 
353             len_buffer ++;
354             }
355          else if (len_buffer > 0)
356             {
357             xml_ended = true;
358             ier = HOK;
359             }
360          else 
361             {
362             xml_ended = true;
363             ier = HEND_FILE;
364             }
365          }
366    return HOK;
367 }
368 // ====================================================== putError
369 void XmlTree::putError (cpchar mess)
370 {
371      printf (" ***** Erreur : %s\n", mess);
372      printf (" +++ Derniere ligne lue : nro %d, %deme caractere\n", 
373                nro_ligne, fic_pos);
374      printf ("%s\n", fic_buffer.c_str());
375      //  exit (102);
376 }
377 // ====================================================== addChild
378 XmlTree* XmlTree::addChild (const string& nom)
379 {
380    XmlTree* child = new XmlTree (nom, this);
381    tab_items.push_back (child);
382    nbr_items ++;
383    return child;
384 }
385 // ====================================================== addAttribut
386 void XmlTree::addAttribut (const string& nom, const string& value)
387 {
388    tab_attributs.push_back (nom);
389    tab_values   .push_back (value);
390    nbr_attributs ++;
391    // printf (" %s = %s\n", nom.c_str(), value.c_str());
392 }
393 // ====================================================== dump
394 void XmlTree::dump (int niveau)
395 {
396    string marge = "";
397    for (int niv=0 ; niv<niveau ; niv++)
398        marge += " | ";
399
400    cout << marge << item_name << endl;
401
402    for (int nc=0 ; nc<nbr_attributs ; nc++)
403        {
404        cout << marge  << " : " 
405             << tab_attributs [nc] << " = '" << tab_values [nc] 
406             << "'" << endl;
407        }
408
409    for (int nc=0 ; nc<nbr_items ; nc++)
410        {
411        tab_items [nc]->dump (niveau+1);
412        }
413
414 }
415 END_NAMESPACE_HEXA