Important Update:

- DataTreeCore:
  - Add Parent & Prev Child links to DataMembers
  - Update CreateMember() to set Parent/Sibling reference
      & increase Parent->Len
  - Remove AddMember()
  - Update DestroyMember() to decrease Parent->Len
- JSONparseCore:
  - Update ParseArray() for above changes made to DataTreeCore
This commit is contained in:
Charl Wentzel
2017-08-11 15:42:59 +02:00
parent 73743060a0
commit 2b7c49d5bb
3 changed files with 50 additions and 42 deletions

View File

@@ -17,7 +17,7 @@
CDataTree::CDataTree() CDataTree::CDataTree()
{ {
// Create Root member of tree // Create Root member of tree
RootMember = CreateMember( NULL ); RootMember = CreateMember( NULL, NULL, NULL );
RootMember->Type = jtObject; 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; TDataMember * Member;
@@ -45,43 +45,38 @@ TDataMember * CDataTree::CreateMember( const char * Name, const int Len )
memcpy( Member->Name, Name, Member->NameLen ); memcpy( Member->Name, Name, Member->NameLen );
Member->Name[ Member->NameLen ] = 0; 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; 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 ) bool CDataTree::DestroyMember( TDataMember ** Member )
{ {
TDataMember * NextMember; TDataMember * NextMember;
// Valdate // Validate
if (!Member || !*Member) if (!Member || !*Member)
return false; return false;
// Get next param in list // Get next param in list
NextMember = (*Member)->Next; NextMember = (*Member)->Next;
// Update Parent
if ((*Member)->Parent)
(*Member)->Parent->Len--;
// Destroy // Destroy
if ((*Member)->Name) if ((*Member)->Name)
free( (*Member)->Name ); free( (*Member)->Name );
@@ -102,7 +97,7 @@ bool CDataTree::DestroyMember( TDataMember ** Member )
bool CDataTree::DestroyValue( TDataMember * Member ) bool CDataTree::DestroyValue( TDataMember * Member )
{ {
// Valdate // Validate
if (!Member) if (!Member)
return false; return false;
@@ -111,10 +106,12 @@ bool CDataTree::DestroyValue( TDataMember * Member )
free( Member->Value ); free( Member->Value );
Member->Value = NULL; Member->Value = NULL;
} }
// Destroy Children
while (Member->FirstChild) { while (Member->FirstChild) {
DestroyMember( &(Member->FirstChild) ); DestroyMember( &(Member->FirstChild) );
} }
Member->Len = 0;
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -122,7 +119,8 @@ bool CDataTree::DestroyValue( TDataMember * Member )
TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * Path, bool Create, TDataMember ** Parent ) TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * Path, bool Create, TDataMember ** Parent )
{ {
TDataMember * Member; TDataMember * Member;
TDataMember ** Child = NULL; TDataMember ** Child;
TDataMember * PrevChild;
char * Pos; char * Pos;
char * EndPos; char * EndPos;
char * Key; char * Key;
@@ -182,10 +180,13 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
Index = -1; Index = -1;
// find end of list // find end of list
PrevChild = NULL;
Child = &(Member->FirstChild); Child = &(Member->FirstChild);
while (*Child) while (*Child) {
PrevChild = *Child;
Child = &((*Child)->Next); Child = &((*Child)->Next);
} }
}
else { else {
// Get requested index // Get requested index
Index = (int)strtoul( Key, &EndPos, 10 ); Index = (int)strtoul( Key, &EndPos, 10 );
@@ -193,9 +194,11 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
break; break;
// Find element at requested index // Find element at requested index
PrevChild = NULL;
Child = &(Member->FirstChild); Child = &(Member->FirstChild);
Count = 0; Count = 0;
while (*Child && (Count < Index)) { while (*Child && (Count < Index)) {
PrevChild = *Child;
Child = &((*Child)->Next); Child = &((*Child)->Next);
Count++; Count++;
} }
@@ -204,8 +207,7 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
// Create element if needed // Create element if needed
if (!*Child && Create) { if (!*Child && Create) {
if ((Index == -1) || (Index = Count + 1)) { if ((Index == -1) || (Index = Count + 1)) {
*Child = CreateMember( NULL ); *Child = CreateMember( Member, PrevChild, NULL );
Member->Len++;
} }
} }
} }
@@ -238,13 +240,14 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
} }
// Find next parent // Find next parent
PrevChild = NULL;
Child = &(Member->FirstChild); Child = &(Member->FirstChild);
while (*Child && (((*Child)->NameLen != KeyLen) || strncasecmp( (*Child)->Name, Key, KeyLen ))) { while (*Child && (((*Child)->NameLen != KeyLen) || strncasecmp( (*Child)->Name, Key, KeyLen ))) {
PrevChild = *Child;
Child = &((*Child)->Next); Child = &((*Child)->Next);
} }
if (!*Child && Create) { if (!*Child && Create) {
*Child = CreateMember( Key, KeyLen ); *Child = CreateMember( Member, PrevChild, Key, KeyLen );
Member->Len++;
} }
} }
@@ -324,7 +327,6 @@ bool CDataTree::Delete( TDataMember * BaseMember, const char * Path )
else if ((Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) { else if ((Member = GetMemberPtr( BaseMember, Path, false, &Parent ))) {
// If valid path, destroy member // If valid path, destroy member
DestroyMember( Member ); DestroyMember( Member );
Parent->Len--;
return true; return true;
} }
else { else {

View File

@@ -34,6 +34,8 @@ struct SDataMember
char * Value; char * Value;
unsigned short Len; unsigned short Len;
TDataMember * Parent;
TDataMember * Prev;
TDataMember * Next; TDataMember * Next;
}; };
@@ -45,8 +47,7 @@ private:
TDataMember * RootMember; TDataMember * RootMember;
// Manage Members // Manage Members
TDataMember * CreateMember( const char * Name, const int Len = -1 ); TDataMember * CreateMember( TDataMember * Parent, TDataMember * PrevChild, const char * Name, const int Len = -1 );
bool AddMember( TDataMember * Parent, TDataMember * Member );
bool DestroyMember( TDataMember ** Member ); bool DestroyMember( TDataMember ** Member );
bool DestroyValue( TDataMember * Member ); bool DestroyValue( TDataMember * Member );
@@ -68,8 +69,10 @@ public:
TDataMember * GetIndexChild( TDataMember * Parent, const int Index ); TDataMember * GetIndexChild( TDataMember * Parent, const int Index );
TDataMember * GetFirstChild( TDataMember * Parent, const char * Path, bool Create = false ); TDataMember * GetFirstChild( TDataMember * Parent, const char * Path, bool Create = false );
inline TDataMember * GetParent( TDataMember * Child ) { return ((Child)? Child->Parent : NULL); };
inline TDataMember * GetFirstChild( TDataMember * Parent ) { return ((Parent)? Parent->FirstChild : NULL); }; inline TDataMember * GetFirstChild( TDataMember * Parent ) { return ((Parent)? Parent->FirstChild : NULL); };
inline TDataMember * GetNextChild( TDataMember * PrevChild ) { return ((PrevChild)? PrevChild->Next : 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, const char * Default = NULL, bool Create = false );
const char * GetStr( TDataMember * BaseMember, const char * Path, int &Len, const char * Default = NULL, bool Create = false ); const char * GetStr( TDataMember * BaseMember, const char * Path, int &Len, const char * Default = NULL, bool Create = false );

View File

@@ -598,7 +598,8 @@ bool CJSONparse::ParseObject( TDataMember * Object )
bool CJSONparse::ParseArray( TDataMember * Array ) bool CJSONparse::ParseArray( TDataMember * Array )
{ {
TDataMember * Member = NULL; TDataMember ** Member;
TDataMember * PrevMember;
// Check for start of Object // Check for start of Object
if (*BufPos != '[') { if (*BufPos != '[') {
@@ -608,7 +609,8 @@ bool CJSONparse::ParseArray( TDataMember * Array )
// Set Type // Set Type
DataTree->SetValue( Array, jtArray ); DataTree->SetValue( Array, jtArray );
Member = &(Array->FirstChild);
PrevMember = NULL;
while (true) while (true)
{ {
// Look for Member Name // Look for Member Name
@@ -618,17 +620,18 @@ bool CJSONparse::ParseArray( TDataMember * Array )
} }
// Add new element // Add new element
Member = DataTree->CreateMember( NULL ); *Member = DataTree->CreateMember( Array, PrevMember, NULL );
// Get Value // Get Value
SkipWhiteSpace(); 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) { if (Error) {
DataTree->DestroyMember( &Member ); DataTree->DestroyMember( Member );
return false; return false;
} }
else { else {
DataTree->AddMember( Array, Member ); PrevMember = *Member;
Member = &((*Member)->Next);
} }
// Check if more parameters to follow // Check if more parameters to follow