Important update:

- Buffer:
  - fix undefined value: zero terminate buffer when loading from FD
- DataTree:
  - fix memory leak: destroy temporary search path
  - improve delete(): delete all children for member if no path given
  - bug fix: initiate object with 0 length (not -1)
- JSONparse:
  - Remove level parameter
  - Add path to load/save/print methods (print only portion of tree)
  - fix memory leak: destroy temporary object name
This commit is contained in:
Charl Wentzel
2017-03-29 21:27:28 +02:00
parent 5691b22df9
commit 8f39adb0f3
4 changed files with 131 additions and 70 deletions

View File

@@ -807,6 +807,9 @@ int CShiftBuffer::ReadFromFD( int Handle, int MaxRead )
DataRemain -= BytesRead; DataRemain -= BytesRead;
TotalRead += BytesRead; TotalRead += BytesRead;
BufLen += BytesRead; BufLen += BytesRead;
// Zero terminate
Buffer[BufLen] = 0;
} }
return TotalRead; return TotalRead;
} }

View File

@@ -239,6 +239,9 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
Member = *Child; Member = *Child;
} }
// Destroy temp path
free( WorkPath );
return Child; return Child;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -258,16 +261,26 @@ bool CDataTree::Delete( TDataMember * BaseMember, const char * Path )
TDataMember * Parent; TDataMember * Parent;
TDataMember ** Member; TDataMember ** Member;
// Check if exists // Validate
if (!(Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) { if (!BaseMember && (!Path || !*Path)) {
return false; return false;
} }
// Destroy if (!Path || !*Path) {
// No path - destroy value
DestroyValue( BaseMember );
return true;
}
else if ((Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) {
// If valid path, destroy member
DestroyMember( Member ); DestroyMember( Member );
Parent->Len--; Parent->Len--;
return true; return true;
} }
else {
return false;
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CDataTree::DeleteAll() bool CDataTree::DeleteAll()
@@ -323,7 +336,7 @@ bool CDataTree::SetValue( TDataMember * Member, EDataType Type, const char * Va
} }
else { else {
// Set null value // Set null value
SetValuePtr( Member, Type, NULL, -1 ); SetValuePtr( Member, Type, NULL, 0 );
} }
return true; return true;
} }

View File

