Important Update:

- Improve "printing" for JSON with single & multi line objects
- Fix bugs in getting, setting & creating array elements
- "array[]" allowed to create/add element at end of an array
- No longer duplicate get() path (reduce memory allocation)
  - added NameLen to TMember to eliminate zero-terminate requirement
- Fix ReadfromXXX() return values
This commit is contained in:
Charl Wentzel
2017-04-05 08:07:53 +02:00
parent 66fc4bc123
commit 200f7e1f8b
3 changed files with 99 additions and 53 deletions

View File

@@ -40,7 +40,8 @@ TDataMember * CDataTree::CreateMember( const char * Name )
Member = (TDataMember *)calloc( 1, sizeof(TDataMember) );
if (Name && *Name)
{
Member->Name = (char *)malloc( strlen( Name )+1 );
Member->Len = strlen( Name );
Member->Name = (char *)malloc( Member->Len+1 );
strcpy( Member->Name, Name );
}
return Member;
@@ -119,12 +120,12 @@ bool CDataTree::DestroyValue( TDataMember * Member )
TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char * Path, bool Create, TDataMember ** Parent )
{
char * WorkPath = NULL;
TDataMember * Member;
TDataMember ** Child = NULL;
char * Pos;
char * EndPos;
char * MemberName;
char * Key;
unsigned short KeyLen;
int Index;
int Count;
bool Last = false;
@@ -134,8 +135,6 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
if (Parent) *Parent = NULL;
return NULL;
}
WorkPath = (char*)malloc( strlen(Path)+1 );
strcpy( WorkPath, Path );
// Set init references
if (Parent) *Parent = NULL;
@@ -143,15 +142,12 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
Member = (BaseMember)? BaseMember : RootMember;
// Split path
Pos = (char*)WorkPath;
Pos = (char*)Path;
while (Member && *Pos)
{
// Reset Child reference
Child = NULL;
// Set Name start
MemberName = Pos;
// Find delimiter
if (*Pos == '[')
{
@@ -163,40 +159,61 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
break; // Can't convert something else to an array
}
// Set Index start
Pos++;
Key = Pos;
// Get Index value
Pos++;
while (*Pos && (*Pos != ']')) {
while (*Pos && (*Pos != ']'))
Pos++;
}
if (*Pos != ']') {
if (!*Pos)
break;
}
Index = (int)strtoul( Pos, &EndPos, 10 );
if (EndPos != Pos) {
break;
}
// Check if last
Pos++;
if (!*Pos) {
// Last element
if (!*Pos)
Last = true;
if (Pos == Key+1) {
// Empty bracket only allowed for create
if (!Create)
break;
// find end of list
Child = &(Member->FirstChild);
while (*Child)
Child = &((*Child)->Next);
}
else {
// Get requested index
Index = (int)strtoul( Key, &EndPos, 10 );
if (EndPos != Pos-1)
break;
// Find element at requested index
Child = &(Member->FirstChild);
Count = 0;
while (*Child && (Count < Index)) {
Child = &((*Child)->Next);
Count++;
}
}
// Find next parent
Child = &(Member->FirstChild);
Count = 0;
while (*Child && (Count < Index)) {
Child = &((*Child)->Next);
Count++;
}
// Create element if needed
if (!*Child && Create) {
if (!Index || (Index = Count + 1)) {
*Child = CreateMember( NULL );
Member->Value++;
Member->Len++;
}
}
}
else
{
// Skip separator
if (*Pos == '/') {
Pos++;
}
// Validate
if (Create && (Member->Type == jtNull)) {
Member->Type = jtObject; // Convert to object
@@ -206,26 +223,25 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
}
// Get key value
Key = Pos;
KeyLen = 0;
while (*Pos && (*Pos != '/') && (*Pos != '[')) {
KeyLen++;
Pos++;
}
// More elements?
if (!*Pos) {
// Last element
Last = true;
}
else {
// Zero terminate name
*Pos = 0;
Pos++;
}
// Find next parent
Child = &(Member->FirstChild);
while (*Child && strcasecmp( (*Child)->Name, MemberName )) {
while (*Child && ((*Child)->NameLen != KeyLen) && strncasecmp( (*Child)->Name, Key, KeyLen )) {
Child = &((*Child)->Next);
}
if (!*Child && Create) {
*Child = CreateMember( MemberName );
*Child = CreateMember( Key );
Member->Len++;
}
}
@@ -238,10 +254,6 @@ TDataMember ** CDataTree::GetMemberPtr( TDataMember * BaseMember, const char *
// Next level
Member = *Child;
}
// Destroy temp path
free( WorkPath );
return Child;
}
//---------------------------------------------------------------------------