diff --git a/DataTreeCore.cpp b/DataTreeCore.cpp index b02be4e..5643b59 100644 --- a/DataTreeCore.cpp +++ b/DataTreeCore.cpp @@ -17,7 +17,7 @@ CDataTree::CDataTree() { // Create Root member of tree - RootMember = CreateMember( NULL ); + RootMember = CreateMember( NULL, NULL, NULL ); RootMember->Type = jtObject; } //--------------------------------------------------------------------------- @@ -30,7 +30,7 @@ CDataTree::~CDataTree() } //--------------------------------------------------------------------------- -TDataMember * CDataTree::CreateMember( const char * Name, const int Len ) +TDataMember * CDataTree::CreateMember( TDataMember * Parent, TDataMember * PrevChild, const char * Name, const int Len ) { TDataMember * Member; @@ -45,43 +45,38 @@ TDataMember * CDataTree::CreateMember( const char * Name, const int Len ) memcpy( Member->Name, Name, Member->NameLen ); Member->Name[ Member->NameLen ] = 0; } + + // Update Parent + if (Parent) { + Member->Parent = Parent; + Parent->Len++; + } + + // Set Sibling links + Member->Prev = PrevChild; + Member->Next = NULL; + return Member; } //--------------------------------------------------------------------------- -bool CDataTree::AddMember( TDataMember * Parent, TDataMember * Member ) -{ - TDataMember ** Child; - // Validate - if (!Parent || !Member) { - return false; - } - - // Get end of list - Child = &(Parent->FirstChild); - while (*Child) { - Child = &((*Child)->Next); - } - - // Add member - *Child = Member; - Parent->Len++; - return true; -} -//--------------------------------------------------------------------------- bool CDataTree::DestroyMember( TDataMember ** Member ) { TDataMember * NextMember; - // Valdate + // Validate if (!Member || !*Member) return false; // Get next param in list NextMember = (*Member)->Next; + // Update Parent + if ((*Member)->Parent) + (*Member)->Parent->Len--; + // Destroy if ((*Member)->Name) free( (*Member)->Name ); @@ -102,7 +97,7 @@ bool CDataTree::DestroyMember( TDataMember ** Member ) bool CDataTree::DestroyValue( TDataMember * Member ) { - // Valdate + // Validate if (!Member) return false; @@ -111,10 +106,12 @@ bool CDataTree::DestroyValue( TDataMember * Member ) free( Member->Value ); Member->Value = NULL; } + + // Destroy Children while (Member->FirstChild) { DestroyMember( &(Member->FirstChild) ); } - Member->Len = 0; + return true; } //--------------------------------------------------------------------------- @@ -122,7 +119,8 @@ bool CDataTree::DestroyValue( TDataMember * Member ) TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * Path, bool Create, TDataMember ** Parent ) { TDataMember * Member; - TDataMember ** Child = NULL; + TDataMember ** Child; + TDataMember * PrevChild; char * Pos; char * EndPos; char * Key; @@ -182,9 +180,12 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * Index = -1; // find end of list + PrevChild = NULL; Child = &(Member->FirstChild); - while (*Child) + while (*Child) { + PrevChild = *Child; Child = &((*Child)->Next); + } } else { // Get requested index @@ -193,9 +194,11 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * break; // Find element at requested index + PrevChild = NULL; Child = &(Member->FirstChild); Count = 0; while (*Child && (Count < Index)) { + PrevChild = *Child; Child = &((*Child)->Next); Count++; } @@ -204,8 +207,7 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * // Create element if needed if (!*Child && Create) { if ((Index == -1) || (Index = Count + 1)) { - *Child = CreateMember( NULL ); - Member->Len++; + *Child = CreateMember( Member, PrevChild, NULL ); } } } @@ -238,13 +240,14 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * } // Find next parent + PrevChild = NULL; Child = &(Member->FirstChild); while (*Child && (((*Child)->NameLen != KeyLen) || strncasecmp( (*Child)->Name, Key, KeyLen ))) { + PrevChild = *Child; Child = &((*Child)->Next); } if (!*Child && Create) { - *Child = CreateMember( Key, KeyLen ); - Member->Len++; + *Child = CreateMember( Member, PrevChild, Key, KeyLen ); } } @@ -324,7 +327,6 @@ bool CDataTree::Delete( TDataMember * BaseMember, const char * Path ) else if ((Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) { // If valid path, destroy member DestroyMember( Member ); - Parent->Len--; return true; } else { diff --git a/DataTreeCore.h b/DataTreeCore.h index 30f8a87..e13bc8b 100644 --- a/DataTreeCore.h +++ b/DataTreeCore.h @@ -34,6 +34,8 @@ struct SDataMember char * Value; unsigned short Len; + TDataMember * Parent; + TDataMember * Prev; TDataMember * Next; }; @@ -45,8 +47,7 @@ private: TDataMember * RootMember; // Manage Members - TDataMember * CreateMember( const char * Name, const int Len = -1 ); - bool AddMember( TDataMember * Parent, TDataMember * Member ); + TDataMember * CreateMember( TDataMember * Parent, TDataMember * PrevChild, const char * Name, const int Len = -1 ); bool DestroyMember( TDataMember ** Member ); bool DestroyValue( TDataMember * Member ); @@ -68,8 +69,10 @@ public: TDataMember * GetIndexChild( TDataMember * Parent, const int Index ); TDataMember * GetFirstChild( TDataMember * Parent, const char * Path, bool Create = false ); - inline TDataMember * GetFirstChild( TDataMember * Parent ) { return ((Parent)? Parent->FirstChild : NULL); }; - inline TDataMember * GetNextChild( TDataMember * PrevChild ) { return ((PrevChild)? PrevChild->Next : NULL); }; + inline TDataMember * GetParent( TDataMember * Child ) { return ((Child)? Child->Parent : NULL); }; + inline TDataMember * GetFirstChild( TDataMember * Parent ) { return ((Parent)? Parent->FirstChild : NULL); }; + inline TDataMember * GetPrevChild( TDataMember * Child ) { return ((Child)? Child->Prev : NULL); }; + inline TDataMember * GetNextChild( TDataMember * Child ) { return ((Child)? Child->Next : NULL); }; const char * GetStr( TDataMember * BaseMember, const char * Path, const char * Default = NULL, bool Create = false ); const char * GetStr( TDataMember * BaseMember, const char * Path, int &Len, const char * Default = NULL, bool Create = false ); diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index db87436..41dbc60 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -598,7 +598,8 @@ bool CJSONparse::ParseObject( TDataMember * Object ) bool CJSONparse::ParseArray( TDataMember * Array ) { - TDataMember * Member = NULL; + TDataMember ** Member; + TDataMember * PrevMember; // Check for start of Object if (*BufPos != '[') { @@ -608,7 +609,8 @@ bool CJSONparse::ParseArray( TDataMember * Array ) // Set Type DataTree->SetValue( Array, jtArray ); - + Member = &(Array->FirstChild); + PrevMember = NULL; while (true) { // Look for Member Name @@ -618,17 +620,18 @@ bool CJSONparse::ParseArray( TDataMember * Array ) } // Add new element - Member = DataTree->CreateMember( NULL ); + *Member = DataTree->CreateMember( Array, PrevMember, NULL ); // Get Value SkipWhiteSpace(); - if (!ParseObject( Member ) && !Error && !ParseArray( Member ) && !Error && !ParseString( Member ) && !Error && !ParsePrimitive( Member ) ) {} + if (!ParseObject( *Member ) && !Error && !ParseArray( *Member ) && !Error && !ParseString( *Member ) && !Error && !ParsePrimitive( *Member ) ) {} if (Error) { - DataTree->DestroyMember( &Member ); + DataTree->DestroyMember( Member ); return false; } else { - DataTree->AddMember( Array, Member ); + PrevMember = *Member; + Member = &((*Member)->Next); } // Check if more parameters to follow