Salome HOME
cfbcbdbdbd9aa2d2f46205df6a1e8bb1919a42c7
[modules/paravis.git] / src / Plugins / JSONReader / JSONParser / vtkJSONParser.cxx
1 //  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author: Roman NIKOLAEV
20
21 #include "vtkJSONParser.h"
22
23 #include <vtkObjectFactory.h>
24 #include <vtkTable.h>
25 #include <vtkInformation.h>
26 #include <vtkDoubleArray.h>
27
28 #include <algorithm>
29 #include <sstream>
30 #include <list>
31 #include <map>
32
33 //DEBUG macro
34 //#define __DEBUG
35
36
37 // Key worlds
38 #define MD  "_metadata"
39 #define CMT "_comment"
40 #define TBN "table_name"
41 #define TBD "table_description"
42 #define SHT "short_names"
43 #define LNG "long_names"
44 #define UNT "units"
45 #define DT "date"
46
47 // Separators
48 #define COMMA ','
49
50 #define COLON ':'
51
52 #define OSB '['
53 #define CSB ']'
54
55 #define OCB '{'
56 #define CCB '}'
57 #define ENDL '\n'
58 #define QTS  '"'
59 #define SPS ' '
60 #define TAB  '\t'
61
62 #define NA   "n/a"
63
64
65 #define addInfo(info) \
66   Info I; \
67   I.type = info; \
68   I.ln = this->LineNumber; \
69   I.cn = this->ColumnNumber; \
70   I.pos = ftell(this->File); \
71   this->CInfoVector.push_back(I);
72
73 //---------------------------------------------------
74 bool isBlankOrEnd(const char c) {
75   return c ==  SPS || c == ENDL || c == TAB || c == EOF;
76 }
77
78 bool isDigitOrDot(const char c) {
79   return (c >= '.' && c <='9') || c == '+' || c == '-' || c == 'e';
80 }
81
82 // Exception
83 //---------------------------------------------------
84 vtkJSONException::vtkJSONException(const char *reason) : Reason(reason) {
85 }
86
87 //---------------------------------------------------
88 vtkJSONException::~vtkJSONException() throw () {
89 }
90
91 //---------------------------------------------------
92 const char* vtkJSONException::what() const throw() {
93   return Reason.c_str();
94 }
95
96 // Containers to store information about nodes:
97
98 // Base node
99 //---------------------------------------------------
100 class vtkJSONNode {
101 public:
102   vtkJSONNode() { Name = 0; }
103   virtual ~vtkJSONNode() { }
104   const char* GetName() { return this->Name ; }
105   void SetName(const char* name) { this->Name  = name; }
106 private:
107   const char* Name;
108 };
109
110 class vtkJSONMetaNode : public vtkJSONNode {
111 public:  
112   vtkJSONMetaNode() : vtkJSONNode() {
113     this->SetName(MD);
114   this->Comment  = 0;
115   this->TableName = 0;
116   this->TableDescription = 0;
117   this->Date = 0;
118   }
119
120   virtual ~vtkJSONMetaNode() {
121     delete this->Comment; this->Comment = 0;
122     delete this->TableName; this->TableName = 0;
123     delete this->Date; this->Date= 0;
124     delete this->TableDescription; this->TableDescription = 0;
125     for(int i = 0; i < this->ShortNames.size(); i++) {
126       delete this->ShortNames[i]; this->ShortNames[i] = 0;
127     }
128     for(int i = 0; i < this->LongNames.size(); i++) {
129       delete this->LongNames[i]; this->LongNames[i] = 0;
130     }
131     for(int i = 0; i < this->Units.size(); i++) {
132       delete this->Units[i]; this->Units[i] = 0;
133     }
134   }
135
136   void SetComment(const char* comment) { this->Comment = comment; }
137   const char* GetComment() { return this->Comment; }
138
139   void SetTableName(const char* name) { this->TableName = name; }
140   const char* GetTableName() { return this->TableName; }
141
142   void SetDate(const char* name) { this->Date = name; }
143   const char* GetDate() { return this->Date; }
144
145   void SetTableDescription(const char* description) { this->TableDescription = description; }
146   const char* GetDescription() { return this->TableDescription; }
147
148   void SetShortNames(std::vector<const char*> names) { this->ShortNames = names; }
149   std::vector<const char*> GetShortNames() { return this->ShortNames; }
150
151   void SetLongNames(std::vector<const char*> names) { this->LongNames = names; }
152   std::vector<const char*> GetLongNames() { return this->LongNames; }
153
154   void SetUnits(std::vector<const char*> units) { this->Units = units; }
155   std::vector<const char*> GetUnits() { return this->Units; }
156
157 private:
158   const char* Comment;
159   const char* TableName;
160   const char* TableDescription;
161   const char* Date;
162   std::vector<const char*> ShortNames;
163   std::vector<const char*> LongNames;
164   std::vector<const char*> Units;
165 };
166
167 struct char_cmp { 
168   bool operator () (const char *a, const char *b) const 
169   {
170     return strcmp(a,b)<0;
171   } 
172 };
173
174 typedef std::map<const char*, double, char_cmp> vtkJSONMap;
175
176 class vtkJSONInfoNode : public vtkJSONNode {
177 public:  
178   vtkJSONInfoNode(const char* name) : vtkJSONNode() {
179     this->SetName(name);
180   }
181   virtual ~vtkJSONInfoNode() {
182     vtkJSONMap::iterator it = this->Values.begin();
183     for( ;it != this->Values.end(); it++) {
184       delete it->first;
185       const char* c = it->first;
186       c = 0;
187     }
188   }
189   void AddValue(const char* key, const double value) {
190     this->Values.insert(std::pair<const char*,double>(key,value)); 
191   }
192   vtkJSONMap& GetValues() { return this->Values; }
193 private:  
194   vtkJSONMap Values;
195 };
196
197
198 //---------------------------------------------------
199 vtkStandardNewMacro(vtkJSONParser);
200
201 //---------------------------------------------------
202 vtkJSONParser::vtkJSONParser()
203 {
204   this->FileName = NULL;
205   this->LineNumber = 1;
206   this->ColumnNumber = 0;
207   this->File = 0;
208   this->InsideQuotes = false;
209   this->LastString = 0;
210   this->CurrentNode = 0;
211   this->ParseList = false;
212   this->ParseObjectList = false;
213   this->LastValue = NAN;
214   this->ShortNamesFilled = false;
215 }
216
217 //---------------------------------------------------
218 vtkJSONParser::~vtkJSONParser()
219 {
220   delete this->FileName;
221   this->FileName = 0;
222 }
223
224
225 //---------------------------------------------------
226 int vtkJSONParser::Parse(vtkTable* theTable) 
227 {
228   if(!this->FileName) {
229     vtkErrorMacro("The name of the file is not defined");
230     return 1;
231   }
232   this->File = fopen( this->FileName, "r" );
233   
234   if( !this->File ) {
235     std::string message  = std::string("Can't open file: ") + std::string(this->FileName);
236     throwSimpleException(message.c_str());
237     return 1;
238   }
239   char ch = 0;
240
241   this->ExpectedCharacters.push_back(OCB);
242   
243   while( ch != EOF ) {
244     ch = fgetc(this->File);
245     processCharacter(ch);
246     if(isDigitsAllowed() && isDigitOrDot(ch)) {
247       readDoubleValue();
248     }
249     int nb = 1;
250     switch(ch) {
251     case OCB: processOCB(); break;
252     case CCB: processCCB(); break;
253
254     case OSB: processOSB(); break;
255     case CSB: processCSB(); break;
256
257     case ENDL: processENDL(); nb = 0; break;
258
259     case QTS: processQTS(); break;
260
261     case COLON: processCOLON(); break;
262
263     case COMMA: processCOMMA(); break;
264     }
265     this->ColumnNumber+=nb;
266   }  
267   fclose(this->File);
268
269   if(this->CInfoVector.size() > 0 ) {
270     throwException("braket is not closed ", 
271                    this->CInfoVector.back().ln,
272                    this->CInfoVector.back().cn);
273   }
274
275   finalize(theTable);
276   clean();
277   return 1;
278 }
279
280 //---------------------------------------------------
281 void vtkJSONParser::finalize( vtkTable *t ) {
282   std::vector<vtkJSONNode*>::iterator it = this->Nodes.begin();
283   vtkJSONMetaNode* mn = 0;
284   for( ; it != this->Nodes.end(); it++ ) {
285     mn = dynamic_cast<vtkJSONMetaNode*>(*it);
286     if (mn)
287       break;
288   }
289   std::vector<const char*> units;
290   if(mn) {
291     if(!mn->GetShortNames().empty()) {
292       this->ShortNames.clear();
293       this->ShortNames = mn->GetShortNames();
294     }
295     t->GetInformation()->Set(vtkDataObject::FIELD_NAME(), mn->GetTableName() ? mn->GetTableName() : "");
296     units = mn->GetUnits();
297   }
298   
299   long nbRow = mn ? (this->Nodes.size() - 1 ) : this->Nodes.size();
300   for (long col=0; col < this->ShortNames.size(); col++) {
301     vtkDoubleArray* newCol = vtkDoubleArray::New();
302     newCol->SetNumberOfValues(nbRow);
303     vtkJSONInfoNode* in = 0;
304     std::string name = this->ShortNames[col];
305     name += "[";
306     if(col < units.size()){
307       name += units[col];
308     } else {
309       name += NA;
310     }
311     name += "]";
312     newCol->SetName(name.c_str());
313     it = this->Nodes.begin();
314     long row = 0;
315     for( ; it != this->Nodes.end(); it++ ) {
316       in = dynamic_cast<vtkJSONInfoNode*>(*it);
317       if (in) {
318         vtkJSONMap& vl = in->GetValues();
319         vtkJSONMap::iterator mit = vl.find(this->ShortNames[col]);
320         if(mit != vl.end()) {
321           newCol->SetValue(row, mit->second);
322           vl.erase(mit);
323           delete mit->first;
324           const char* c = mit->first;
325           c = 0;
326           row++;
327         } else {
328           std::string s("Item with name '");
329           s+=in->GetName();
330           s+="' has not key '";
331           s+=this->ShortNames[col];
332           s+="' !";
333           throwSimpleException(s.c_str());
334         }
335       }
336     }
337     t->AddColumn(newCol);
338   } 
339   it = this->Nodes.begin();
340   vtkJSONInfoNode* in = 0;
341   for( ; it != this->Nodes.end(); it++ ) {
342     in = dynamic_cast<vtkJSONInfoNode*>(*it);
343     if (in) {     
344       vtkJSONMap& vl = in->GetValues();
345       if(vl.size() > 0 ) {
346         std::string s("Item with name '");
347         s+=in->GetName();
348         s+="' has unexpected key '";
349         s+=vl.begin()->first;
350         s+="' !";
351         throwSimpleException(s.c_str());        
352       }
353     }
354   }
355 }
356
357 //---------------------------------------------------
358 void vtkJSONParser::processQTS() {
359   this->InsideQuotes = !this->InsideQuotes;
360   if(this->InsideQuotes) {
361     addInfo(QTS);
362   } else {
363     // Quotes is closed, get content
364     Info i =  this->CInfoVector.back();
365     this->CInfoVector.pop_back();
366     if(i.type == QTS) {
367       long begin = i.pos;
368       long end = ftell(this->File) - 1;
369       this->LastString = getString(begin, end);
370       bool parse_list = (this->CInfoVector.size() >= 1 && this->CInfoVector.back().type == OSB);
371       if(parse_list) {
372         this->CurrentList.push_back(this->LastString);
373       } else {
374         this->Strings.push_back(this->LastString);
375         processMetaNode();
376       }
377 #ifdef __DEBUG
378       std::cout<<"String  : "<<this->LastString<<std::endl;
379 #endif
380       
381       this->ExpectedCharacters.clear();
382       this->ExpectedCharacters.push_back(COLON);
383       this->ExpectedCharacters.push_back(COMMA);
384       this->ExpectedCharacters.push_back(CCB);
385       this->ExpectedCharacters.push_back(CSB); 
386     }
387   }
388 }
389
390 //---------------------------------------------------
391 void vtkJSONParser::processCOLON() {
392   if (this->InsideQuotes)
393     return;
394   this->ExpectedCharacters.clear();
395   this->ExpectedCharacters.push_back(OCB);
396   this->ExpectedCharacters.push_back(QTS);
397   this->ExpectedCharacters.push_back(OSB);
398   if(GetInfoNode() && Strings.size() ==  1 ) {
399     allowsDigits();
400   }
401 }
402
403 //---------------------------------------------------
404 void vtkJSONParser::processOCB() { 
405   if (this->InsideQuotes)
406     return;
407   this->ExpectedCharacters.clear();
408   this->ExpectedCharacters.push_back(QTS);
409   this->ExpectedCharacters.push_back(CCB);
410   
411   // Create node
412   if(this->CInfoVector.size() >= 1) {    
413     if ( !GetMetaNode() && this->Strings.size() > 0 && 
414          this->Strings.back() &&
415          strcmp(this->Strings.back(), MD) == 0 ) {
416 #ifdef __DEBUG
417       std::cout<<"Create new Meta Node !!!"<<std::endl;
418 #endif      
419       this->CurrentNode = new vtkJSONMetaNode();
420       delete this->Strings.back();
421       this->Strings.back() = 0;
422       this->Strings.pop_back();
423     } else {
424       if(this->CInfoVector.back().type == OSB ) {
425         this->ParseObjectList = true;
426       }
427 #ifdef __DEBUG
428       std::cout<<"Create new Node with name '"<<(this->Strings.size() == 0 ? "" : this->Strings.back())<<"' !!!"<<std::endl;
429 #endif          
430       this->CurrentNode = new vtkJSONInfoNode(this->Strings.size() == 0 ? "" : this->Strings.back());
431       if(!this->ParseObjectList && this->Strings.size() == 1) {
432         this->Strings.pop_back();
433       }
434     }
435   }
436   addInfo(OCB);
437 }
438
439 //---------------------------------------------------
440 vtkJSONMetaNode* vtkJSONParser::GetMetaNode() {
441   vtkJSONMetaNode *mnode = 0;
442   if( this->CurrentNode ) {
443     mnode = dynamic_cast<vtkJSONMetaNode*>(this->CurrentNode);
444   }
445   return mnode;
446 }
447
448 //---------------------------------------------------
449 vtkJSONInfoNode* vtkJSONParser::GetInfoNode() {
450   vtkJSONInfoNode *mnode = 0;
451   if( this->CurrentNode ) {
452     mnode = dynamic_cast<vtkJSONInfoNode*>(this->CurrentNode);
453   }
454   return mnode;
455 }
456
457 //---------------------------------------------------
458 void vtkJSONParser::processENDL() { 
459   if(this->InsideQuotes) {
460
461     throwException("quote is not closed !");
462   }
463   this->LineNumber++;
464   this->ColumnNumber=0;
465 }
466
467
468 //---------------------------------------------------
469 void vtkJSONParser::processCSB() {
470   if (this->InsideQuotes)
471     return;  
472  
473   if(this->CInfoVector.back().type == OSB) {
474     if(this->ParseList) {
475       this->ParseList = false;
476     }    
477     if(this->ParseObjectList) {
478       this->ParseObjectList = false;
479     }
480     this->CInfoVector.pop_back();
481   }
482
483   this->ExpectedCharacters.clear();
484   this->ExpectedCharacters.push_back(COMMA);
485   this->ExpectedCharacters.push_back(OCB);
486   this->ExpectedCharacters.push_back(CCB);
487 }
488
489 //---------------------------------------------------
490 void vtkJSONParser::processOSB() {
491   if (this->InsideQuotes)
492     return;
493
494   if(this->ParseList) {
495     Info i = CInfoVector.back();
496     if(i.type == OSB) {
497       throwException("list, which has been opened in this place, has not been closed !", i.ln, i.cn);
498     }
499   }  
500   if(GetMetaNode()) {
501     this->ParseList = true;
502   } else {
503     if( this->Strings.size() > 0 ) {
504       delete this->Strings[Strings.size()-1];
505       this->Strings[Strings.size()-1] = 0;
506       this->Strings.pop_back();
507     }
508   }
509   addInfo(OSB);
510   this->ExpectedCharacters.clear();
511   this->ExpectedCharacters.push_back(QTS);
512   this->ExpectedCharacters.push_back(OCB);
513 }
514
515 //---------------------------------------------------
516 void vtkJSONParser::processCCB() {
517   if (this->InsideQuotes)
518     return;
519
520   this->ExpectedCharacters.clear();
521   this->ExpectedCharacters.push_back(COMMA);
522   this->ExpectedCharacters.push_back(CCB);
523   if(this->ParseObjectList) {
524     this->ExpectedCharacters.push_back(CSB);
525   }
526
527   processMetaNode();
528   processInfoNode();
529
530   if(this->CurrentNode)
531     this->Nodes.push_back(this->CurrentNode);
532   if( !this->ShortNamesFilled ){
533     vtkJSONInfoNode* n = dynamic_cast<vtkJSONInfoNode*>(this->CurrentNode);
534     if(n){
535       this->ShortNamesFilled = true;
536     }
537   }
538
539 #ifdef __DEBUG
540   if(this->CurrentNode)
541     std::cout<<"End parsing node with name '"<<this->CurrentNode->GetName()<<"' !!!!"<<std::endl;
542 #endif
543
544   if (this->CInfoVector.size() > 0 && this->CInfoVector.back().type == OCB ) {
545     this->CInfoVector.pop_back();
546   } else{
547     throwException ("unexpected closed braket '}' !");
548   }
549
550   this->CurrentNode = 0;
551 }
552
553 //---------------------------------------------------
554 void vtkJSONParser::processCOMMA() {
555   if (this->InsideQuotes)
556     return;
557   this->ExpectedCharacters.clear();
558   this->ExpectedCharacters.push_back(QTS);
559   this->ExpectedCharacters.push_back(OCB);
560   processMetaNode();
561   processInfoNode();
562 }
563
564 void vtkJSONParser::processMetaNode() {
565  vtkJSONMetaNode* mn = GetMetaNode();
566   if(mn) {
567     bool strings  = this->Strings.size() == 2 && !this->ParseList;
568     bool str_and_list = (this->Strings.size() == 1 && this->CurrentList.size() > 0 && !this->ParseList);
569     
570     if( strings ) {
571       if ( strcmp(this->Strings[0], CMT) == 0 ) {
572         mn->SetComment(this->Strings[1]);
573 #ifdef __DEBUG
574       std::cout<<"Table Comment  : "<<this->Strings[1]<<std::endl;
575 #endif
576       } else if ( strcmp(this->Strings[0], TBN) == 0 ) { 
577         mn->SetTableName(this->Strings[1]);
578 #ifdef __DEBUG
579       std::cout<<"Table Name  : "<<this->Strings[1]<<std::endl;
580 #endif
581       } else if ( strcmp(this->Strings[0], TBD) == 0 ) {
582         mn->SetTableDescription(this->Strings[1]);
583 #ifdef __DEBUG
584         std::cout<<"Table Description  : "<<this->Strings[1]<<std::endl;
585 #endif
586       } else if ( strcmp(this->Strings[0], DT) == 0 ) {
587         mn->SetDate(this->Strings[1]);
588 #ifdef __DEBUG
589       std::cout<<"Date  : "<<this->Strings[1]<<std::endl;
590 #endif
591       } else {
592         std::stringstream s;
593         s << "File : "<< this->FileName;
594         s << ", line "<<this->LineNumber;
595         s << " unexpected key world: '"<<this->Strings[0]<<"'";
596       }
597       delete this->Strings[0];
598       this->Strings[0] = 0;
599       Strings.pop_back();
600       Strings.pop_back();
601       
602     } else if(str_and_list) {
603       if ( strcmp(this->Strings[0], SHT) == 0 ) { 
604         std::vector<const char*>::const_iterator it = this->CurrentList.begin();
605         for( ;it != this->CurrentList.end(); it++) {
606           checkShortName(*it);
607         }
608         mn->SetShortNames(this->CurrentList);
609 #ifdef __DEBUG
610         std::cout<<"Short Names : "<<std::endl;
611 #endif
612       } else if ( strcmp(this->Strings[0], LNG) == 0 ) { 
613         mn->SetLongNames(this->CurrentList);
614 #ifdef __DEBUG
615         std::cout<<"Long Names : "<<std::endl;
616 #endif
617       } else if ( strcmp(this->Strings[0], UNT) == 0 ) { 
618         mn->SetUnits(this->CurrentList);
619 #ifdef __DEBUG
620         std::cout<<"Units : ";
621 #endif
622       } else {
623         std::stringstream s;
624         s << "File : "<< this->FileName;
625         s << ", line "<<this->LineNumber;
626         s << " unexpected key world: '"<<this->Strings[0]<<"'";
627       }
628       delete this->Strings[0];
629       this->Strings[0] = 0;
630       Strings.pop_back();
631 #ifdef __DEBUG
632       std::vector<const char*>::const_iterator it = this->CurrentList.begin();
633       std::cout<<"[ ";
634       for( ;it != this->CurrentList.end(); it++) {
635         std::cout<<"'"<<*it<<"'";
636         if ( it+1 != this->CurrentList.end() )
637           std::cout<<", ";
638       }
639       std::cout<<" ]"<<std::endl;
640 #endif
641       this->CurrentList.clear();
642     }
643   }
644 }
645 //---------------------------------------------------
646 void vtkJSONParser::processInfoNode() { 
647  vtkJSONInfoNode* in = GetInfoNode();
648   if(in) {
649     if(this->Strings.size() == 1 && !isnan(this->LastValue)) {
650       in->AddValue(this->Strings[0],this->LastValue);
651       if(!ShortNamesFilled) {
652         char* name = new char[strlen(Strings[0])];
653         strcpy(name, Strings[0]);
654         this->ShortNames.push_back(name);
655       }
656       this->Strings.pop_back();
657       this->LastValue = NAN;
658     }
659   }
660 }
661
662 //---------------------------------------------------
663 void vtkJSONParser::processCharacter(const char ch) {
664   if (this->InsideQuotes)
665     return;
666   if(isBlankOrEnd(ch))
667     return;
668
669   if(this->ExpectedCharacters.empty())
670     return;
671   
672   std::vector<char>::const_iterator it = std::find(this->ExpectedCharacters.begin(),
673                                                    this->ExpectedCharacters.end(),
674                                                    ch);  
675   
676   // Unexpected character is found
677   if(it == this->ExpectedCharacters.end()) {
678     std::string s("unexpected character '");
679     s+=ch;
680     s+="' !";
681     throwException(s.c_str());
682
683   }
684 }
685
686 //---------------------------------------------------
687 char* vtkJSONParser::getString(long b, long e) {
688   char* result = 0;
689
690   long old_pos = ftell(this->File);
691   fseek(this->File, b, SEEK_SET);
692   long data_s = e - b;
693   result = new char[data_s];
694   result[0] = 0;
695   size_t nb_read = fread(result, sizeof(char), data_s, this->File);  
696   result[nb_read] = '\0';
697   fseek(this->File, old_pos, SEEK_SET);
698   return result;
699 }
700
701 //---------------------------------------------------
702 void vtkJSONParser::allowsDigits() {
703   for(char c = '.'; c <= '9'; c++) {
704     ExpectedCharacters.push_back(c);
705   }
706   ExpectedCharacters.push_back('-');
707   ExpectedCharacters.push_back('+');
708   ExpectedCharacters.push_back('e');
709 }
710
711 //---------------------------------------------------
712 bool vtkJSONParser::isDigitsAllowed() {
713   std::vector<char>::const_iterator it = std::find(this->ExpectedCharacters.begin(),
714                                                    this->ExpectedCharacters.end(),
715                                                    '0');
716   return (it != this->ExpectedCharacters.end());
717 }
718
719 //---------------------------------------------------
720 void vtkJSONParser::readDoubleValue() {
721   long b = ftell(this->File);
722
723   while(1) {
724     char ch = fgetc(this->File); 
725     if(!isDigitOrDot(ch)) {
726       break;
727     }
728   }
729
730   long e = ftell(this->File);
731   fseek(this->File, b-1, SEEK_SET);
732   long data_s = e - b;
733   char* result = new char[data_s];
734   result[0] = 0;
735   size_t nb_read = fread(result, sizeof(char), data_s, this->File);  
736   result[nb_read] = '\0';
737   this->ExpectedCharacters.clear();
738   this->ExpectedCharacters.push_back(COMMA);
739   this->ExpectedCharacters.push_back(CCB);
740   this->LastValue = atof(result);
741 #ifdef __DEBUG
742   std::cout<<"Read number : "<<this->LastValue<<std::endl;
743 #endif
744 }
745
746 //---------------------------------------------------
747 void vtkJSONParser::checkShortName(const char* name) {
748   size_t ln = strlen(name);
749   if( ln > 0 ){
750     for( size_t i = 0; i < ln; i++ ) { 
751       // a - z
752       if(!(name[i] >= 'a' &&  name[i] <= 'z') && 
753       // A - Z
754          !(name[i] >= 'A' &&  name[i] <= 'Z') ) {
755         std::string s("wrong short name '");
756         s += name;
757         s += "' !";
758         throwException(s.c_str(), this->LineNumber);
759       }
760     }
761   }
762 }
763
764 void vtkJSONParser::clean() {
765   std::vector<vtkJSONNode*>::iterator it = this->Nodes.begin();
766   for( ; it != this->Nodes.end(); it++ ) {
767     delete *(it);
768     *it = 0;
769   }
770 }
771
772 //---------------------------------------------------
773 void vtkJSONParser::throwException(const char* message) {
774     std::stringstream s;
775     s << "File : "<< this->FileName;
776     s << ", line "<<this->LineNumber;
777     s << ", column " << this->ColumnNumber<<" : ";
778     s << message;
779     clean();
780     throw vtkJSONException(s.str().c_str());  
781 }
782
783 //---------------------------------------------------
784 void vtkJSONParser::throwException(const char* message, int ln, int cn) {
785     std::stringstream s;
786     s << "File : "<< this->FileName;
787     s << ", line "<<ln;
788     s << ", column :" << cn << "  ";
789     s << message;
790     clean();
791     throw vtkJSONException(s.str().c_str());  
792 }
793 //---------------------------------------------------
794 void vtkJSONParser::throwException(const char* message, int ln) {
795   std::stringstream s;
796    s << "File "<< this->FileName;
797    s << ", line "<<ln <<" : ";
798    s << message;
799    clean();
800    throw vtkJSONException(s.str().c_str());  
801 }
802
803 //---------------------------------------------------
804 void vtkJSONParser::throwSimpleException(const char* message) {
805   clean();
806   throw vtkJSONException(message);
807 }