Salome HOME
Implementation of the "0023167: [CEA 1592] JSON ParaView reader" issue.
authorrnv <rnv@opencascade.com>
Mon, 26 Oct 2015 12:40:52 +0000 (15:40 +0300)
committerrnv <rnv@opencascade.com>
Mon, 26 Oct 2015 12:48:33 +0000 (15:48 +0300)
31 files changed:
CMakeLists.txt
src/Plugins/CMakeLists.txt
src/Plugins/JSONReader/CMakeLists.txt [new file with mode: 0644]
src/Plugins/JSONReader/Examples/example1.json [new file with mode: 0644]
src/Plugins/JSONReader/Examples/example1_wo_metadata.json [new file with mode: 0644]
src/Plugins/JSONReader/Examples/example2.json [new file with mode: 0644]
src/Plugins/JSONReader/Examples/example2_wo_metadata.json [new file with mode: 0644]
src/Plugins/JSONReader/JSONParser/CMakeLists.txt [new file with mode: 0644]
src/Plugins/JSONReader/JSONParser/vtkJSONParser.cxx [new file with mode: 0644]
src/Plugins/JSONReader/JSONParser/vtkJSONParser.h [new file with mode: 0644]
src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt [new file with mode: 0644]
src/Plugins/JSONReader/ParaViewPlugin/JSONReader.xml [new file with mode: 0644]
src/Plugins/JSONReader/ParaViewPlugin/plugin.cmake [new file with mode: 0644]
src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx [new file with mode: 0644]
src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex1.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex10.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex11.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex2.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex3.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex4.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex5.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex6.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex7.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex8.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/BadFiles/bad_ex9.json [new file with mode: 0644]
src/Plugins/JSONReader/Test/CMakeLists.txt [new file with mode: 0644]
src/Plugins/JSONReader/Test/JSONParserTest.cxx [new file with mode: 0644]
src/Plugins/JSONReader/Test/MainTest.hxx [new file with mode: 0644]
src/Plugins/JSONReader/Test/vtkJSONParserTest.cxx [new file with mode: 0644]
src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx [new file with mode: 0644]

