From 8f39adb0f3ce2e41f72e65c859bf0d88eaedee5d Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Wed, 29 Mar 2017 21:27:28 +0200 Subject: [PATCH] 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 --- BufferCore.cpp | 3 + DataTreeCore.cpp | 27 ++++++-- JSONparseCore.cpp | 164 +++++++++++++++++++++++++++++----------------- JSONparseCore.h | 7 +- 4 files changed, 131 insertions(+), 70 deletions(-) diff --git a/BufferCore.cpp b/BufferCore.cpp index c6bdf60..827264a 100644 --- a/BufferCore.cpp +++ b/BufferCore.cpp @@ -807,6 +807,9 @@ int CShiftBuffer::ReadFromFD( int Handle, int MaxRead ) DataRemain -= BytesRead; TotalRead += BytesRead; BufLen += BytesRead; + + // Zero terminate + Buffer[BufLen] = 0; } return TotalRead; } diff --git a/DataTreeCore.cpp b/DataTreeCore.cpp index e77c491..171e8f9 100644 --- a/DataTreeCore.cpp +++ b/DataTreeCore.cpp @@ -239,6 +239,9 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * Member = *Child; } + // Destroy temp path + free( WorkPath ); + return Child; } //--------------------------------------------------------------------------- @@ -258,15 +261,25 @@ bool CDataTree::Delete( TDataMember * BaseMember, const char * Path ) TDataMember * Parent; TDataMember ** Member; - // Check if exists - if (!(Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) { + // Validate + if (!BaseMember && (!Path || !*Path)) { return false; } - // Destroy - DestroyMember( Member ); - Parent->Len--; - return true; + 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 ); + Parent->Len--; + return true; + } + else { + return false; + } } //--------------------------------------------------------------------------- @@ -323,7 +336,7 @@ bool CDataTree::SetValue( TDataMember * Member, EDataType Type, const char * Va } else { // Set null value - SetValuePtr( Member, Type, NULL, -1 ); + SetValuePtr( Member, Type, NULL, 0 ); } return true; } diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index 19846a4..2122044 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -28,7 +28,6 @@ CJSONparse::CJSONparse( CDataTree * pDataTree ) Buffer = NULL; BufEnd = NULL; - Level = 0; // Parsing operation 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; + // Validate + if (!DataTree) { + return false; + } + // Clear Error Error = false; @@ -84,14 +173,19 @@ bool CJSONparse::LoadFromFile( const char * FilePath, int pBufLen ) 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 LineNo = 1; - Error = false; - - // Create Root object - DataTree->DeleteAll(); - RootObject = DataTree->GetRootMember(); - Level = 0; + DataTree->Delete( RootObject, NULL ); // Parse Root Object SkipWhiteSpace(); @@ -256,7 +350,6 @@ bool CJSONparse::ParseObject( TDataMember * Object ) BufPos++; // Set Type - Level++; DataTree->SetValue( Object, jtObject ); while (true) @@ -305,6 +398,9 @@ bool CJSONparse::ParseObject( TDataMember * Object ) return false; } + // Free Name + free( MemberName ); + // Check if more parameters to follow SkipWhiteSpace(); if (*BufPos != ',') { @@ -321,7 +417,6 @@ bool CJSONparse::ParseObject( TDataMember * Object ) return false; } BufPos++; - Level--; // success return true; @@ -339,7 +434,6 @@ bool CJSONparse::ParseArray( TDataMember * Array ) BufPos++; // Set Type - Level++; DataTree->SetValue( Array, jtArray ); while (true) @@ -386,7 +480,6 @@ bool CJSONparse::ParseArray( TDataMember * Array ) return false; } BufPos++; - Level--; // success 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 ) { TDataMember * Member; @@ -526,7 +576,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent ) // Opening brace write( OutputHandle, "{", 1 ); - Level++; // Extend spacer memset( &Spacer[SpacerLen], ' ', 2 ); @@ -595,7 +644,6 @@ bool CJSONparse::PrintObject( TDataMember * Object, const int Indent ) Spacer[SpacerLen] = 0; // Closing brace - Level--; if (Object->Len) { write( OutputHandle, Spacer, SpacerLen ); } @@ -613,7 +661,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent ) // Opening brace write( OutputHandle, "[", 1 ); - Level++; // Extend spacer memset( &Spacer[SpacerLen], ' ', 2 ); @@ -668,7 +715,6 @@ bool CJSONparse::PrintArray( TDataMember * Array, const int Indent ) Spacer[SpacerLen] = 0; // Closing brace - Level--; if (Array->Len) { write( OutputHandle, Spacer, SpacerLen ); } diff --git a/JSONparseCore.h b/JSONparseCore.h index 603292b..bbae172 100644 --- a/JSONparseCore.h +++ b/JSONparseCore.h @@ -36,7 +36,6 @@ private: char * BufPos; char * LineMark; int LineNo; - int Level; // Printing Operation char Spacer[100]; @@ -74,10 +73,10 @@ public: CJSONparse( CDataTree * pDataTree ); ~CJSONparse(); - bool PrintToScreen( const int Indent ); + bool PrintToScreen( const char * Path, const int Indent ); - bool LoadFromFile( const char * FilePath, int pBufLen = 500 ); - bool SaveToFile( const char * FilePath, const int Indent = 2 ); + bool LoadFromFile( const char * Path, const char * FilePath, int pBufLen = 500 ); + bool SaveToFile( const char * Path, const char * FilePath, const int Indent = 2 ); const char * GetError() { return ((Error)? ErrorText : "Success"); }; };