Important Update:

- JSONparseCore:
  - Implement output to string
  - Added method WriteToString()
  - Create function pointers which is selected for correct output:
    JSONstrOutput or JSONfileOutput -> Print()
  - Replace all write() statements with Print() statements
  - Modify PrintStr not use dprintf, but sprintf to temp buffer
This commit is contained in:
Charl Wentzel
2019-04-07 10:25:44 +02:00
parent 7acdd8f704
commit f20a9a676f
2 changed files with 126 additions and 46 deletions

View File

@@ -8,7 +8,6 @@
// Standard C/C++ Libraries
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
// 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;
}
//---------------------------------------------------------------------------

View File

@@ -11,6 +11,7 @@
// Standard C/C++ Libraries
#include <string.h>
#include <ctype.h>
#include <unistd.h>
// 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;
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_ */