diff --git a/ejson/Number.cpp b/ejson/Number.cpp index 2bfe781..df71285 100644 --- a/ejson/Number.cpp +++ b/ejson/Number.cpp @@ -18,7 +18,7 @@ bool ejson::Number::IParse(const etk::UString& _data, int32_t& _pos, ejson::file { JSON_PARSE_ELEMENT("start parse : 'Number' "); etk::UString tmpVal; - for (int32_t iii=_pos+1; iii<_data.Size(); iii++) { + for (int32_t iii=_pos; iii<_data.Size(); iii++) { _filePos.Check(_data[iii]); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); diff --git a/ejson/Object.cpp b/ejson/Object.cpp index 124c2f1..c70526d 100644 --- a/ejson/Object.cpp +++ b/ejson/Object.cpp @@ -43,7 +43,13 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file statusParsing_te mode = parseName; etk::UString currentName; JSON_PARSE_ELEMENT("start parse : 'Object' "); - for (int32_t iii=_pos+1; iii<_data.Size(); iii++) { + bool standalone = true; + int32_t startPos = _pos+1; + if (_data[_pos] != '{' ) { // when the main node call it, it can be start with != '{' + standalone = false; + startPos = _pos; + } + for (int32_t iii=startPos; iii<_data.Size(); iii++) { _filePos.Check(_data[iii]); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT DrawElementParsed(_data[iii], _filePos); @@ -193,6 +199,9 @@ bool ejson::Object::IParse(const etk::UString& _data, int32_t& _pos, ejson::file } } _pos = _data.Size(); + if (false==standalone) { + return true; + } return false; } bool ejson::Object::IGenerate(etk::UString& _data, int32_t _indent) const diff --git a/ejson/ejson.cpp b/ejson/ejson.cpp index 867f43e..2824a57 100644 --- a/ejson/ejson.cpp +++ b/ejson/ejson.cpp @@ -21,7 +21,6 @@ #define __class__ "Document" ejson::Document::Document(void) : - m_subElement(NULL), m_writeErrorWhenDetexted(true), m_comment(""), m_Line(""), @@ -32,17 +31,12 @@ ejson::Document::Document(void) : ejson::Document::~Document(void) { - if (NULL!=m_subElement) { - delete m_subElement; - m_subElement=NULL; - } + } bool ejson::Document::IGenerate(etk::UString& _data, int32_t _indent) const { - if (NULL!=m_subElement) { - m_subElement->IGenerate(_data, _indent+1); - } + ejson::Object::IGenerate(_data, _indent+1); _data += "\n"; return true; } @@ -177,7 +171,9 @@ void ejson::Document::CreateError(const etk::UString& _data, int32_t _pos, const bool ejson::Document::IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc) { - JSON_PARSE_ELEMENT("start parse : 'Value' "); + JSON_PARSE_ELEMENT("start parse : 'Document' "); + bool haveMainNode=false; + bool nodeParsed=false; for (int32_t iii=_pos; iii<_data.Size(); iii++) { _filePos.Check(_data[iii]); #ifdef ENABLE_DISPLAY_PARSED_ELEMENT @@ -190,144 +186,40 @@ bool ejson::Document::IParse(const etk::UString& _data, int32_t& _pos, ejson::fi || _data[iii]=='\r') { // white space ==> nothing to do ... } else if (_data[iii]=='{') { - // find an object: - JSON_PARSE_ELEMENT("find Object"); - ejson::Object * tmpElement = new ejson::Object(); - if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in object"); + if (nodeParsed==true) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "element already parsed"); _pos=iii; - return false; } - tmpElement->IParse(_data, iii, _filePos, _doc); - m_subElement = tmpElement; - } else if (_data[iii]=='"') { - // find a string: - JSON_PARSE_ELEMENT("find String quoted"); - ejson::String * tmpElement = new ejson::String(true); - if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in String"); - _pos=iii; - return false; - } - tmpElement->IParse(_data, iii, _filePos, _doc); - m_subElement = tmpElement; - } else if (_data[iii]=='[') { - // find a list: - JSON_PARSE_ELEMENT("find List"); - ejson::Array * tmpElement = new ejson::Array(); - if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Array"); - _pos=iii; - return false; - } - tmpElement->IParse(_data, iii, _filePos, _doc); - m_subElement = tmpElement; - } else if( _data[iii] == 'f' - || _data[iii] == 't' ) { - // find boolean: - JSON_PARSE_ELEMENT("find Boolean"); - ejson::Boolean * tmpElement = new ejson::Boolean(); - if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->IParse(_data, iii, _filePos, _doc); - m_subElement = tmpElement; - } else if( _data[iii] == 'n') { - // find null: - JSON_PARSE_ELEMENT("find Null"); - ejson::Null * tmpElement = new ejson::Null(); - if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->IParse(_data, iii, _filePos, _doc); - m_subElement = tmpElement; - } else if(true==CheckNumber(_data[iii])) { - // find number: - JSON_PARSE_ELEMENT("find Number"); - ejson::Number * tmpElement = new ejson::Number(); - if (NULL==tmpElement) { - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Allocation error in Boolean"); - _pos=iii; - return false; - } - tmpElement->IParse(_data, iii, _filePos, _doc); - m_subElement = tmpElement; + // find a main object: + // ==> generic sub parsing + iii++; + haveMainNode=true; + nodeParsed=true; + ejson::Object::IParse(_data, iii, _filePos, _doc); } else if(_data[iii]=='}') { - // find end of value: _pos=iii; // ==> return the end element type ==> usefull to check end and check if adding element is needed - return true; + if (haveMainNode==true) { + // find end of value: + return true; + } else { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "find } but never start !!!"); + return false; + } } else { - // find an error .... - EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, etk::UString("Find '") + _data[iii] + "' with no element in the element..."); - // move the curent index - _pos = iii+1; - return false; + if (nodeParsed==true) { + _pos=iii; + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "element already parsed"); + return false; + } + nodeParsed=true; + // this might not have the '{' start element !!! + if (false==ejson::Object::IParse(_data, iii, _filePos, _doc)) { + EJSON_CREATE_ERROR(_doc, _data, iii, _filePos, "Object sub parsing in error"); + _pos = iii; + return false; + } } } return true; } - -ejson::Value* ejson::Document::GetSub(const etk::UString& _named) const -{ - if (m_subElement == NULL) { - return NULL; - } - ejson::Object* tmp = m_subElement->ToObject(); - if (NULL==tmp) { - return NULL; - } - return tmp->GetSub(_named); -} - -ejson::Object* ejson::Document::GetSubObject(const etk::UString& _named) const -{ - ejson::Value* tmp = GetSub(_named); - if (NULL == tmp) { - return NULL; - } - return tmp->ToObject(); -} - -ejson::String* ejson::Document::GetSubString(const etk::UString& _named) const -{ - ejson::Value* tmp = GetSub(_named); - if (NULL == tmp) { - return NULL; - } - return tmp->ToString(); -} - -ejson::Array* ejson::Document::GetSubArray(const etk::UString& _named) const -{ - ejson::Value* tmp = GetSub(_named); - if (NULL == tmp) { - return NULL; - } - return tmp->ToArray(); -} - - -bool ejson::Document::SetSub(ejson::Value* _value) -{ - if (NULL == _value) { - return false; - } - if (NULL!=m_subElement) { - delete(m_subElement); - } - m_subElement = _value; - return true; -} - -void ejson::Document::Clear(void) -{ - if (NULL!=m_subElement) { - delete(m_subElement); - m_subElement=NULL; - } -} diff --git a/ejson/ejson.h b/ejson/ejson.h index 40d0f67..a007230 100644 --- a/ejson/ejson.h +++ b/ejson/ejson.h @@ -19,7 +19,7 @@ namespace ejson { - class Document : public ejson::Value + class Document : public ejson::Object { public: /** @@ -63,14 +63,6 @@ namespace ejson * @brief Display the Document on console */ void Display(void); - private: - ejson::Value* m_subElement; //!< only element that contain the json document: - public: - ejson::Value* GetSub(const etk::UString& _named) const; - ejson::Object* GetSubObject(const etk::UString& _named) const; - ejson::String* GetSubString(const etk::UString& _named) const; - ejson::Array* GetSubArray(const etk::UString& _named) const; - bool SetSub(ejson::Value* _value); private: bool m_writeErrorWhenDetexted; etk::UString m_comment; @@ -84,11 +76,10 @@ namespace ejson void DisplayError(void); public: // herited function: virtual nodeType_te GetType(void) const { return typeDocument; }; - bool IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); - bool IGenerate(etk::UString& _data, int32_t _indent) const; + virtual bool IParse(const etk::UString& _data, int32_t& _pos, ejson::filePos& _filePos, ejson::Document& _doc); + virtual bool IGenerate(etk::UString& _data, int32_t _indent) const; virtual ejson::Document* ToDocument(void) { return this; }; virtual const ejson::Document* ToDocument(void) const { return this; }; - virtual void Clear(void); }; }; diff --git a/ejson/test.cpp b/ejson/test.cpp index 25de61f..1257382 100644 --- a/ejson/test.cpp +++ b/ejson/test.cpp @@ -52,6 +52,102 @@ void Init(void) -1, "{ \t\r }\n"); l_list.PushBack(check); + // ====================================================== + check.Set("test ejson::null", -2, ""); + l_list.PushBack(check); + // ------------------------------------------------------ + reference = "{\n\t\"tmpElement\": null\n}\n"; + check.Set(reference, + -1, + "{ tmpElement:null }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "{ \t\ntmpElement:null \t\n }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "tmpElement:null\n"); + l_list.PushBack(check); + // ====================================================== + check.Set("test ejson::boolean", -2, ""); + l_list.PushBack(check); + // ------------------------------------------------------ + reference = "{\n\t\"tmpElement\": true\n}\n"; + check.Set(reference, + -1, + "{ tmpElement:true }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "{ \t\ntmpElement:true \t\n }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "tmpElement:true\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + reference = "{\n\t\"tmpElement\": false\n}\n"; + check.Set(reference, + -1, + "{ tmpElement:false }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "{ \t\ntmpElement:false \t\n }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "tmpElement:false\n"); + l_list.PushBack(check); + // ====================================================== + check.Set("test ejson::number", -2, ""); + l_list.PushBack(check); + // ------------------------------------------------------ + reference = "{\n\t\"tmpElement\": 956256.000000\n}\n"; + check.Set(reference, + -1, + "{ tmpElement:956256 }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "{ \t\ntmpElement:956256 \t\n }\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set(reference, + -1, + "tmpElement:956256\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("{\n\t\"tmpElement\": 956256.000000\n}\n", + -1, + "{tmpElement:956256}\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("{\n\t\"tmpElement\": -956256.000000\n}\n", + -1, + "{tmpElement:-956256}\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("{\n\t\"tmpElement\": -956256.000000\n}\n", + -1, + "{tmpElement:-956256}\n"); + l_list.PushBack(check); + // ------------------------------------------------------ + check.Set("{\n\t\"tmpElement\": -956.256000\n}\n", + -1, + "{tmpElement:-956.256}\n"); + l_list.PushBack(check); + + + // ====================================================== check.Set("test ejson::all", -2, ""); l_list.PushBack(check); @@ -104,29 +200,28 @@ void Init(void) reference); l_list.PushBack(check); // ------------------------------------------------------ - /* check.Set(reference, -1, - "{\n" + "{\n" " menu: {\n" - " id: file,\n" - " value: File,\n" + " id: \"file\",\n" + " value: \"File\",\n" " popup: {\n" " menuitem: [\n" " {\n" - " value: Close,\n" + " value: \"Close\",\n" " onclick: \"CloseDoc()\"\n" " },\n" " {\n" - " value: New,\n" + " value: \"New\",\n" " onclick: \"CreateNewDoc()\"\n" " },\n" " {\n" - " value: Open,\n" + " value: \"Open\",\n" " onclick: \"OpenDoc()\"\n" " },\n" " {\n" - " value: Close,\n" + " value: \"Close\",\n" " onclick: \"CloseDoc()\"\n" " }\n" " ]\n" @@ -134,7 +229,234 @@ void Init(void) " }\n" "}\n"); l_list.PushBack(check); - */ + // ------------------------------------------------------ + check.Set(reference, + -1, + "menu: {\n" + " id: \"file\",\n" + " value: \"File\",\n" + " popup: {\n" + " menuitem: [\n" + " {\n" + " value: \"Close\",\n" + " onclick: \"CloseDoc()\"\n" + " },\n" + " {\n" + " value: \"New\",\n" + " onclick: \"CreateNewDoc()\"\n" + " },\n" + " {\n" + " value: \"Open\",\n" + " onclick: \"OpenDoc()\"\n" + " },\n" + " {\n" + " value: \"Close\",\n" + " onclick: \"CloseDoc()\"\n" + " }\n" + " ]\n" + " }\n" + "}\n"); + l_list.PushBack(check); + +////////////////////////////////////////////////////////////////////////// + " + { + \"glossary\": { + \"title\": \"example glossary\", + \"GlossDiv\": { + \"title\": \"S\", + \"GlossList\": { + \"GlossEntry\": { + \"ID\": \"SGML\", + \"SortAs\": \"SGML\", + \"GlossTerm\": \"Standard Generalized Markup Language\", + \"Acronym\": \"SGML\", + \"Abbrev\": \"ISO 8879:1986\", + \"GlossDef\": { + \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\", + \"GlossSeeAlso\": [\"GML\", \"XML\"] + }, + \"GlossSee\": \"markup\" + } + } + } + } +} +" +////////////////////////////////////////////////////////////////////////// +" +{\"menu\": { + \"id\": \"file\", + \"value\": \"File\", + \"popup\": { + \"menuitem\": [ + {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"}, + {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"}, + {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"} + ] + } +}} +" +////////////////////////////////////////////////////////////////////////// +" +{\"widget\": { + \"debug\": \"on\", + \"window\": { + \"title\": \"Sample Konfabulator Widget\", + \"name\": \"main_window\", + \"width\": 500, + \"height\": 500 + }, + \"image\": { + \"src\": \"Images/Sun.png\", + \"name\": \"sun1\", + \"hOffset\": 250, + \"vOffset\": 250, + \"alignment\": \"center\" + }, + \"text\": { + \"data\": \"Click Here\", + \"size\": 36, + \"style\": \"bold\", + \"name\": \"text1\", + \"hOffset\": 250, + \"vOffset\": 100, + \"alignment\": \"center\", + \"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\" + } +}} +" + +////////////////////////////////////////////////////////////////////////// + + + + +" +{\"web-app\": { + \"servlet\": [ + { + \"servlet-name\": \"cofaxCDS\", + \"servlet-class\": \"org.cofax.cds.CDSServlet\", + \"init-param\": { + \"configGlossary:installationAt\": \"Philadelphia, PA\", + \"configGlossary:adminEmail\": \"ksm@pobox.com\", + \"configGlossary:poweredBy\": \"Cofax\", + \"configGlossary:poweredByIcon\": \"/images/cofax.gif\", + \"configGlossary:staticPath\": \"/content/static\", + \"templateProcessorClass\": \"org.cofax.WysiwygTemplate\", + \"templateLoaderClass\": \"org.cofax.FilesTemplateLoader\", + \"templatePath\": \"templates\", + \"templateOverridePath\": \"\", + \"defaultListTemplate\": \"listTemplate.htm\", + \"defaultFileTemplate\": \"articleTemplate.htm\", + \"useJSP\": false, + \"jspListTemplate\": \"listTemplate.jsp\", + \"jspFileTemplate\": \"articleTemplate.jsp\", + \"cachePackageTagsTrack\": 200, + \"cachePackageTagsStore\": 200, + \"cachePackageTagsRefresh\": 60, + \"cacheTemplatesTrack\": 100, + \"cacheTemplatesStore\": 50, + \"cacheTemplatesRefresh\": 15, + \"cachePagesTrack\": 200, + \"cachePagesStore\": 100, + \"cachePagesRefresh\": 10, + \"cachePagesDirtyRead\": 10, + \"searchEngineListTemplate\": \"forSearchEnginesList.htm\", + \"searchEngineFileTemplate\": \"forSearchEngines.htm\", + \"searchEngineRobotsDb\": \"WEB-INF/robots.db\", + \"useDataStore\": true, + \"dataStoreClass\": \"org.cofax.SqlDataStore\", + \"redirectionClass\": \"org.cofax.SqlRedirection\", + \"dataStoreName\": \"cofax\", + \"dataStoreDriver\": \"com.microsoft.jdbc.sqlserver.SQLServerDriver\", + \"dataStoreUrl\": \"jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon\", + \"dataStoreUser\": \"sa\", + \"dataStorePassword\": \"dataStoreTestQuery\", + \"dataStoreTestQuery\": \"SET NOCOUNT ON;select test='test';\", + \"dataStoreLogFile\": \"/usr/local/tomcat/logs/datastore.log\", + \"dataStoreInitConns\": 10, + \"dataStoreMaxConns\": 100, + \"dataStoreConnUsageLimit\": 100, + \"dataStoreLogLevel\": \"debug\", + \"maxUrlLength\": 500}}, + { + \"servlet-name\": \"cofaxEmail\", + \"servlet-class\": \"org.cofax.cds.EmailServlet\", + \"init-param\": { + \"mailHost\": \"mail1\", + \"mailHostOverride\": \"mail2\"}}, + { + \"servlet-name\": \"cofaxAdmin\", + \"servlet-class\": \"org.cofax.cds.AdminServlet\"}, + + { + \"servlet-name\": \"fileServlet\", + \"servlet-class\": \"org.cofax.cds.FileServlet\"}, + { + \"servlet-name\": \"cofaxTools\", + \"servlet-class\": \"org.cofax.cms.CofaxToolsServlet\", + \"init-param\": { + \"templatePath\": \"toolstemplates/\", + \"log\": 1, + \"logLocation\": \"/usr/local/tomcat/logs/CofaxTools.log\", + \"logMaxSize\": \"\", + \"dataLog\": 1, + \"dataLogLocation\": \"/usr/local/tomcat/logs/dataLog.log\", + \"dataLogMaxSize\": \"\", + \"removePageCache\": \"/content/admin/remove?cache=pages&id=\", + \"removeTemplateCache\": \"/content/admin/remove?cache=templates&id=\", + \"fileTransferFolder\": \"/usr/local/tomcat/webapps/content/fileTransferFolder\", + \"lookInContext\": 1, + \"adminGroupID\": 4, + \"betaServer\": true}}], + \"servlet-mapping\": { + \"cofaxCDS\": \"/\", + \"cofaxEmail\": \"/cofaxutil/aemail/*\", + \"cofaxAdmin\": \"/admin/*\", + \"fileServlet\": \"/static/*\", + \"cofaxTools\": \"/tools/*\"}, + + \"taglib\": { + \"taglib-uri\": \"cofax.tld\", + \"taglib-location\": \"/WEB-INF/tlds/cofax.tld\"}}} + +" +////////////////////////////////////////////////////////////////////////// + +" +{\"menu\": { + \"header\": \"SVG Viewer\", + \"items\": [ + {\"id\": \"Open\"}, + {\"id\": \"OpenNew\", \"label\": \"Open New\"}, + null, + {\"id\": \"ZoomIn\", \"label\": \"Zoom In\"}, + {\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"}, + {\"id\": \"OriginalView\", \"label\": \"Original View\"}, + null, + {\"id\": \"Quality\"}, + {\"id\": \"Pause\"}, + {\"id\": \"Mute\"}, + null, + {\"id\": \"Find\", \"label\": \"Find...\"}, + {\"id\": \"FindAgain\", \"label\": \"Find Again\"}, + {\"id\": \"Copy\"}, + {\"id\": \"CopyAgain\", \"label\": \"Copy Again\"}, + {\"id\": \"CopySVG\", \"label\": \"Copy SVG\"}, + {\"id\": \"ViewSVG\", \"label\": \"View SVG\"}, + {\"id\": \"ViewSource\", \"label\": \"View Source\"}, + {\"id\": \"SaveAs\", \"label\": \"Save As\"}, + null, + {\"id\": \"Help\"}, + {\"id\": \"About\", \"label\": \"About Adobe CVG Viewer...\"} + ] +}} +" +////////////////////////////////////////////////////////////////////////// + + } int main(int argc, const char *argv[])