/* * DataTreeCore.cpp * * Created on: 5 Mar 2017 * Author: wentzelc */ // redA Libraries #include "DataTreeCore.h" // Standard C/C++ Libraries #include #include #include #include #include //--------------------------------------------------------------------------- CDataTree::CDataTree() { // Create Root member of tree RootObject = CreateMember( NULL ); RootObject->Type = jtObject; } //--------------------------------------------------------------------------- CDataTree::~CDataTree() { // Destroy Members DeleteAll(); DestroyMember( &RootObject ); } //--------------------------------------------------------------------------- TDataMember * CDataTree::CreateMember( const char * Name ) { TDataMember * Member; Member = (TDataMember *)calloc( 1, sizeof(TDataMember) ); if (Name && *Name) { Member->Name = (char *)malloc( strlen( Name )+1 ); strcpy( Member->Name, Name ); } return Member; } //--------------------------------------------------------------------------- bool CDataTree::DestroyMember( TDataMember ** Member ) { TDataMember * NextMember; // Valdate if (!Member || !*Member) return false; // Get next param in list NextMember = (*Member)->Next; // Destroy if ((*Member)->Name) free( (*Member)->Name ); if ((*Member)->Value) free( (*Member)->Value ); while ((*Member)->FirstChild) { DestroyMember( &((*Member)->FirstChild) ); } free( *Member ); // Restore list integrity *Member = NextMember; return true; } //--------------------------------------------------------------------------- bool CDataTree::GetParent( const char * ParentPath, TDataMember **Parent ) { TDataMember * Member; char * ParentName; char * Pos; // Validate if (!Parent) { return false; } // Set first Parent *Parent = RootObject; // Check if path provided if (!ParentPath || !*ParentPath) { return true; } // Split path Pos = (char*)ParentPath; while (*Pos) { // Set Name start ParentName = Pos; // Find delimeter while (*Pos && (*Pos != '/')) { Pos++; } // Zero terminate name if (*Pos) { *Pos = 0; Pos++; } // Find next parent Member = (*Parent)->FirstChild; while (Member && strcasecmp( Member->Name, ParentName )) { Member = Member->Next; } if (!Member) { return false; } // Set Next parent *Parent = Member; } return true; } //--------------------------------------------------------------------------- TDataMember * CDataTree::GetMember( TDataMember * Parent, const char * Name ) { TDataMember * Member; // Validate if (!Parent || !Name || !*Name) { return NULL; } // Get Member Member = Parent->FirstChild; while (Member && strcasecmp( Member->Name, Name )) Member = Member->Next; return Member; } //--------------------------------------------------------------------------- TDataMember ** CDataTree::GetMemberPtr( TDataMember * Parent, const char * Name ) { TDataMember ** Member; // Validate if (!Parent || !Name || !*Name) { return NULL; } // Get Member Member = &(Parent->FirstChild); while (Member && strcasecmp( (*Member)->Name, Name )) Member = &((*Member)->Next); return Member; } //--------------------------------------------------------------------------- bool CDataTree::Delete( const char * ParentPath, const char * Name ) { TDataMember * Parent; TDataMember ** Member; // Check if exists if (!GetParent( ParentPath, &Parent ) || !(Member = GetMemberPtr( Parent, Name ))) { return false; } // Destroy DestroyMember( Member ); Parent->Len--; return true; } //--------------------------------------------------------------------------- bool CDataTree::DeleteAll() { while (RootObject->FirstChild) { DestroyMember( &(RootObject->FirstChild) ); } return true; } //--------------------------------------------------------------------------- bool CDataTree::SetMember( TDataMember * Member, EDataType Type, const char * Value, const int Len ) { // Clear previous value if (Member->Value != NULL) { free( Member->Value ); } // Set type Member->Type = Type; // Set new value switch (Type) { case jtNull: case jtObject: case jtArray: Member->Len = 0; Member->Value = NULL; break; case jtString: case jtFloat: case jtInt: case jtBool: Member->Len = (Len == -1)? strlen(Value) : Len; Member->Value = (char *)malloc( sizeof(Member->Len+1) ); if (Value) { memcpy( Member->Value, Value, Member->Len+1 ); } else { memset( Member->Value, 0, Member->Len+1 ); } Member->Value[Member->Len] = 0; break; } return true; } //--------------------------------------------------------------------------- bool CDataTree::SetObject( const char * ParentPath, const char * Name ) { TDataMember * Parent; TDataMember ** Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return false; } // Create new param if it doesn't exist if (!(Member = GetMemberPtr( Parent, Name ))) { *Member = CreateMember( Name ); } SetMember( *Member, jtObject, NULL, -1 ); return true; } //--------------------------------------------------------------------------- bool CDataTree::SetStr( const char * ParentPath, const char * Name, const char * Value, const int Len ) { TDataMember * Parent; TDataMember ** Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return false; } // Create new param if it doesn't exist if (!(Member = GetMemberPtr( Parent, Name ))) { *Member = CreateMember( Name ); } SetMember( *Member, jtString, Value, Len ); return true; } //--------------------------------------------------------------------------- bool CDataTree::SetInt( const char * ParentPath, const char * Name, const long Value ) { TDataMember * Parent; TDataMember ** Member; char ValueStr[50]; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return false; } // Create new param if it doesn't exist if (!(Member = GetMemberPtr( Parent, Name ))) { *Member = CreateMember( Name ); } sprintf( ValueStr, "%ld", Value ); SetMember( *Member, jtInt, ValueStr, -1 ); return true; } //--------------------------------------------------------------------------- bool CDataTree::SetFloat( const char * ParentPath, const char * Name, const double Value ) { TDataMember * Parent; TDataMember ** Member; char ValueStr[50]; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return false; } // Create new param if it doesn't exist if (!*(Member = GetMemberPtr( Parent, Name ))) { *Member = CreateMember( Name ); } sprintf( ValueStr, "%lf", Value ); SetMember( *Member, jtFloat, ValueStr, -1 ); return true; } //--------------------------------------------------------------------------- bool CDataTree::SetBool( const char * ParentPath, const char * Name, const bool Value ) { TDataMember * Parent; TDataMember ** Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return false; } // Create new param if it doesn't exist if (!*(Member = GetMemberPtr( Parent, Name ))) { *Member = CreateMember( Name ); } SetMember( *Member, jtBool, ((Value == 0)? "0" : "1"), -1 ); return true; } //--------------------------------------------------------------------------- bool CDataTree::SetNull( const char * ParentPath, const char * Name ) { TDataMember * Parent; TDataMember ** Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return false; } // Create new param if it doesn't exist if (!*(Member = GetMemberPtr( Parent, Name ))) { *Member = CreateMember( Name ); } SetMember( *Member, jtNull, NULL, -1 ); return true; } //--------------------------------------------------------------------------- const EDataType CDataTree::GetType( const char * ParentPath, const char * Name ) { TDataMember * Parent; TDataMember * Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return jtNull; } // Return type if ((Member = GetMember( Parent, Name ))) { return Member->Type; } else { return jtNull; } } //--------------------------------------------------------------------------- const char * CDataTree::GetStr( const char * ParentPath, const char * Name, const char * Default ) { TDataMember * Parent; TDataMember * Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return Default; } // Return value if ((Member = GetMember( Parent, Name )) && (Member->Type == jtString)) { return Member->Value; } else { return Default; } } //--------------------------------------------------------------------------- const char * CDataTree::GetStr( const char * ParentPath, const char * Name, int &Len, const char * Default ) { TDataMember * Parent; TDataMember * Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return Default; } // Return value if ((Member = GetMember( Parent, Name )) && (Member->Type == jtString)) { Len = Member->Len; return Member->Value; } else { Len = strlen( Default ); return Default; } } //--------------------------------------------------------------------------- const long CDataTree::GetInt( const char * ParentPath, const char * Name, long Default ) { TDataMember * Parent; TDataMember * Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return Default; } // Return value if ((Member = GetMember( Parent, Name )) && (Member->Type == jtInt)) { return strtol( Member->Value, NULL, 10 ); } else { return Default; } } //--------------------------------------------------------------------------- const double CDataTree::GetFloat( const char * ParentPath, const char * Name, double Default ) { TDataMember * Parent; TDataMember * Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return Default; } // Return value if ((Member = GetMember( Parent, Name )) && (Member->Type == jtFloat)) { return strtod( Member->Value, NULL ); } else { return Default; } } //--------------------------------------------------------------------------- const bool CDataTree::GetBool( const char * ParentPath, const char * Name, bool Default ) { TDataMember * Parent; TDataMember * Member; // Validate if (!Name || !*Name || !GetParent( ParentPath, &Parent )) { return Default; } // Return value if ((Member = GetMember( Parent, Name )) && (Member->Type == jtBool)) { return ((!strcasecmp( Member->Value, "0" ))? false : true ); } else { return Default; } } //---------------------------------------------------------------------------