Salome HOME
7c28266e2b6b286e0f1d41b221c6d11175741d99
[modules/hexablock.git] / src / HEXABLOCK / HexXmlTree.cxx
1
2 // C++ : ParserXml
3
4 #include "HexXmlTree.hxx"
5
6 BEGIN_NAMESPACE_HEXA
7
8 enum { HEND_FILE = -2, HEND_LINE = -1, CRLF = 13 };
9
10 // ====================================================== Constructeur 
11 XmlTree::XmlTree (const string& nom, XmlTree* dad)
12 {
13     item_name     = nom;
14     item_vide     = "";
15     xml_parent    = dad;
16     nbr_attributs = 0;
17     nbr_items     = 0;
18
19    fic_buffer  = "";
20    len_buffer  = 0;
21    fic_xml     = NULL;
22    nro_ligne   = 0;
23    fic_pos     = 1988;
24 }
25 // ====================================================== Destructeur
26 XmlTree::~XmlTree ()
27 {
28 }
29 // ====================================================== findChild
30 XmlTree* XmlTree::findChild (const string& nom)
31 {
32    for (int nro = 0 ; nro<nbr_items ; nro++)
33        {
34        if (nom == tab_items [nro]->item_name)
35            return tab_items [nro];
36        }
37    return NULL;
38 }
39 // ====================================================== findAttribute
40 int XmlTree::findAttribute (const string& nom)
41 {
42    for (int nro = 0 ; nro<nbr_attributs ; nro++)
43        {
44        if (nom == tab_attributs [nro])
45           return nro;
46        }
47    return NOTHING;
48 }
49 // ====================================================== findValue
50 const string& XmlTree::findValue (const string& nom)
51 {
52    for (int nro = 0 ; nro<nbr_attributs ; nro++)
53        {
54        if (nom == tab_attributs [nro])
55           return  tab_values    [nro];
56        }
57    return item_vide;
58 }
59 // ====================================================== parseFile
60 int XmlTree::parseFile (const string& ficnom)
61 {
62    fic_buffer  = "";
63    len_buffer  = 0;
64    nro_ligne   = 0;
65    fic_pos     = 1988;
66
67    fic_xml = fopen (ficnom.c_str(), "r");
68    if (fic_xml==NULL)
69       return HERR;
70
71    enum EnumEtat { M_PREMS, M_BALISE_OUVERTE, M_NEUTRE };
72    EnumEtat etat =  M_PREMS;
73
74    XmlTree* node = this;
75    EnumItem item_lu;
76    string   nom, valeur, foo;
77    while ((item_lu=readItem (nom)) != M_NONE)
78       {
79       switch (item_lu) 
80          {
81          case M_BEGIN :
82               item_lu = getItem (nom, M_IDENT);
83               if (etat==M_PREMS) 
84                  setName (nom);
85               else
86                  node = node -> addChild  (nom);
87               etat = M_BALISE_OUVERTE;
88               break;
89
90          case M_END   :
91               if (etat != M_BALISE_OUVERTE) 
92                  putError (" balise ouverte");
93               etat = M_NEUTRE;
94               break;
95
96          case M_BEGIN_CLOSE :
97               if (etat == M_BALISE_OUVERTE) 
98                  putError (" balise ouverte");
99               getItem (nom, M_IDENT);
100               getItem (foo, M_END);
101               node = node -> getParent ();
102               break;
103
104          case M_CLOSE :
105               if (etat != M_BALISE_OUVERTE) 
106                  putError (" balise deja fermee");
107               node = node -> getParent ();
108               etat = M_NEUTRE;
109               break;
110
111          case M_IDENT :
112               getItem (valeur, M_EQUALS);
113               getItem (valeur, M_STRING);
114               node -> addAttribut (nom, valeur);
115               break;
116
117          case M_COMMENT : goTo ("-->");
118               break;
119
120          case M_PROLOG  : goTo ("?>");
121               break;
122
123          default :
124          case M_EQUALS :
125          case M_STRING :
126          case M_END_COMMENT :
127          case M_END_PROLOG :
128               putError ("Item incorrect");
129          }
130       }
131    return HOK;
132 }
133 // ====================================================== getItem
134 EnumItem XmlTree::getItem (string& value, EnumItem waited)
135 {
136    EnumItem item = readItem (value);
137
138    if (item == waited) 
139       return item;
140    putError ("Erreur de sequence");
141    return item;
142 }
143 // ====================================================== readItem
144 EnumItem XmlTree::readItem (string& value)
145 {
146    value  = "";
147
148    while (true)
149          {
150          if (fic_pos>=len_buffer)
151             {
152             int ier=readLine ();
153             if (ier==HEND_FILE) 
154                return M_NONE;
155             }
156          else
157             {
158             char  car = fic_buffer [fic_pos++];
159
160             if (car=='=')
161                return M_EQUALS;
162             else if (car=='>')
163                return M_END;
164             else if (car=='"')
165                {
166                getString (value);
167                return M_STRING;
168                }
169             else if (isalpha (car))
170                {
171                getIdent (value);
172                return M_IDENT;
173                }
174
175             char ncar = fic_pos >= len_buffer ? ' ' : fic_buffer [fic_pos];
176             if (car=='/' && ncar == '>')
177                {
178                fic_pos++;
179                return M_CLOSE;
180                }
181             else if (car=='<')
182                {
183                if (ncar=='/') 
184                   {
185                   fic_pos++;
186                   return M_BEGIN_CLOSE;
187                   }
188                else if (ncar=='?') 
189                   {
190                   fic_pos++;
191                   return M_PROLOG;
192                   }
193                else if (ncar=='!') 
194                   {
195                   fic_pos++;
196                   return M_COMMENT;
197                   }
198                else
199                   return M_BEGIN;
200                }
201             }
202          }
203 }
204 // ====================================================== getIdent
205 int XmlTree::getIdent (string& ident)
206 {
207    ident = "";
208
209    for (int nc=fic_pos-1; nc<len_buffer ; nc++)
210        {
211        char car = fic_buffer[nc];
212        if (isalnum (car))
213            {
214            ident.push_back (car);
215            }
216        else
217            {
218            fic_pos = nc;
219            return HOK;
220            }
221        }
222
223    fic_pos = len_buffer;
224    return HOK;
225 }
226 // ====================================================== goTo
227 int XmlTree::goTo (cpchar ouca)
228 {
229    int nbc = strlen (ouca) - 1;
230    int pos = 0;
231    int car = ' ';
232
233    while ((car = getChar ()) != EOF)
234        {
235        if (car!=ouca[pos])
236           pos = 0;
237        else if (pos<nbc)
238           pos++;
239        else 
240           return HOK;
241        }
242
243    return HERR;
244 }
245 // ====================================================== getString
246 int XmlTree::getString (string& chaine)
247 {
248    chaine  = "";
249    int car = ' ';
250
251    while ((car = getChar ()) != EOF)
252        {
253        if (car=='"') 
254           return HOK;
255        chaine.push_back (car); 
256        }
257
258    return HERR;
259 }
260 // ====================================================== getChar
261 int XmlTree::getChar ()
262 {
263    while (true)
264          {
265          if (fic_pos<len_buffer)
266             {
267             fic_pos++;
268             return fic_buffer [fic_pos-1];
269             }
270          int ier = readLine ();
271          if (ier==HEND_FILE)
272             return EOF;
273          else
274             return EOL;
275          }
276 }
277 // ====================================================== readLine
278 int XmlTree::readLine ()
279 {
280    nro_ligne++;
281    fic_buffer = "";
282    fic_pos    = 0;
283
284    if (fic_xml==NULL || feof (fic_xml))
285        return HEND_FILE;
286
287    len_buffer = 0;
288    int ier = HEND_LINE;
289    while (ier==HEND_LINE)
290          {
291          int carac = fgetc (fic_xml);
292          if (carac==EOL || carac==CRLF)
293             {
294             ier = HOK;
295             }
296          else if (carac!=EOF)
297             {
298             fic_buffer.push_back (carac); 
299             len_buffer ++;
300             }
301          else if (len_buffer > 0)
302             ier = HOK;
303          else 
304             ier = HEND_FILE;
305          }
306    return HOK;
307 }
308 // ====================================================== putError
309 void XmlTree::putError (cpchar mess)
310 {
311      printf (" ***** Erreur : %s\n", mess);
312      printf (" +++ Derniere ligne lue : nro %d, %deme caractere\n", 
313                nro_ligne, fic_pos);
314      printf ("%s\n", fic_buffer.c_str());
315      //  exit (102);
316 }
317 // ====================================================== addChild
318 XmlTree* XmlTree::addChild (const string& nom)
319 {
320    XmlTree* child = new XmlTree (nom, this);
321    tab_items.push_back (child);
322    nbr_items ++;
323    return child;
324 }
325 // ====================================================== addAttribut
326 void XmlTree::addAttribut (const string& nom, const string& value)
327 {
328    tab_attributs.push_back (nom);
329    tab_values   .push_back (value);
330    nbr_attributs ++;
331    // printf (" %s = %s\n", nom.c_str(), value.c_str());
332 }
333 // ====================================================== dump
334 void XmlTree::dump (int niveau)
335 {
336    string marge = "";
337    for (int niv=0 ; niv<niveau ; niv++)
338        marge += " | ";
339
340    cout << marge << item_name << endl;
341
342    for (int nc=0 ; nc<nbr_attributs ; nc++)
343        {
344        cout << marge  << " : " 
345             << tab_attributs [nc] << " = '" << tab_values [nc] 
346             << "'" << endl;
347        }
348
349    for (int nc=0 ; nc<nbr_items ; nc++)
350        {
351        tab_items [nc]->dump (niveau+1);
352        }
353
354 }
355 END_NAMESPACE_HEXA