diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index 354e767..c3cce76 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -8,7 +8,6 @@ // Standard C/C++ Libraries #include #include -#include // redA Libraries #include "JSONparseCore.h" @@ -49,10 +48,54 @@ bool CJSONparse::SetBase( CDataMember * Object ) } //--------------------------------------------------------------------------- +bool CJSONparse::WriteToString( const char * BasePath, char * TargetStr, int &MaxLen, const int Indent ) +{ + CDataMember * Member; + + // Validate + if (!DataTree) { + Error = true; + sprintf( ErrorText, "No Data Tree set" ); + MaxLen = 0; + return false; + } + + // Prepare Output + if (!TargetStr) { + Error = true; + sprintf( ErrorText, "Could not write to String" ); + MaxLen = 0; + return false; + } + OutputStr = TargetStr; + OutputMaxLen = MaxLen; + OutputPos = 0; + Print = JSONstrOutput; + + // Get Root object + if (!(Member = DataTree->GetChild( BasePath ))) { + Error = true; + sprintf( ErrorText, "Invalid root object path" ); + MaxLen = 0; + return false; + } + + // Print to file + if (!PrintObject( Member, Indent ) || + (Print( this, "\n", 1 ) < 0)) { + MaxLen = 0; + return false; + } + + MaxLen = OutputPos; + return true; +} +//--------------------------------------------------------------------------- + bool CJSONparse::WriteToScreen( const char * BasePath, const int Indent ) { // Print to screen - WriteToHandle( BasePath, 1, Indent ); + WriteToHandle( BasePath, STDOUT_FILENO, Indent ); return true; } @@ -133,6 +176,7 @@ bool CJSONparse::WriteToHandle( const char * BasePath, const int Handle, const i return false; } OutputHandle = Handle; + Print = JSONfileOutput; // Get Root object if (!(Member = DataTree->GetChild( BasePath ))) { @@ -144,7 +188,7 @@ bool CJSONparse::WriteToHandle( const char * BasePath, const int Handle, const i // Print to file if (!PrintObject( Member, Indent ) || - (write( OutputHandle, "\n", 1 ) < 0)) { + (Print( this, "\n", 1 ) < 0)) { OutputHandle = -1; return false; } @@ -759,9 +803,10 @@ bool CJSONparse::ParsePrimitive( CDataMember * Member ) bool CJSONparse::PrintString( char * String, int Len ) { int BytesWritten = 0; + char TempBuf[7] = ""; // Start quote - if (write( OutputHandle, "\"", 1 ) < 0) + if (Print( this, "\"", 1 ) < 0) return false; // Content @@ -774,7 +819,7 @@ bool CJSONparse::PrintString( char * String, int Len ) BufPos++; // Print Portion - if (write( OutputHandle, Mark, (BufPos-Mark) ) < 0) + if (Print( this, Mark, (BufPos-Mark) ) < 0) return false; // Handle special chars @@ -783,16 +828,17 @@ bool CJSONparse::PrintString( char * String, int Len ) } else { switch (*BufPos) { - case '\b': BytesWritten = write( OutputHandle, "\\b", 2 ); break; - case '\f': BytesWritten = write( OutputHandle, "\\f", 2 ); break; - case '\n': BytesWritten = write( OutputHandle, "\\n", 2 ); break; - case '\r': BytesWritten = write( OutputHandle, "\\r", 2 ); break; - case '\t': BytesWritten = write( OutputHandle, "\\t", 2 ); break; - case '/': BytesWritten = write( OutputHandle, "\\/", 2 ); break; - case '\\': BytesWritten = write( OutputHandle, "\\\\", 2 ); break; - case '"': BytesWritten = write( OutputHandle, "\\\"", 2 ); break; + case '\b': BytesWritten = Print( this, "\\b", 2 ); break; + case '\f': BytesWritten = Print( this, "\\f", 2 ); break; + case '\n': BytesWritten = Print( this, "\\n", 2 ); break; + case '\r': BytesWritten = Print( this, "\\r", 2 ); break; + case '\t': BytesWritten = Print( this, "\\t", 2 ); break; + case '/': BytesWritten = Print( this, "\\/", 2 ); break; + case '\\': BytesWritten = Print( this, "\\\\", 2 ); break; + case '"': BytesWritten = Print( this, "\\\"", 2 ); break; default: - BytesWritten = dprintf( OutputHandle, "\\u%04X", (unsigned char)*BufPos ); + BytesWritten = sprintf( TempBuf, "\\u%04X", (unsigned char)*BufPos ); + Print( this, TempBuf, 6 ); break; } if (BytesWritten < 0) @@ -802,7 +848,7 @@ bool CJSONparse::PrintString( char * String, int Len ) } // End Quote - if (write( OutputHandle, "\"", 1 ) < 0) + if (Print( this, "\"", 1 ) < 0) return false; return true; @@ -817,12 +863,12 @@ bool CJSONparse::PrintObject( CDataMember * Object, const int Indent ) int Count = 0; // Opening brace - if (write( OutputHandle, "{", 1 ) < 0) + if (Print( this, "{", 1 ) < 0) return false; // Check if empty if (Object->Len == 0) { - if (write( OutputHandle, "}", 1 ) < 0) + if (Print( this, "}", 1 ) < 0) return false; return true; } @@ -841,10 +887,10 @@ bool CJSONparse::PrintObject( CDataMember * Object, const int Indent ) if (Indent) { if (First) { First = false; - if (write( OutputHandle, "\n", 1 ) < 0) + if (Print( this, "\n", 1 ) < 0) return false; } - if (write( OutputHandle, Spacer, SpacerLen ) < 0) + if (Print( this, Spacer, SpacerLen ) < 0) return false; } @@ -852,10 +898,10 @@ bool CJSONparse::PrintObject( CDataMember * Object, const int Indent ) if (!PrintString( Member->Name, strlen(Member->Name) )) return false; if (Indent) { - if (write( OutputHandle," : ", 3 ) < 0) + if (Print( this, " : ", 3 ) < 0) return false; } else { - if (write( OutputHandle, ":", 1 ) < 0) + if (Print( this, ":", 1 ) < 0) return false; } @@ -864,24 +910,24 @@ bool CJSONparse::PrintObject( CDataMember * Object, const int Indent ) switch (Member->Type) { case jtNull : - if (write( OutputHandle, "null", 4 ) < 0) + if (Print( this, "null", 4 ) < 0) return false; break; case jtBool : if (!strcmp( Member->Value, "0" )) { - if (write( OutputHandle, "false", 5 ) < 0) + if (Print( this, "false", 5 ) < 0) return false; } else { - if (write( OutputHandle, "true", 4 ) < 0) + if (Print( this, "true", 4 ) < 0) return false; } break; case jtInt : case jtFloat : - if (write( OutputHandle, Member->Value, Member->Len ) < 0) + if (Print( this, Member->Value, Member->Len ) < 0) return false; break; @@ -901,11 +947,11 @@ bool CJSONparse::PrintObject( CDataMember * Object, const int Indent ) break; } if (!Last) { - if (write( OutputHandle, ",", 1 ) < 0) + if (Print( this, ",", 1 ) < 0) return false; } if (Indent) { - if (write( OutputHandle, "\n", 1 ) < 0) + if (Print( this, "\n", 1 ) < 0) return false; } } @@ -918,10 +964,10 @@ bool CJSONparse::PrintObject( CDataMember * Object, const int Indent ) // Closing brace if (Indent) { - if (write( OutputHandle, Spacer, SpacerLen ) < 0) + if (Print( this, Spacer, SpacerLen ) < 0) return false; } - if (write( OutputHandle, "}", 1 ) < 0) + if (Print( this, "}", 1 ) < 0) return false; return true; } @@ -935,12 +981,12 @@ bool CJSONparse::PrintArray( CDataMember * Array, const int Indent ) int Count = 0; // Opening brace - if (write( OutputHandle, "[", 1 ) < 0) + if (Print( this, "[", 1 ) < 0) return false; // Check if empty if (Array->Len == 0) { - if (write( OutputHandle, "]", 1 ) < 0) + if (Print( this, "]", 1 ) < 0) return false; return true; } @@ -959,10 +1005,10 @@ bool CJSONparse::PrintArray( CDataMember * Array, const int Indent ) if (Indent) { if (First) { First = false; - if (write( OutputHandle, "\n", 1 ) < 0) + if (Print( this, "\n", 1 ) < 0) return false; } - if (write( OutputHandle, Spacer, SpacerLen ) < 0) + if (Print( this, Spacer, SpacerLen ) < 0) return false; } @@ -970,21 +1016,21 @@ bool CJSONparse::PrintArray( CDataMember * Array, const int Indent ) switch (Member->Type) { case jtNull : - if (write( OutputHandle, "null", 4 ) < 0) + if (Print( this, "null", 4 ) < 0) return false; break; case jtBool : case jtInt : case jtFloat : - if (write( OutputHandle, Member->Value, Member->Len ) < 0) + if (Print( this, Member->Value, Member->Len ) < 0) return false; break; case jtString : - if ((write( OutputHandle, "\"", 1 ) < 0) || - (write( OutputHandle, Member->Value, Member->Len ) < 0) || - (write( OutputHandle, "\"", 1 ) < 0)) + if ((Print( this, "\"", 1 ) < 0) || + (Print( this, Member->Value, Member->Len ) < 0) || + (Print( this, "\"", 1 ) < 0)) return false; break; @@ -999,11 +1045,11 @@ bool CJSONparse::PrintArray( CDataMember * Array, const int Indent ) break; } if (!Last) { - if (write( OutputHandle, ",", 1 ) < 0) + if (Print( this, ",", 1 ) < 0) return false; } if (Indent) { - if (write( OutputHandle, "\n", 1 ) < 0) + if (Print( this, "\n", 1 ) < 0) return false; } } @@ -1016,12 +1062,11 @@ bool CJSONparse::PrintArray( CDataMember * Array, const int Indent ) // Closing brace if (Indent) { - if (write( OutputHandle, Spacer, SpacerLen ) < 0) + if (Print( this, Spacer, SpacerLen ) < 0) return false; } - if (write( OutputHandle, "]", 1 ) < 0) + if (Print( this, "]", 1 ) < 0) return false; return true; } //--------------------------------------------------------------------------- - diff --git a/JSONparseCore.h b/JSONparseCore.h index e2ce0f4..e777eab 100644 --- a/JSONparseCore.h +++ b/JSONparseCore.h @@ -11,6 +11,7 @@ // Standard C/C++ Libraries #include #include +#include // redA Libraries #include "DataTreeCore.h" @@ -18,14 +19,26 @@ //--------------------------------------------------------------------------- +// Pointer template for File/String Output functions +class CJSONparse; +inline ssize_t JSONstrOutput( CJSONparse * JSONparse, const char * Data, size_t Len ); +inline ssize_t JSONfileOutput( CJSONparse * JSONparse, const char * Data, size_t Len ); + +typedef ssize_t (*FOutput)( CJSONparse * JSONparse, const char * Data, size_t Len ); + +//--------------------------------------------------------------------------- + class CJSONparse { -private: +protected: CDataMember * DataTree = NULL; // File operation - int InputHandle = -1; - int OutputHandle = -1; + int InputHandle = -1; + int OutputHandle = -1; + char * OutputStr = NULL; + size_t OutputMaxLen = 0; + size_t OutputPos = 0; CShiftBuffer * Buffer = NULL; @@ -37,6 +50,7 @@ private: bool RefillBuffer = false; // Printing Operation + FOutput Print = NULL; char Spacer[100] = ""; int SpacerLen = 0; @@ -77,12 +91,33 @@ public: bool ReadFromFile( const char * BasePath, const char * FilePath ); // Output + bool WriteToString( const char * BasePath, char * TargetStr, int &MaxLen, const int Indent = 0 ); bool WriteToHandle( const char * BasePath, const int Handle, const int Indent = 2 ); bool WriteToScreen( const char * BasePath, const int Indent = 2 ); bool WriteToFile( const char * BasePath, const char * Path, const char * FileName, const int Indent = 2 ); bool WriteToFile( const char * BasePath, const char * FilePath, const int Indent = 2 ); const char * GetError() { return ((Error)? ErrorText : "Success"); }; + + friend inline ssize_t JSONstrOutput( CJSONparse * JSONparse, const char * Data, size_t Len ); + friend inline ssize_t JSONfileOutput( CJSONparse * JSONparse, const char * Data, size_t Len ); }; +//--------------------------------------------------------------------------- + +inline ssize_t JSONstrOutput( CJSONparse * JSONparse, const char * Data, size_t Len ) +{ + if (JSONparse->OutputPos + Len > JSONparse->OutputMaxLen) return -1; + memcpy( &JSONparse->OutputStr[JSONparse->OutputPos], Data, Len ); + JSONparse->OutputPos += Len; + JSONparse->OutputStr[JSONparse->OutputPos] = 0; + return Len; +} +//--------------------------------------------------------------------------- + +inline ssize_t JSONfileOutput( CJSONparse * JSONparse, const char * Data, size_t Len ) +{ + return write( JSONparse->OutputHandle, Data, Len ); +} +//--------------------------------------------------------------------------- #endif /* REDACORE_JSONPARSECORE_H_ */