index 5ec42e80fc14ef9996f9b1f20f1bc278be383b14..4aed0ec84294da2adeb9af0943449c3f7dc84275 100644 (file)
@@ -83,6 +83,8 @@ CMAKE_DEPENDENT_OPTION(SALOME_LIGHT_ONLY "Build SALOME Light only (no CORBA)" OF
 
 IF(SALOME_BUILD_TESTS)
   ENABLE_TESTING()
+  FIND_PACKAGE(SalomeCppUnit)
+  SALOME_LOG_OPTIONAL_PACKAGE(CppUnit SALOME_BUILD_TESTS)
 ENDIF()
 
 # Prerequisites
index ba04a76b671b408cf2449530cff595bc6a37874f..20310a0793a642f8b21ec90190030d60fdca6f4f 100755 (executable)
@@ -34,6 +34,7 @@ SET(_subdirs
   EllipseBuilder
   DifferenceTimesteps
   ArrayRenamer
+  JSONReader
   )
   
 IF(NOT SALOME_LIGHT_ONLY)
diff --git a/src/Plugins/JSONReader/CMakeLists.txt b/src/Plugins/JSONReader/CMakeLists.txt
new file mode 100644 (file)
index 0000000..163fef3
--- /dev/null
@@ -0,0 +1,39 @@
+# Copyright (C) 2015 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Author : Roman NIKOLAEV
+
+PROJECT(JSONReader)
+
+cmake_minimum_required(VERSION 2.8)
+
+# Find ParaView
+FIND_PACKAGE(ParaView REQUIRED)
+INCLUDE(${PARAVIEW_USE_FILE})
+
+# Standard CMake option for building libraries shared or static by default.
+OPTION(BUILD_SHARED_LIBS "Build with shared libraries" ${VTK_BUILD_SHARED_LIBS})
+
+# Add subdirectories
+ADD_SUBDIRECTORY(JSONParser)
+ADD_SUBDIRECTORY(ParaViewPlugin)
+IF(SALOME_BUILD_TESTS)
+  ENABLE_TESTING()
+  ADD_SUBDIRECTORY(Test)
+ENDIF()
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Examples/example1.json b/src/Plugins/JSONReader/Examples/example1.json
new file mode 100644 (file)
index 0000000..db0edfc
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "_metadata": {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Examples/example1_wo_metadata.json b/src/Plugins/JSONReader/Examples/example1_wo_metadata.json
new file mode 100644 (file)
index 0000000..ad7bf54
--- /dev/null
@@ -0,0 +1,22 @@
+{
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Examples/example2.json b/src/Plugins/JSONReader/Examples/example2.json
new file mode 100644 (file)
index 0000000..55d17e8
--- /dev/null
@@ -0,0 +1,32 @@
+{
+    "_metadata": {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight"],
+      "long_names": ["Pressure", "Velocity", "Total weight"],
+      "date" : "12/12/12",
+      "units": ["Pa", "m/s", "kg"]
+      },
+    
+     "item1" : {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+     "item2" :
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+    "item3" :
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+}
diff --git a/src/Plugins/JSONReader/Examples/example2_wo_metadata.json b/src/Plugins/JSONReader/Examples/example2_wo_metadata.json
new file mode 100644 (file)
index 0000000..d52cea5
--- /dev/null
@@ -0,0 +1,22 @@
+{
+
+     "item1" : {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+     "item2" :
+      {
+        "P": 4.156,
+        "u": 465.0,
+        "weight": 137.5
+      },
+      
+    "item3" :
+      {
+        "P": -3.0305890e+4,
+        "u": 1.0305890e-1,
+        "weight": -3.0305890e+5
+      }
+}
diff --git a/src/Plugins/JSONReader/JSONParser/CMakeLists.txt b/src/Plugins/JSONReader/JSONParser/CMakeLists.txt
new file mode 100644 (file)
index 0000000..10f1d0e
--- /dev/null
@@ -0,0 +1,30 @@
+# Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author: Roman NIKOLAEV
+
+SET(PARCER_SRCS
+    vtkJSONParser.cxx)
+
+ADD_LIBRARY(vtkJSONParser ${PARCER_SRCS})
+
+TARGET_LINK_LIBRARIES(vtkJSONParser ${VTK_LIBRARIES})
+
+INSTALL(
+    TARGETS vtkJSONParser
+    DESTINATION lib/salome)
diff --git a/src/Plugins/JSONReader/JSONParser/vtkJSONParser.cxx b/src/Plugins/JSONReader/JSONParser/vtkJSONParser.cxx
new file mode 100644 (file)
index 0000000..cfbcbdb
--- /dev/null
@@ -0,0 +1,807 @@
+//  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author: Roman NIKOLAEV
+
+#include "vtkJSONParser.h"
+
+#include <vtkObjectFactory.h>
+#include <vtkTable.h>
+#include <vtkInformation.h>
+#include <vtkDoubleArray.h>
+
+#include <algorithm>
+#include <sstream>
+#include <list>
+#include <map>
+
+//DEBUG macro
+//#define __DEBUG
+
+
+// Key worlds
+#define MD  "_metadata"
+#define CMT "_comment"
+#define TBN "table_name"
+#define TBD "table_description"
+#define SHT "short_names"
+#define LNG "long_names"
+#define UNT "units"
+#define DT "date"
+
+// Separators
+#define COMMA ','
+
+#define COLON ':'
+
+#define OSB '['
+#define CSB ']'
+
+#define OCB '{'
+#define CCB '}'
+#define ENDL '\n'
+#define QTS  '"'
+#define SPS ' '
+#define TAB  '\t'
+
+#define NA   "n/a"
+
+
+#define addInfo(info) \
+  Info I; \
+  I.type = info; \
+  I.ln = this->LineNumber; \
+  I.cn = this->ColumnNumber; \
+  I.pos = ftell(this->File); \
+  this->CInfoVector.push_back(I);
+
+//---------------------------------------------------
+bool isBlankOrEnd(const char c) {
+  return c ==  SPS || c == ENDL || c == TAB || c == EOF;
+}
+
+bool isDigitOrDot(const char c) {
+  return (c >= '.' && c <='9') || c == '+' || c == '-' || c == 'e';
+}
+
+// Exception
+//---------------------------------------------------
+vtkJSONException::vtkJSONException(const char *reason) : Reason(reason) {
+}
+
+//---------------------------------------------------
+vtkJSONException::~vtkJSONException() throw () {
+}
+
+//---------------------------------------------------
+const char* vtkJSONException::what() const throw() {
+  return Reason.c_str();
+}
+
+// Containers to store information about nodes:
+
+// Base node
+//---------------------------------------------------
+class vtkJSONNode {
+public:
+  vtkJSONNode() { Name = 0; }
+  virtual ~vtkJSONNode() { }
+  const char* GetName() { return this->Name ; }
+  void SetName(const char* name) { this->Name  = name; }
+private:
+  const char* Name;
+};
+
+class vtkJSONMetaNode : public vtkJSONNode {
+public:  
+  vtkJSONMetaNode() : vtkJSONNode() {
+    this->SetName(MD);
+  this->Comment  = 0;
+  this->TableName = 0;
+  this->TableDescription = 0;
+  this->Date = 0;
+  }
+
+  virtual ~vtkJSONMetaNode() {
+    delete this->Comment; this->Comment = 0;
+    delete this->TableName; this->TableName = 0;
+    delete this->Date; this->Date= 0;
+    delete this->TableDescription; this->TableDescription = 0;
+    for(int i = 0; i < this->ShortNames.size(); i++) {
+      delete this->ShortNames[i]; this->ShortNames[i] = 0;
+    }
+    for(int i = 0; i < this->LongNames.size(); i++) {
+      delete this->LongNames[i]; this->LongNames[i] = 0;
+    }
+    for(int i = 0; i < this->Units.size(); i++) {
+      delete this->Units[i]; this->Units[i] = 0;
+    }
+  }
+
+  void SetComment(const char* comment) { this->Comment = comment; }
+  const char* GetComment() { return this->Comment; }
+
+  void SetTableName(const char* name) { this->TableName = name; }
+  const char* GetTableName() { return this->TableName; }
+
+  void SetDate(const char* name) { this->Date = name; }
+  const char* GetDate() { return this->Date; }
+
+  void SetTableDescription(const char* description) { this->TableDescription = description; }
+  const char* GetDescription() { return this->TableDescription; }
+
+  void SetShortNames(std::vector<const char*> names) { this->ShortNames = names; }
+  std::vector<const char*> GetShortNames() { return this->ShortNames; }
+
+  void SetLongNames(std::vector<const char*> names) { this->LongNames = names; }
+  std::vector<const char*> GetLongNames() { return this->LongNames; }
+
+  void SetUnits(std::vector<const char*> units) { this->Units = units; }
+  std::vector<const char*> GetUnits() { return this->Units; }
+
+private:
+  const char* Comment;
+  const char* TableName;
+  const char* TableDescription;
+  const char* Date;
+  std::vector<const char*> ShortNames;
+  std::vector<const char*> LongNames;
+  std::vector<const char*> Units;
+};
+
+struct char_cmp { 
+  bool operator () (const char *a, const char *b) const 
+  {
+    return strcmp(a,b)<0;
+  } 
+};
+
+typedef std::map<const char*, double, char_cmp> vtkJSONMap;
+
+class vtkJSONInfoNode : public vtkJSONNode {
+public:  
+  vtkJSONInfoNode(const char* name) : vtkJSONNode() {
+    this->SetName(name);
+  }
+  virtual ~vtkJSONInfoNode() {
+    vtkJSONMap::iterator it = this->Values.begin();
+    for( ;it != this->Values.end(); it++) {
+      delete it->first;
+      const char* c = it->first;
+      c = 0;
+    }
+  }
+  void AddValue(const char* key, const double value) {
+    this->Values.insert(std::pair<const char*,double>(key,value)); 
+  }
+  vtkJSONMap& GetValues() { return this->Values; }
+private:  
+  vtkJSONMap Values;
+};
+
+
+//---------------------------------------------------
+vtkStandardNewMacro(vtkJSONParser);
+
+//---------------------------------------------------
+vtkJSONParser::vtkJSONParser()
+{
+  this->FileName = NULL;
+  this->LineNumber = 1;
+  this->ColumnNumber = 0;
+  this->File = 0;
+  this->InsideQuotes = false;
+  this->LastString = 0;
+  this->CurrentNode = 0;
+  this->ParseList = false;
+  this->ParseObjectList = false;
+  this->LastValue = NAN;
+  this->ShortNamesFilled = false;
+}
+
+//---------------------------------------------------
+vtkJSONParser::~vtkJSONParser()
+{
+  delete this->FileName;
+  this->FileName = 0;
+}
+
+
+//---------------------------------------------------
+int vtkJSONParser::Parse(vtkTable* theTable) 
+{
+  if(!this->FileName) {
+    vtkErrorMacro("The name of the file is not defined");
+    return 1;
+  }
+  this->File = fopen( this->FileName, "r" );
+  
+  if( !this->File ) {
+    std::string message  = std::string("Can't open file: ") + std::string(this->FileName);
+    throwSimpleException(message.c_str());
+    return 1;
+  }
+  char ch = 0;
+
+  this->ExpectedCharacters.push_back(OCB);
+  
+  while( ch != EOF ) {
+    ch = fgetc(this->File);
+    processCharacter(ch);
+    if(isDigitsAllowed() && isDigitOrDot(ch)) {
+      readDoubleValue();
+    }
+    int nb = 1;
+    switch(ch) {
+    case OCB: processOCB(); break;
+    case CCB: processCCB(); break;
+
+    case OSB: processOSB(); break;
+    case CSB: processCSB(); break;
+
+    case ENDL: processENDL(); nb = 0; break;
+
+    case QTS: processQTS(); break;
+
+    case COLON: processCOLON(); break;
+
+    case COMMA: processCOMMA(); break;
+    }
+    this->ColumnNumber+=nb;
+  }  
+  fclose(this->File);
+
+  if(this->CInfoVector.size() > 0 ) {
+    throwException("braket is not closed ", 
+                  this->CInfoVector.back().ln,
+                  this->CInfoVector.back().cn);
+  }
+
+  finalize(theTable);
+  clean();
+  return 1;
+}
+
+//---------------------------------------------------
+void vtkJSONParser::finalize( vtkTable *t ) {
+  std::vector<vtkJSONNode*>::iterator it = this->Nodes.begin();
+  vtkJSONMetaNode* mn = 0;
+  for( ; it != this->Nodes.end(); it++ ) {
+    mn = dynamic_cast<vtkJSONMetaNode*>(*it);
+    if (mn)
+      break;
+  }
+  std::vector<const char*> units;
+  if(mn) {
+    if(!mn->GetShortNames().empty()) {
+      this->ShortNames.clear();
+      this->ShortNames = mn->GetShortNames();
+    }
+    t->GetInformation()->Set(vtkDataObject::FIELD_NAME(), mn->GetTableName() ? mn->GetTableName() : "");
+    units = mn->GetUnits();
+  }
+  
+  long nbRow = mn ? (this->Nodes.size() - 1 ) : this->Nodes.size();
+  for (long col=0; col < this->ShortNames.size(); col++) {
+    vtkDoubleArray* newCol = vtkDoubleArray::New();
+    newCol->SetNumberOfValues(nbRow);
+    vtkJSONInfoNode* in = 0;
+    std::string name = this->ShortNames[col];
+    name += "[";
+    if(col < units.size()){
+      name += units[col];
+    } else {
+      name += NA;
+    }
+    name += "]";
+    newCol->SetName(name.c_str());
+    it = this->Nodes.begin();
+    long row = 0;
+    for( ; it != this->Nodes.end(); it++ ) {
+      in = dynamic_cast<vtkJSONInfoNode*>(*it);
+      if (in) {
+       vtkJSONMap& vl = in->GetValues();
+       vtkJSONMap::iterator mit = vl.find(this->ShortNames[col]);
+       if(mit != vl.end()) {
+         newCol->SetValue(row, mit->second);
+         vl.erase(mit);
+         delete mit->first;
+         const char* c = mit->first;
+         c = 0;
+         row++;
+       } else {
+         std::string s("Item with name '");
+         s+=in->GetName();
+         s+="' has not key '";
+         s+=this->ShortNames[col];
+         s+="' !";
+         throwSimpleException(s.c_str());
+       }
+      }
+    }
+    t->AddColumn(newCol);
+  } 
+  it = this->Nodes.begin();
+  vtkJSONInfoNode* in = 0;
+  for( ; it != this->Nodes.end(); it++ ) {
+    in = dynamic_cast<vtkJSONInfoNode*>(*it);
+    if (in) {     
+      vtkJSONMap& vl = in->GetValues();
+      if(vl.size() > 0 ) {
+       std::string s("Item with name '");
+       s+=in->GetName();
+       s+="' has unexpected key '";
+       s+=vl.begin()->first;
+       s+="' !";
+       throwSimpleException(s.c_str());        
+      }
+    }
+  }
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processQTS() {
+  this->InsideQuotes = !this->InsideQuotes;
+  if(this->InsideQuotes) {
+    addInfo(QTS);
+  } else {
+    // Quotes is closed, get content
+    Info i =  this->CInfoVector.back();
+    this->CInfoVector.pop_back();
+    if(i.type == QTS) {
+      long begin = i.pos;
+      long end = ftell(this->File) - 1;
+      this->LastString = getString(begin, end);
+      bool parse_list = (this->CInfoVector.size() >= 1 && this->CInfoVector.back().type == OSB);
+      if(parse_list) {
+       this->CurrentList.push_back(this->LastString);
+      } else {
+       this->Strings.push_back(this->LastString);
+       processMetaNode();
+      }
+#ifdef __DEBUG
+      std::cout<<"String  : "<<this->LastString<<std::endl;
+#endif
+      
+      this->ExpectedCharacters.clear();
+      this->ExpectedCharacters.push_back(COLON);
+      this->ExpectedCharacters.push_back(COMMA);
+      this->ExpectedCharacters.push_back(CCB);
+      this->ExpectedCharacters.push_back(CSB); 
+    }
+  }
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processCOLON() {
+  if (this->InsideQuotes)
+    return;
+  this->ExpectedCharacters.clear();
+  this->ExpectedCharacters.push_back(OCB);
+  this->ExpectedCharacters.push_back(QTS);
+  this->ExpectedCharacters.push_back(OSB);
+  if(GetInfoNode() && Strings.size() ==  1 ) {
+    allowsDigits();
+  }
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processOCB() { 
+  if (this->InsideQuotes)
+    return;
+  this->ExpectedCharacters.clear();
+  this->ExpectedCharacters.push_back(QTS);
+  this->ExpectedCharacters.push_back(CCB);
+  
+  // Create node
+  if(this->CInfoVector.size() >= 1) {    
+    if ( !GetMetaNode() && this->Strings.size() > 0 && 
+        this->Strings.back() &&
+        strcmp(this->Strings.back(), MD) == 0 ) {
+#ifdef __DEBUG
+      std::cout<<"Create new Meta Node !!!"<<std::endl;
+#endif      
+      this->CurrentNode = new vtkJSONMetaNode();
+      delete this->Strings.back();
+      this->Strings.back() = 0;
+      this->Strings.pop_back();
+    } else {
+      if(this->CInfoVector.back().type == OSB ) {
+       this->ParseObjectList = true;
+      }
+#ifdef __DEBUG
+      std::cout<<"Create new Node with name '"<<(this->Strings.size() == 0 ? "" : this->Strings.back())<<"' !!!"<<std::endl;
+#endif          
+      this->CurrentNode = new vtkJSONInfoNode(this->Strings.size() == 0 ? "" : this->Strings.back());
+      if(!this->ParseObjectList && this->Strings.size() == 1) {
+       this->Strings.pop_back();
+      }
+    }
+  }
+  addInfo(OCB);
+}
+
+//---------------------------------------------------
+vtkJSONMetaNode* vtkJSONParser::GetMetaNode() {
+  vtkJSONMetaNode *mnode = 0;
+  if( this->CurrentNode ) {
+    mnode = dynamic_cast<vtkJSONMetaNode*>(this->CurrentNode);
+  }
+  return mnode;
+}
+
+//---------------------------------------------------
+vtkJSONInfoNode* vtkJSONParser::GetInfoNode() {
+  vtkJSONInfoNode *mnode = 0;
+  if( this->CurrentNode ) {
+    mnode = dynamic_cast<vtkJSONInfoNode*>(this->CurrentNode);
+  }
+  return mnode;
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processENDL() { 
+  if(this->InsideQuotes) {
+
+    throwException("quote is not closed !");
+  }
+  this->LineNumber++;
+  this->ColumnNumber=0;
+}
+
+
+//---------------------------------------------------
+void vtkJSONParser::processCSB() {
+  if (this->InsideQuotes)
+    return;  
+  if(this->CInfoVector.back().type == OSB) {
+    if(this->ParseList) {
+      this->ParseList = false;
+    }    
+    if(this->ParseObjectList) {
+      this->ParseObjectList = false;
+    }
+    this->CInfoVector.pop_back();
+  }
+
+  this->ExpectedCharacters.clear();
+  this->ExpectedCharacters.push_back(COMMA);
+  this->ExpectedCharacters.push_back(OCB);
+  this->ExpectedCharacters.push_back(CCB);
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processOSB() {
+  if (this->InsideQuotes)
+    return;
+
+  if(this->ParseList) {
+    Info i = CInfoVector.back();
+    if(i.type == OSB) {
+      throwException("list, which has been opened in this place, has not been closed !", i.ln, i.cn);
+    }
+  }  
+  if(GetMetaNode()) {
+    this->ParseList = true;
+  } else {
+    if( this->Strings.size() > 0 ) {
+      delete this->Strings[Strings.size()-1];
+      this->Strings[Strings.size()-1] = 0;
+      this->Strings.pop_back();
+    }
+  }
+  addInfo(OSB);
+  this->ExpectedCharacters.clear();
+  this->ExpectedCharacters.push_back(QTS);
+  this->ExpectedCharacters.push_back(OCB);
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processCCB() {
+  if (this->InsideQuotes)
+    return;
+
+  this->ExpectedCharacters.clear();
+  this->ExpectedCharacters.push_back(COMMA);
+  this->ExpectedCharacters.push_back(CCB);
+  if(this->ParseObjectList) {
+    this->ExpectedCharacters.push_back(CSB);
+  }
+
+  processMetaNode();
+  processInfoNode();
+
+  if(this->CurrentNode)
+    this->Nodes.push_back(this->CurrentNode);
+  if( !this->ShortNamesFilled ){
+    vtkJSONInfoNode* n = dynamic_cast<vtkJSONInfoNode*>(this->CurrentNode);
+    if(n){
+      this->ShortNamesFilled = true;
+    }
+  }
+
+#ifdef __DEBUG
+  if(this->CurrentNode)
+    std::cout<<"End parsing node with name '"<<this->CurrentNode->GetName()<<"' !!!!"<<std::endl;
+#endif
+
+  if (this->CInfoVector.size() > 0 && this->CInfoVector.back().type == OCB ) {
+    this->CInfoVector.pop_back();
+  } else{
+    throwException ("unexpected closed braket '}' !");
+  }
+
+  this->CurrentNode = 0;
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processCOMMA() {
+  if (this->InsideQuotes)
+    return;
+  this->ExpectedCharacters.clear();
+  this->ExpectedCharacters.push_back(QTS);
+  this->ExpectedCharacters.push_back(OCB);
+  processMetaNode();
+  processInfoNode();
+}
+
+void vtkJSONParser::processMetaNode() {
+ vtkJSONMetaNode* mn = GetMetaNode();
+  if(mn) {
+    bool strings  = this->Strings.size() == 2 && !this->ParseList;
+    bool str_and_list = (this->Strings.size() == 1 && this->CurrentList.size() > 0 && !this->ParseList);
+    
+    if( strings ) {
+      if ( strcmp(this->Strings[0], CMT) == 0 ) {
+       mn->SetComment(this->Strings[1]);
+#ifdef __DEBUG
+      std::cout<<"Table Comment  : "<<this->Strings[1]<<std::endl;
+#endif
+      } else if ( strcmp(this->Strings[0], TBN) == 0 ) { 
+       mn->SetTableName(this->Strings[1]);
+#ifdef __DEBUG
+      std::cout<<"Table Name  : "<<this->Strings[1]<<std::endl;
+#endif
+      } else if ( strcmp(this->Strings[0], TBD) == 0 ) {
+       mn->SetTableDescription(this->Strings[1]);
+#ifdef __DEBUG
+       std::cout<<"Table Description  : "<<this->Strings[1]<<std::endl;
+#endif
+      } else if ( strcmp(this->Strings[0], DT) == 0 ) {
+       mn->SetDate(this->Strings[1]);
+#ifdef __DEBUG
+      std::cout<<"Date  : "<<this->Strings[1]<<std::endl;
+#endif
+      } else {
+       std::stringstream s;
+       s << "File : "<< this->FileName;
+       s << ", line "<<this->LineNumber;
+       s << " unexpected key world: '"<<this->Strings[0]<<"'";
+      }
+      delete this->Strings[0];
+      this->Strings[0] = 0;
+      Strings.pop_back();
+      Strings.pop_back();
+      
+    } else if(str_and_list) {
+      if ( strcmp(this->Strings[0], SHT) == 0 ) { 
+       std::vector<const char*>::const_iterator it = this->CurrentList.begin();
+       for( ;it != this->CurrentList.end(); it++) {
+         checkShortName(*it);
+       }
+       mn->SetShortNames(this->CurrentList);
+#ifdef __DEBUG
+       std::cout<<"Short Names : "<<std::endl;
+#endif
+      } else if ( strcmp(this->Strings[0], LNG) == 0 ) { 
+       mn->SetLongNames(this->CurrentList);
+#ifdef __DEBUG
+       std::cout<<"Long Names : "<<std::endl;
+#endif
+      } else if ( strcmp(this->Strings[0], UNT) == 0 ) { 
+       mn->SetUnits(this->CurrentList);
+#ifdef __DEBUG
+       std::cout<<"Units : ";
+#endif
+      } else {
+       std::stringstream s;
+       s << "File : "<< this->FileName;
+       s << ", line "<<this->LineNumber;
+       s << " unexpected key world: '"<<this->Strings[0]<<"'";
+      }
+      delete this->Strings[0];
+      this->Strings[0] = 0;
+      Strings.pop_back();
+#ifdef __DEBUG
+      std::vector<const char*>::const_iterator it = this->CurrentList.begin();
+      std::cout<<"[ ";
+      for( ;it != this->CurrentList.end(); it++) {
+        std::cout<<"'"<<*it<<"'";
+       if ( it+1 != this->CurrentList.end() )
+         std::cout<<", ";
+      }
+      std::cout<<" ]"<<std::endl;
+#endif
+      this->CurrentList.clear();
+    }
+  }
+}
+//---------------------------------------------------
+void vtkJSONParser::processInfoNode() { 
+ vtkJSONInfoNode* in = GetInfoNode();
+  if(in) {
+    if(this->Strings.size() == 1 && !isnan(this->LastValue)) {
+      in->AddValue(this->Strings[0],this->LastValue);
+      if(!ShortNamesFilled) {
+       char* name = new char[strlen(Strings[0])];
+       strcpy(name, Strings[0]);
+       this->ShortNames.push_back(name);
+      }
+      this->Strings.pop_back();
+      this->LastValue = NAN;
+    }
+  }
+}
+
+//---------------------------------------------------
+void vtkJSONParser::processCharacter(const char ch) {
+  if (this->InsideQuotes)
+    return;
+  if(isBlankOrEnd(ch))
+    return;
+
+  if(this->ExpectedCharacters.empty())
+    return;
+  
+  std::vector<char>::const_iterator it = std::find(this->ExpectedCharacters.begin(),
+                                                  this->ExpectedCharacters.end(),
+                                                  ch);  
+  
+  // Unexpected character is found
+  if(it == this->ExpectedCharacters.end()) {
+    std::string s("unexpected character '");
+    s+=ch;
+    s+="' !";
+    throwException(s.c_str());
+
+  }
+}
+
+//---------------------------------------------------
+char* vtkJSONParser::getString(long b, long e) {
+  char* result = 0;
+
+  long old_pos = ftell(this->File);
+  fseek(this->File, b, SEEK_SET);
+  long data_s = e - b;
+  result = new char[data_s];
+  result[0] = 0;
+  size_t nb_read = fread(result, sizeof(char), data_s, this->File);  
+  result[nb_read] = '\0';
+  fseek(this->File, old_pos, SEEK_SET);
+  return result;
+}
+
+//---------------------------------------------------
+void vtkJSONParser::allowsDigits() {
+  for(char c = '.'; c <= '9'; c++) {
+    ExpectedCharacters.push_back(c);
+  }
+  ExpectedCharacters.push_back('-');
+  ExpectedCharacters.push_back('+');
+  ExpectedCharacters.push_back('e');
+}
+
+//---------------------------------------------------
+bool vtkJSONParser::isDigitsAllowed() {
+  std::vector<char>::const_iterator it = std::find(this->ExpectedCharacters.begin(),
+                                                  this->ExpectedCharacters.end(),
+                                                  '0');
+  return (it != this->ExpectedCharacters.end());
+}
+
+//---------------------------------------------------
+void vtkJSONParser::readDoubleValue() {
+  long b = ftell(this->File);
+
+  while(1) {
+    char ch = fgetc(this->File); 
+    if(!isDigitOrDot(ch)) {
+      break;
+    }
+  }
+
+  long e = ftell(this->File);
+  fseek(this->File, b-1, SEEK_SET);
+  long data_s = e - b;
+  char* result = new char[data_s];
+  result[0] = 0;
+  size_t nb_read = fread(result, sizeof(char), data_s, this->File);  
+  result[nb_read] = '\0';
+  this->ExpectedCharacters.clear();
+  this->ExpectedCharacters.push_back(COMMA);
+  this->ExpectedCharacters.push_back(CCB);
+  this->LastValue = atof(result);
+#ifdef __DEBUG
+  std::cout<<"Read number : "<<this->LastValue<<std::endl;
+#endif
+}
+
+//---------------------------------------------------
+void vtkJSONParser::checkShortName(const char* name) {
+  size_t ln = strlen(name);
+  if( ln > 0 ){
+    for( size_t i = 0; i < ln; i++ ) { 
+      // a - z
+      if(!(name[i] >= 'a' &&  name[i] <= 'z') && 
+      // A - Z
+        !(name[i] >= 'A' &&  name[i] <= 'Z') ) {
+       std::string s("wrong short name '");
+       s += name;
+       s += "' !";
+       throwException(s.c_str(), this->LineNumber);
+      }
+    }
+  }
+}
+
+void vtkJSONParser::clean() {
+  std::vector<vtkJSONNode*>::iterator it = this->Nodes.begin();
+  for( ; it != this->Nodes.end(); it++ ) {
+    delete *(it);
+    *it = 0;
+  }
+}
+
+//---------------------------------------------------
+void vtkJSONParser::throwException(const char* message) {
+    std::stringstream s;
+    s << "File : "<< this->FileName;
+    s << ", line "<<this->LineNumber;
+    s << ", column " << this->ColumnNumber<<" : ";
+    s << message;
+    clean();
+    throw vtkJSONException(s.str().c_str());  
+}
+
+//---------------------------------------------------
+void vtkJSONParser::throwException(const char* message, int ln, int cn) {
+    std::stringstream s;
+    s << "File : "<< this->FileName;
+    s << ", line "<<ln;
+    s << ", column :" << cn << "  ";
+    s << message;
+    clean();
+    throw vtkJSONException(s.str().c_str());  
+}
+//---------------------------------------------------
+void vtkJSONParser::throwException(const char* message, int ln) {
+  std::stringstream s;
+   s << "File "<< this->FileName;
+   s << ", line "<<ln <<" : ";
+   s << message;
+   clean();
+   throw vtkJSONException(s.str().c_str());  
+}
+
+//---------------------------------------------------
+void vtkJSONParser::throwSimpleException(const char* message) {
+  clean();
+  throw vtkJSONException(message);
+}
diff --git a/src/Plugins/JSONReader/JSONParser/vtkJSONParser.h b/src/Plugins/JSONReader/JSONParser/vtkJSONParser.h
new file mode 100644 (file)
index 0000000..9ebe61e
--- /dev/null
@@ -0,0 +1,173 @@
+//  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Autor: Roman NIKOLAEV (roman.nikolaev@opencascade.com)
+
+#ifndef __vtkJSONParser_h_
+#define __vtkJSONParser_h_
+
+#include <vtkObject.h>
+#include <vector>
+#include <stdio.h>
+#include <exception>
+#include <string> 
+
+
+class vtkTable;
+class vtkJSONNode;
+class vtkJSONMetaNode;
+class vtkJSONInfoNode;
+
+//---------------------------------------------------
+class vtkJSONException : public std::exception {
+ public:
+    vtkJSONException(const char *reason);
+    ~vtkJSONException() throw ();
+    const char* what() const throw();
+ protected:
+  std::string Reason;
+}; 
+
+class vtkJSONParser : public vtkObject
+{
+public:
+  static vtkJSONParser* New();
+
+  // Description:
+  // Specifies the name of the file
+  vtkGetStringMacro(FileName);
+  vtkSetStringMacro(FileName);
+
+  virtual int Parse(vtkTable* theTable);
+
+protected:
+  
+  //Struct to store cursor information
+  //----------------------------------
+  struct Info {
+  public:
+    char type;
+    long ln;
+    long cn;
+    long pos;
+    
+    Info() {
+      type = 0;
+      ln = -1;  
+      cn = -1;
+      pos = -1;
+    }
+  };
+
+  vtkJSONParser();
+  ~vtkJSONParser();
+
+  // name of the file to read from
+  //----------------------------------
+  char* FileName;
+
+  // current line and column
+  //----------------------------------
+  int LineNumber;
+  int ColumnNumber;
+
+  // markup information
+  //----------------------------------
+  std::vector<Info> CInfoVector;
+
+  // file
+  //----------------------------------
+  FILE* File; 
+
+  // Nodes
+  //----------------------------------
+  std::vector<vtkJSONNode*> Nodes;
+  vtkJSONNode*              CurrentNode;  
+  vtkJSONMetaNode*          MetaNode;
+
+  // Nodes
+  //----------------------------------
+  std::vector<char> ExpectedCharacters;
+
+  // Flags
+  //----------------------------------
+  bool InsideQuotes;
+  bool ParseList;
+  bool ParseObjectList;
+  bool ShortNamesFilled;
+
+  // Last parced string
+  //----------------------------------
+  char* LastString;
+  std::vector<const char*> Strings;
+  std::vector<const char*> CurrentList;
+  std::vector<const char*> ShortNames;
+  
+  // Last parced values
+  //----------------------------------  
+  double LastValue; 
+
+private:
+  vtkJSONParser(const vtkJSONParser&); // Not implemented.
+  void operator=(const vtkJSONParser&); // Not implemented.
+
+  vtkJSONMetaNode* GetMetaNode();
+  vtkJSONInfoNode* GetInfoNode();
+
+  void processOCB();
+  void processCCB();
+
+  void processOSB();
+  void processCSB();
+
+  void processCOMMA();
+
+  void processCOLON();
+
+  void processENDL();
+
+  void processQTS();
+
+  void processCharacter(const char ch);
+
+  void processMetaNode();
+  void processInfoNode();
+
+  void readDoubleValue();
+
+  char* getString(long b, long e);
+
+  void allowsDigits();
+
+  bool isDigitsAllowed();
+
+  void checkShortName(const char* unit);
+
+  void finalize(vtkTable *t);
+
+  void clean();
+
+  void throwSimpleException(const char* message);
+
+  void throwException(const char* message);
+
+  void throwException(const char* message, int ln, int cn);
+  
+  void throwException(const char* message, int ln);
+};
+#endif //__vtkJSONParser_h_
diff --git a/src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt b/src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6fd4e2c
--- /dev/null
@@ -0,0 +1,32 @@
+#  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# Author : Roman NIKOLAEV
+
+INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/JSONParser )
+
+ADD_PARAVIEW_PLUGIN(JSONReader "1.0"
+  SERVER_MANAGER_XML JSONReader.xml
+  SERVER_MANAGER_SOURCES vtkJSONReader.cxx
+  REQUIRED_ON_SERVER)
+
+TARGET_LINK_LIBRARIES(JSONReader vtkJSONParser)
+
+INSTALL(TARGETS JSONReader
+  DESTINATION lib/paraview
+)
diff --git a/src/Plugins/JSONReader/ParaViewPlugin/JSONReader.xml b/src/Plugins/JSONReader/ParaViewPlugin/JSONReader.xml
new file mode 100644 (file)
index 0000000..5b35ddd
--- /dev/null
@@ -0,0 +1,27 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="sources">
+    <SourceProxy name="JSONReader" class="vtkJSONReader" label="JSON Reader">
+
+      <Hints>
+         <ReaderFactory extensions="json"
+                        file_description="JSON file" />
+      </Hints>
+
+      <Documentation
+         short_help="Reads JSON file"
+         long_help="Reads JSON file and converts it to the VTK table">
+      </Documentation>
+
+      <StringVectorProperty
+          name="FileName"
+          command="SetFileName"
+          number_of_elements="1"
+          panel_visibility="never">
+          <FileListDomain name="files"/>
+          <Documentation>
+            This property specifies the file name for the JSON reader
+          </Documentation>
+      </StringVectorProperty>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/Plugins/JSONReader/ParaViewPlugin/plugin.cmake b/src/Plugins/JSONReader/ParaViewPlugin/plugin.cmake
new file mode 100644 (file)
index 0000000..4a646ba
--- /dev/null
@@ -0,0 +1,3 @@
+pv_plugin(JSONReader
+  DESCRIPTION "Reads the JSON file and converts it to the VTK table"
+  DEFAULT_ENABLED)
diff --git a/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx b/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx
new file mode 100644 (file)
index 0000000..5a02d46
--- /dev/null
@@ -0,0 +1,96 @@
+//  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author: Roman NIKOLAEV
+
+#include "vtkJSONReader.h"
+#include "vtkJSONParser.h"
+
+#include <vtkObjectFactory.h>
+#include <vtkTable.h>
+#include <vtkInformationVector.h>
+#include <vtkInformation.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkVariantArray.h>
+#include <vtkStringArray.h>
+#include <vtkStringToNumeric.h>
+
+#include <vtksys/stl/stdexcept>
+#include <vtksys/ios/sstream>
+
+vtkStandardNewMacro(vtkJSONReader);
+
+//---------------------------------------------------
+vtkJSONReader::vtkJSONReader()
+{
+  this->SetNumberOfInputPorts(0);
+  this->SetNumberOfOutputPorts(1);
+  this->FileName = NULL;
+  this->Parser = vtkJSONParser::New();
+}
+
+//---------------------------------------------------
+vtkJSONReader::~vtkJSONReader()
+{
+  this->SetFileName(NULL);
+  this->Parser->Delete();
+}
+
+//---------------------------------------------------
+int vtkJSONReader::CanReadFile(const char* fname)
+{
+  return 1;
+}
+
+//---------------------------------------------------
+void vtkJSONReader::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "FileName: " 
+      << (this->FileName ? this->FileName : "(none)") << endl;
+  os << indent << "Parser: "<<this->Parser << endl;
+}
+
+//---------------------------------------------------
+int vtkJSONReader::RequestData(vtkInformation*, 
+    vtkInformationVector**,
+    vtkInformationVector* outputVector)
+{
+  vtkTable* const output_table = vtkTable::GetData(outputVector);
+
+  vtkInformation* const outInfo = outputVector->GetInformationObject(0);
+  if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) &&
+  outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
+  {
+   return 1;
+  }
+
+ // If the filename is not defined
+ if (!this->FileName && !this->Parser)
+   {
+     return 1;
+   }
+
+ this->Parser->SetFileName(this->FileName);
+ try{
+   return this->Parser->Parse(output_table);
+ } catch(vtkJSONException e) {
+   std::cout<<e.what()<<std::endl;
+   return 1;
+ }
+}
diff --git a/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h b/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h
new file mode 100644 (file)
index 0000000..474b7f9
--- /dev/null
@@ -0,0 +1,65 @@
+//  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Autor: Roman NIKOLAEV (roman.nikolaev@opencascade.com)
+
+#ifndef __vtkJSONReader_h_
+#define __vtkJSONReader_h_
+
+#include "vtkTableAlgorithm.h"
+
+class vtkStringArray;
+class vtkJSONParser;
+
+class VTK_EXPORT vtkJSONReader: public vtkTableAlgorithm
+{
+public:
+  static vtkJSONReader* New();
+  vtkTypeMacro(vtkJSONReader, vtkTableAlgorithm)
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Specifies the name of the file
+  vtkGetStringMacro(FileName);
+  vtkSetStringMacro(FileName);
+
+  // Description:
+  // Determine whether the given file can be read
+  virtual int CanReadFile(const char* fname);
+
+  // Description:
+  // Request Data
+  virtual int RequestData(vtkInformation*, 
+                         vtkInformationVector**,
+                         vtkInformationVector*);
+
+
+protected:
+  vtkJSONReader();
+  ~vtkJSONReader();  
+  // name of the file to read from
+  char*            FileName;
+
+  vtkJSONParser*   Parser;
+
+private:
+  vtkJSONReader(const vtkJSONReader&); // Not implemented.
+  void operator=(const vtkJSONReader&); // Not implemented.
+};
+
+#endif //__vtkJSONReader_h_
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex1.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex1.json
new file mode 100644 (file)
index 0000000..ed81300
--- /dev/null
@@ -0,0 +1,32 @@
+a {
+  "_metadata": {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex10.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex10.json
new file mode 100644 (file)
index 0000000..b843902
--- /dev/null
@@ -0,0 +1,31 @@
+{ 
+  "_metadata" : {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex11.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex11.json
new file mode 100644 (file)
index 0000000..7bab6eb
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata" : {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+} 9999
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex2.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex2.json
new file mode 100644 (file)
index 0000000..94606f2
--- /dev/null
@@ -0,0 +1,32 @@
+{ b
+  "_metadata": {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex3.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex3.json
new file mode 100644 (file)
index 0000000..0197d6d
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata: {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex4.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex4.json
new file mode 100644 (file)
index 0000000..6c09987
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata" : c {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex5.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex5.json
new file mode 100644 (file)
index 0000000..6149788
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata" :  {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015",
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex6.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex6.json
new file mode 100644 (file)
index 0000000..c52e556
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata" : {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ,
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex7.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex7.json
new file mode 100644 (file)
index 0000000..8305bcd
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata" : {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": 
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex8.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex8.json
new file mode 100644 (file)
index 0000000..f1c0f85
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata" : {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": "43.5"
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/BadFiles/bad_ex9.json b/src/Plugins/JSONReader/Test/BadFiles/bad_ex9.json
new file mode 100644 (file)
index 0000000..6116f3f
--- /dev/null
@@ -0,0 +1,32 @@
+{ 
+  "_metadata" : {
+      "_comment": "",
+      "table_name": "Short name of the table",
+      "table_description": "A somewhat longer description for the table",
+    
+      "short_names": ["P", "u", "weight" ],
+      "long_names": [ "Pressure", "Velocity", "Total weight" ],
+      "units": [ "Pa", "m/s", "kg" ],
+      "date" : "12/09/2015"
+      },
+    
+   "items": [
+      {
+        "P":3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0,
+        "weight": 43.5
+      },
+      
+      {
+        "P": 3.15,
+        "u": 0.0 0.0,
+        "weight": 43.5
+      }
+   ]
+}
\ No newline at end of file
diff --git a/src/Plugins/JSONReader/Test/CMakeLists.txt b/src/Plugins/JSONReader/Test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..dd0fb21
--- /dev/null
@@ -0,0 +1,35 @@
+#  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+INCLUDE_DIRECTORIES(
+  ${CMAKE_CURRENT_SOURCE_DIR}/../JSONParser
+  ${CPPUNIT_INCLUDE_DIRS}
+)
+
+SET(JSONParserTest_SOURCES
+ JSONParserTest.cxx
+ vtkJSONParserTest.cxx
+ )
+
+ADD_EXECUTABLE(vtkJSONParserTest ${JSONParserTest_SOURCES})
+TARGET_LINK_LIBRARIES(vtkJSONParserTest vtkJSONParser ${CPPUNIT_LIBRARIES})
+ADD_TEST(vtkJSONParserTest vtkJSONParserTest)
+
+
diff --git a/src/Plugins/JSONReader/Test/JSONParserTest.cxx b/src/Plugins/JSONReader/Test/JSONParserTest.cxx
new file mode 100644 (file)
index 0000000..2b55fec
--- /dev/null
@@ -0,0 +1,6 @@
+
+#include "vtkJSONParserTest.hxx"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( vtkJSONParserTest );
+
+#include "MainTest.hxx"
diff --git a/src/Plugins/JSONReader/Test/MainTest.hxx b/src/Plugins/JSONReader/Test/MainTest.hxx
new file mode 100644 (file)
index 0000000..7e08570
--- /dev/null
@@ -0,0 +1,88 @@
+//  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef _MAINTEST_HXX_
+#define _MAINTEST_HXX_
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/TestResultCollector.h>
+#include <cppunit/TextTestProgressListener.h>
+#include <cppunit/BriefTestProgressListener.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/TestRunner.h>
+#include <stdexcept>
+
+#include <iostream>
+#include <fstream>
+
+// ============================================================================
+/*!
+ *  Main program source for Unit Tests with cppunit package does not depend
+ *  on actual tests, so we use the same for all partial unit tests.
+ */
+// ============================================================================
+
+int main(int argc, char* argv[])
+{
+  // --- Create the event manager and test controller
+  CPPUNIT_NS::TestResult controller;
+
+  // ---  Add a listener that colllects test result
+  CPPUNIT_NS::TestResultCollector result;
+  controller.addListener( &result );
+
+  // ---  Add a listener that print dots as test run.
+#ifdef WIN32
+  CPPUNIT_NS::TextTestProgressListener progress;
+#else
+  CPPUNIT_NS::BriefTestProgressListener progress;
+#endif
+  controller.addListener( &progress );      
+
+  // ---  Get the top level suite from the registry
+
+  CPPUNIT_NS::Test *suite =
+    CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest();
+
+  // ---  Adds the test to the list of test to run
+
+  CPPUNIT_NS::TestRunner runner;
+  runner.addTest( suite );
+  runner.run( controller);
+
+  // ---  Print test in a compiler compatible format.
+
+  std::ofstream testFile;
+  testFile.open("UnitTestsResult.txt", std::ios::out |  std::ios::trunc);
+  //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr );
+  CPPUNIT_NS::CompilerOutputter outputter( &result, testFile );
+  outputter.write(); 
+
+  // ---  Run the tests.
+
+  bool wasSucessful = result.wasSuccessful();
+  testFile.close();
+
+  // ---  Return error code 1 if the one of test failed.
+
+  return wasSucessful ? 0 : 1;
+}
+
+#endif
diff --git a/src/Plugins/JSONReader/Test/vtkJSONParserTest.cxx b/src/Plugins/JSONReader/Test/vtkJSONParserTest.cxx
new file mode 100644 (file)
index 0000000..256461f
--- /dev/null
@@ -0,0 +1,164 @@
+//  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+
+#include "vtkJSONParserTest.hxx"
+#include <vtkJSONParser.h>
+
+#include <vtkTable.h>
+#include <vtkVariant.h>
+#include <vtkAbstractArray.h>
+
+#include <iostream>
+#include <sstream>
+#include <stdlib.h>
+
+//---------------------------------------------------
+std::string vtkJSONParserTest::getGoodFilesDir() {
+  char* c =  getenv("PARAVIS_SRC_DIR");
+  std::string s = std::string(c == 0 ? "" : c);
+  if( !s.empty() ) {
+    s+="/src";
+    s+="/Plugins";
+    s+="/JSONReader";
+    s+="/Examples/";
+  }
+  return s;
+}
+
+//---------------------------------------------------
+std::string vtkJSONParserTest::getBadFilesDir() {
+  char* c =  getenv("PARAVIS_SRC_DIR");
+  std::string s = std::string(c == 0 ? "" : c);
+  if( !s.empty() ) {
+    s+="/src";
+    s+="/Plugins";
+    s+="/JSONReader";
+    s+="/Test";
+    s+="/BadFiles";
+    s+="/";
+  }  
+  return s;
+}
+
+//---------------------------------------------------
+void vtkJSONParserTest::testParseBadFiles() {
+  std::string dir = getBadFilesDir();
+  if(dir.empty())
+    CPPUNIT_FAIL("Can't get examples dir !!! ");
+  std::string fn = "bad_ex";
+  
+  // 11 existing files, bad_ex12.json doesn't exists, check exception
+  for(int i = 1; i <=12; i++) {
+    std::string s = dir + fn;
+    std::stringstream convert;
+    convert << i;
+    s += convert.str();
+    s += ".json";
+    vtkJSONParser* Parser = vtkJSONParser::New();
+    vtkTable* table = vtkTable::New();
+    Parser->SetFileName(s.c_str());
+    bool expected_exception_thrown = false;
+    try{
+      Parser->Parse(table);
+    } catch(vtkJSONException e) {
+      expected_exception_thrown = true;
+    }
+    Parser->Delete();
+    table->Delete();
+    if(!expected_exception_thrown) {
+      CPPUNIT_FAIL("Expected exception is not thrown !!! ");
+    }
+  }
+}
+
+//---------------------------------------------------
+void vtkJSONParserTest::testParseGoodFiles() {
+  std::string dir = getGoodFilesDir();
+  if(dir.empty())
+    CPPUNIT_FAIL("Can't get examples dir !!! ");
+  std::string fn = "example";
+  
+  for(int i = 1; i <=2; i++) {
+    std::string s = dir + fn;
+    std::stringstream convert;
+    convert << i;
+    s += convert.str();
+    s += ".json";
+    vtkJSONParser* Parser = vtkJSONParser::New();
+    vtkTable* table = vtkTable::New();
+    Parser->SetFileName(s.c_str());
+    bool exception_thrown = false;
+    try{
+      Parser->Parse(table);
+    } catch(vtkJSONException e) {
+      exception_thrown = true;
+    }
+    Parser->Delete();
+    table->Delete();
+    
+    if(exception_thrown) {
+      CPPUNIT_FAIL("Unexpected exception has been thrown !!! ");
+    }
+  }
+
+  vtkJSONParser* Parser = vtkJSONParser::New();
+  vtkTable* table = vtkTable::New();
+  fn = "example";
+  std::string s = dir + fn;
+  std::stringstream convert;
+  convert << 2;
+  s += convert.str();
+  s += "_wo_metadata.json";
+  Parser->SetFileName(s.c_str());
+  bool exception_thrown = false;
+  try{
+    Parser->Parse(table);
+  } catch(vtkJSONException e) {
+    exception_thrown = true;      
+  }    
+  if(exception_thrown) {
+    CPPUNIT_FAIL("Unexpected exception has been thrown !!! ");
+  }
+
+  double v = table->GetValue(2,0).ToDouble();
+  double v1 = table->GetValue(2,1).ToDouble();
+  double v2 = table->GetValue(2,2).ToDouble();
+
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", 3.15, table->GetValue(0,0).ToDouble(), 0.001);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", 0.0, table->GetValue(0,1).ToDouble(), 0.001);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", 43.5, table->GetValue(0,2).ToDouble(), 0.001);
+
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", 4.156, table->GetValue(1,0).ToDouble(), 0.001);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", 465, table->GetValue(1,1).ToDouble(), 0.001);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", 137.5, table->GetValue(1,2).ToDouble(), 0.001);
+
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", -3.0305890e+4, table->GetValue(2,0).ToDouble(), 0.001);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", 1.0305890e-1, table->GetValue(2,1).ToDouble(), 0.001);
+  CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Unexpected value : ", -3.0305890e+5, table->GetValue(2,2).ToDouble(), 0.001);
+
+  std::string s1 ();
+    
+  CPPUNIT_ASSERT_EQUAL( std::string("P[n/a]"), std::string(table->GetColumn(0)->GetName()));
+  CPPUNIT_ASSERT_EQUAL( std::string("u[n/a]"), std::string(table->GetColumn(1)->GetName()));
+  CPPUNIT_ASSERT_EQUAL( std::string("weight[n/a]"), std::string(table->GetColumn(2)->GetName()));
+  
+  Parser->Delete();
+  table->Delete();
+}
diff --git a/src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx b/src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx
new file mode 100644 (file)
index 0000000..2f89cb4
--- /dev/null
@@ -0,0 +1,40 @@
+//  Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef __VTKJSONPARSERTEST_HXX__
+#define __VTKJSONPARSERTEST_HXX__
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <string.h>
+
+class vtkJSONParserTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE(vtkJSONParserTest);
+    CPPUNIT_TEST( testParseGoodFiles );
+    CPPUNIT_TEST( testParseBadFiles );
+    CPPUNIT_TEST_SUITE_END();
+    
+public:
+    void testParseGoodFiles();
+    void testParseBadFiles();
+private:
+  std::string getGoodFilesDir();
+  std::string getBadFilesDir();
+};
+
+#endif