@@ -28,7 +28,6 @@ CJSONparse::CJSONparse( CDataTree * pDataTree )
Buffer = NULL; Buffer = NULL;
BufEnd = NULL; BufEnd = NULL;
Level = 0;
// Parsing operation // Parsing operation
BufPos = NULL; BufPos = NULL;
@@ -54,10 +53,100 @@ CJSONparse::~CJSONparse()
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CJSONparse::LoadFromFile( const char * FilePath, int pBufLen ) bool CJSONparse::PrintToScreen( const char * RootPath, const int Indent )
{
TDataMember * RootObject;
// Validate
if (!DataTree) {
return false;
}
// Set to StdOut
OutputHandle = 1;
// Get Root object
if (!RootPath || !*RootPath) {
RootObject = DataTree->GetRootMember();
}
else if (!(RootObject = DataTree->GetMember( NULL, RootPath ))) {
Error = true;
sprintf( ErrorText, "Invalid root object path" );
return false;
}
// Print key name
if (RootObject->Name) {
write( OutputHandle, "\"", 1 );
write( OutputHandle, RootObject->Name, strlen(RootObject->Name) );
write( OutputHandle, "\" : ", 4 );
}
// Print to screen
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return true;
}
//---------------------------------------------------------------------------
bool CJSONparse::SaveToFile( const char * RootPath, const char * FilePath, const int Indent )
{
TDataMember * RootObject;
// Validate
if (!DataTree) {
return false;
}
// Clear Error
Error = false;
// Validate
if (!FilePath || !FilePath[0]) {
Error = true;
sprintf( ErrorText, "No File path specified" );
return false;
}
// Open file
if (!(OutputHandle = open( FilePath, O_CREAT|O_WRONLY|O_TRUNC ))) {
Error = true;
sprintf( ErrorText, "Could not open file" );
return false;
}
// Get Root object
if (!RootPath || !*RootPath) {
RootObject = DataTree->GetRootMember();
}
else if (!(RootObject = DataTree->GetMember( NULL, RootPath ))) {
Error = true;
sprintf( ErrorText, "Invalid root object path" );
return false;
}
// Print to file
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return true;
}
//---------------------------------------------------------------------------
bool CJSONparse::LoadFromFile( const char * RootPath, const char * FilePath, int pBufLen )
{ {
TDataMember * RootObject = NULL; TDataMember * RootObject = NULL;
// Validate
if (!DataTree) {
return false;
}
// Clear Error // Clear Error
Error = false; Error = false;
@@ -84,14 +173,19 @@ bool CJSONparse::LoadFromFile( const char * FilePath, int pBufLen )
return false; return false;
} }
// Get/Create Root object
if (!RootPath || !*RootPath) {
RootObject = DataTree->GetRootMember();
}
else if (!(RootObject = DataTree->GetMember( NULL, RootPath, true ))) {
Error = true;
sprintf( ErrorText, "Invalid root object path" );
return false;
}
// Reset values // Reset values
LineNo = 1; LineNo = 1;
Error = false; DataTree->Delete( RootObject, NULL );
// Create Root object
DataTree->DeleteAll();
RootObject = DataTree->GetRootMember();
Level = 0;
// Parse Root Object // Parse Root Object
SkipWhiteSpace(); SkipWhiteSpace();
@@ -256,7 +350,6 @@ bool CJSONparse::ParseObject( TDataMember * Object )
BufPos++; BufPos++;
// Set Type // Set Type
Level++;
DataTree->SetValue( Object, jtObject ); DataTree->SetValue( Object, jtObject );
while (true) while (true)
@@ -305,6 +398,9 @@ bool CJSONparse::ParseObject( TDataMember * Object )
return false; return false;
} }
// Free Name
free( MemberName );
// Check if more parameters to follow // Check if more parameters to follow
SkipWhiteSpace(); SkipWhiteSpace();
if (*BufPos != ',') { if (*BufPos != ',') {
@@ -321,7 +417,6 @@ bool CJSONparse::ParseObject( TDataMember * Object )
return false; return false;
} }
BufPos++; BufPos++;
Level--;
// success // success
return true; return true;
@@ -339,7 +434,6 @@ bool CJSONparse::ParseArray( TDataMember * Array )
BufPos++; BufPos++;
// Set Type // Set Type
Level++;
DataTree->SetValue( Array, jtArray ); DataTree->SetValue( Array, jtArray );
while (true) while (true)
@@ -386,7 +480,6 @@ bool CJSONparse::ParseArray( TDataMember * Array )
return false; return false;
} }
BufPos++; BufPos++;
Level--;
// success // success
return true; return true;
@@ -474,49 +567,6 @@ bool CJSONparse::ParsePrimitive( TDataMember * Member )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CJSONparse::PrintToScreen( const int Indent )
{
TDataMember * RootObject;
// Set to StdOut
OutputHandle = 1;
// Save Root object
Level = 0;
RootObject = DataTree->GetRootMember();
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return false;
}
//---------------------------------------------------------------------------
bool CJSONparse::SaveToFile( const char * FilePath, const int Indent )
{
TDataMember * RootObject;
// Validate
if (!FilePath || !FilePath[0])
return false;
// Open file
if (!(OutputHandle = open( FilePath, O_WRONLY )))
return false;
// Save Root object
Level = 0;
RootObject = DataTree->GetRootMember();
PrintObject( RootObject, Indent );
// Close file
close( OutputHandle );
OutputHandle = -1;
return false;
}
//---------------------------------------------------------------------------
bool CJSONparse::PrintObject( TDataMember * Object, const int Indent ) bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
{ {
TDataMember * Member; TDataMember * Member;
@@ -526,7 +576,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
// Opening brace // Opening brace
write( OutputHandle, "{", 1 ); write( OutputHandle, "{", 1 );
Level++;
// Extend spacer // Extend spacer
memset( &Spacer[SpacerLen], ' ', 2 ); memset( &Spacer[SpacerLen], ' ', 2 );
@@ -595,7 +644,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent )
Spacer[SpacerLen] = 0; Spacer[SpacerLen] = 0;
// Closing brace // Closing brace
Level--;
if (Object->Len) { if (Object->Len) {
write( OutputHandle, Spacer, SpacerLen ); write( OutputHandle, Spacer, SpacerLen );
} }
@@ -613,7 +661,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
// Opening brace // Opening brace
write( OutputHandle, "[", 1 ); write( OutputHandle, "[", 1 );
Level++;
// Extend spacer // Extend spacer
memset( &Spacer[SpacerLen], ' ', 2 ); memset( &Spacer[SpacerLen], ' ', 2 );
@@ -668,7 +715,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent )
Spacer[SpacerLen] = 0; Spacer[SpacerLen] = 0;
// Closing brace // Closing brace
Level--;
if (Array->Len) { if (Array->Len) {
write( OutputHandle, Spacer, SpacerLen ); write( OutputHandle, Spacer, SpacerLen );
} }

View File

@@ -36,7 +36,6 @@ private:
char * BufPos; char * BufPos;
char * LineMark; char * LineMark;
int LineNo; int LineNo;
int Level;
// Printing Operation // Printing Operation
char Spacer[100]; char Spacer[100];
@@ -74,10 +73,10 @@ public:
CJSONparse( CDataTree * pDataTree ); CJSONparse( CDataTree * pDataTree );
~CJSONparse(); ~CJSONparse();
bool PrintToScreen( const int Indent ); bool PrintToScreen( const char * Path, const int Indent );
bool LoadFromFile( const char * FilePath, int pBufLen = 500 ); bool LoadFromFile( const char * Path, const char * FilePath, int pBufLen = 500 );
bool SaveToFile( const char * FilePath, const int Indent = 2 ); bool SaveToFile( const char * Path, const char * FilePath, const int Indent = 2 );
const char * GetError() { return ((Error)? ErrorText : "Success"); }; const char * GetError() { return ((Error)? ErrorText : "Success"); };
}; };