diff --git a/DeviceCore.cpp b/DeviceCore.cpp index d1f6c35..fc5eedc 100644 --- a/DeviceCore.cpp +++ b/DeviceCore.cpp @@ -44,7 +44,8 @@ CDeviceCore::CDeviceCore( const char * pName, const char * pType ) : CFunctionCo // Data Structures DeviceInit = true; ConfigTypes = new CDataMember(); - JSONparse = new CJSONparse( ConfigTypes ); + ValueTree = new CDataMember(); + JSONparse = new CJSONparse(); } //--------------------------------------------------------------------------- @@ -59,11 +60,14 @@ CDeviceCore::~CDeviceCore() delete JSONparse; if (ConfigTypes) delete ConfigTypes; + if (ValueTree) + delete ValueTree; } //--------------------------------------------------------------------------- bool CDeviceCore::Init( CDataMember * FunctionConfig ) { + char * PersistFile = NULL; char * ConfigName = NULL; CDataMember * PollConfig = NULL; int IntVal1; @@ -102,9 +106,20 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig ) Log->Message( LogLevel, dlMedium, "%s/%s: Set polling param - Int:%d, T/O:%d, Max:%d", ProcessName, Name, PollInterval, ReplyTimeout, MaxRetries ); + // Load Value Tree from persistence file + if ((PersistFile = (char*)Config->GetChStr( "PersistFile", NULL, true ))) { + JSONparse->SetBase( ValueTree ); + JSONparse->ReadFromFile( NULL, PersistFile ); + + Log->Message( LogLevel, dlMedium, "%s/%s: Persistence File '%s' loaded", + ProcessName, Name, PersistFile ); + } + // Update Devices -- may want to do it from derived class intead if (DeviceInit) { - CDeviceCore::InitDevices( FunctionConfig ); + InitDevices( FunctionConfig ); + //JSONparse->SetBase( ValueTree ); + //JSONparse->WriteToScreen( NULL, 2 ); } return true; @@ -113,70 +128,164 @@ bool CDeviceCore::Init( CDataMember * FunctionConfig ) bool CDeviceCore::InitDevices( CDataMember * FunctionConfig ) { - CDataMember * DeviceData = NULL; + CDataMember * DeviceConfig = NULL; TDevice * Device = NULL; + char * Definition = NULL; char * DeviceName = NULL; int DeviceID = 0; char * DeviceAddr = NULL; char * DeviceType = NULL; + char * DataPath = NULL; // Load Device Types - DeviceData = Config->GetChFirstChild( "DeviceTypes", true ); - while (DeviceData) + DeviceConfig = Config->GetChFirstChild( "DeviceTypes", true ); + while (DeviceConfig) { - DeviceType = (char*)DeviceData->GetName(); - Device = AddDeviceType( DeviceType ); + DeviceType = (char*)DeviceConfig->GetName(); + if (!DeviceConfig->isObject()) { + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Invalid device type config for '%s'", + ProcessName, Name, DeviceType ); + DeviceConfig = DeviceConfig->GetNextPeer(); + continue; + } + + DataPath = (char*)DeviceConfig->GetChStr( "DataPath", NULL ); + Device = AddDeviceType( DeviceType, DataPath ); if (Device) { - if (DeviceData->isString()) { - if (JSONparse->ReadFromFile( DeviceType, DeviceData->GetStr() )) { // Contains file reference - InitDeviceParams( Device, ConfigTypes->GetChild( DeviceType ) ); + if ((Definition = (char*)DeviceConfig->GetChStr( "Definition", NULL, false ))) { + JSONparse->SetBase( ConfigTypes ); + if (JSONparse->ReadFromFile( DeviceType, Definition )) { // Contains file reference + InitDeviceParams( Device, ConfigTypes->GetChild( DeviceType ), NULL ); InitParamGroups( Device, ConfigTypes->GetChild( DeviceType ) ); - JSONparse->WriteToFile( DeviceType, DeviceData->GetStr() ); + + JSONparse->SetBase( ConfigTypes ); + JSONparse->WriteToFile( DeviceType, Definition ); } else { if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Fail to load device type '%s' from file: '%s'", - ProcessName, Name, DeviceType, DeviceData->GetStr() ); + ProcessName, Name, DeviceType, DeviceConfig->GetStr() ); } } - else if (DeviceData->isObject()) { - InitDeviceParams( Device, DeviceData ); // Contains definition - InitParamGroups( Device, DeviceData ); - } else { - if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Invalid device type config for '%s'", - ProcessName, Name, DeviceType ); + InitDeviceParams( Device, DeviceConfig, NULL ); // Contains definition + InitParamGroups( Device, DeviceConfig ); } } - DeviceData = DeviceData->GetNextPeer(); + DeviceConfig = DeviceConfig->GetNextPeer(); } // Load Actual Devices - DeviceData = Config->GetChFirstChild( "Devices", true ); - while (DeviceData) + DeviceConfig = Config->GetChFirstChild( "Devices", true ); + while (DeviceConfig) { - DeviceName = (char*)DeviceData->GetName(); - DeviceID = DeviceData->GetChInt( "ID", 0 ); - DeviceAddr = (char*)DeviceData->GetChStr( "Address", NULL ); - DeviceType = (char*)DeviceData->GetChStr( "Type", NULL ); - Device = AddDevice( DeviceName, DeviceType, DeviceID, DeviceAddr ); + DeviceName = (char*)DeviceConfig->GetName(); + if (!DeviceConfig->isObject()) { + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Invalid device config for '%s'", + ProcessName, Name, DeviceName ); + DeviceConfig = DeviceConfig->GetNextPeer(); + continue; + } + + DeviceID = DeviceConfig->GetChInt( "ID", 0 ); + DeviceAddr = (char*)DeviceConfig->GetChStr( "Address", NULL ); + DeviceType = (char*)DeviceConfig->GetChStr( "Type", NULL ); + DataPath = (char*)DeviceConfig->GetChStr( "DataPath", NULL ); + Device = AddDevice( DeviceName, DeviceType, DeviceID, DeviceAddr, DataPath ); if (Device) { - InitDeviceParams( Device, DeviceData ); - InitParamGroups( Device, DeviceData ); + InitDeviceParams( Device, DeviceConfig, Device->DataNode ); + InitParamGroups( Device, DeviceConfig ); } - DeviceData = DeviceData->GetNextPeer(); + DeviceConfig = DeviceConfig->GetNextPeer(); } return true; } //--------------------------------------------------------------------------- -bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig ) +bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig, CDataMember * ParentNode ) { - CDataMember * ParamData; + CDataMember * ParamConfig; + TDeviceParam * Template; + bool isType = (Device->Name)? false : true; + + // Copy Template Params + Template = (Device->Template)? Device->Template->FirstParam : NULL; + while (Template) { + CopyTemplateParam( Device, Template, ParentNode ); + Template = Template->Next; + } + + // Read Device Params + ParamConfig = DeviceConfig->GetChFirstChild( "Parameters", true ); + while (ParamConfig) { + InitDeviceParam( Device, ParamConfig, NULL, ((isType)? NULL : Device->DataPath), ParentNode ); + ParamConfig = ParamConfig->GetNextPeer(); + } + + return true; +} +//--------------------------------------------------------------------------- + +bool CDeviceCore::CopyTemplateParam( TDevice * Device, TDeviceParam * Template, CDataMember * ParentNode ) +{ + TDeviceParam * Param = NULL; + CDataMember * DataNode = NULL; + char * DataPath = NULL; + + if ((Param = AddDeviceParam( Device, Template->Name, Template->DataType, Template->Len ))) + { + SetParamAccess( Param, Template->Read, Template->Write ); + + if (Template->DataPath) { + DataPath = (char*)malloc( strlen(Device->DataPath) + strlen(Template->DataPath) + 2); + sprintf( DataPath, "%s/%s", Device->DataPath, Template->DataPath ); + DataNode = (Device->DataNode)? Device->DataNode->GetChild( Template->DataPath, true ) : NULL; + SetDataPath( Param, DataPath, DataNode ); + } + + if ((Template->DataType == dtUnsigned16) || (Template->DataType == dtUnsigned32_HL) || (Template->DataType == dtUnsigned32_LH)) { + UpdateUnsignedValue( Param, *((u_int16_t*)Template->Value), Template->Changed ); + if (Template->SetChanged) + SetUnsignedValue( Param, *((u_int16_t*)Template->Value), true ); + } + else if ((Template->DataType == dtSigned16) || (Template->DataType == dtSigned32_HL) || (Template->DataType == dtSigned32_LH)) { + UpdateSignedValue( Param, *((int16_t*)Template->Value), Template->Changed ); + if (Template->SetChanged) + SetSignedValue( Param, *((int16_t*)Template->Value), true ); + } + else if ((Template->DataType == dtFloat32_L) || (Template->DataType == dtFloat32_B)) { + UpdateFloatValue( Param, *((float*)Template->Value), Template->Changed ); + if (Template->SetChanged) + SetFloatValue( Param, *((float*)Template->Value), true ); + } + else if (Template->DataType == dtString) { + UpdateStringValue( Param, (char*)Template->Value, Template->Len, Template->Changed ); + if (Template->SetChanged) + SetStringValue( Param, (char*)Template->Value, Template->Len, true ); + } + + SetParamEvent( Param, (Template->EventChannel)? Template->EventChannel->Name : NULL, Template->EventInterval ); + } + + if (DataPath) free( DataPath ); + return true; +} +//--------------------------------------------------------------------------- + +bool CDeviceCore::InitDeviceParam( TDevice * Device, CDataMember * ParamConfig, + const char * ParentName, const char * ParentPath, CDataMember * ParentNode ) +{ + char * NodeName; + char * FullName; + char * DataPath; + CDataMember * DataNode; + CDataMember * Children; + CDataMember * ChildConfig; + CDataMember * ChildMap; + CDataMember * InitVal; TDeviceParam * Param; - TDeviceParam * Template; EDeviceDataType DataType; @@ -185,55 +294,63 @@ bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfi char * EventOut; int EventInt; - // Copy Template - Template = (Device->Template)? Device->Template->FirstParam : NULL; - while (Template) - { - if ((Param = AddDeviceParam( Device, Template->Name, Template->DataType, Template->Len ))) - { - SetParamAccess( Param, Template->Read, Template->Write ); - SetParamEvent( Param, (Template->EventChannel)? Template->EventChannel->Name : NULL, Template->EventInterval ); - - if ((Template->DataType == dtUnsigned16) || (Template->DataType == dtUnsigned32_HL) || (Template->DataType == dtUnsigned32_LH)) { - UpdateUnsignedValue( Param, *((u_int16_t*)Template->Value), Template->Changed ); - if (Template->SetChanged) - SetUnsignedValue( Param, *((u_int16_t*)Template->Value), true ); - } - else if ((Template->DataType == dtSigned16) || (Template->DataType == dtSigned32_HL) || (Template->DataType == dtSigned32_LH)) { - UpdateSignedValue( Param, *((int16_t*)Template->Value), Template->Changed ); - if (Template->SetChanged) - SetSignedValue( Param, *((int16_t*)Template->Value), true ); - } - else if ((Template->DataType == dtFloat32_L) || (Template->DataType == dtFloat32_B)) { - UpdateFloatValue( Param, *((float*)Template->Value), Template->Changed ); - if (Template->SetChanged) - SetFloatValue( Param, *((float*)Template->Value), true ); - } - else if (Template->DataType == dtString) { - UpdateStringValue( Param, (char*)Template->Value, Template->Len, Template->Changed ); - if (Template->SetChanged) - SetStringValue( Param, (char*)Template->Value, Template->Len, true ); - } - } - Template = Template->Next; + // Create Node Name + NodeName = (char*)ParamConfig->GetName(); + if (ParentName && *ParentName) { + FullName = (char*)malloc( strlen(ParentName) + strlen(NodeName) + 2 ); + sprintf( FullName, "%s_%s", ParentName, NodeName ); + } else { + FullName = strdup( NodeName ); } - // Add Parameters - ParamData = DeviceConfig->GetChFirstChild( "Parameters", true ); - while (ParamData) - { - DataType = GetDataType((char*)ParamData->GetChStr( "Type", "Unsigned16", true )); - if ((Param = AddDeviceParam( Device, ParamData->GetName(), DataType, 1 ))) - { - Read = ParamData->GetChBool( "Read", false, true ); - Write = ParamData->GetChBool( "Write", false, true ); + // Create Node Path + DataNode = (ParentNode)? ParentNode->GetChild( NodeName, true ) : NULL; + if (ParentPath && *ParentPath) { + DataPath = (char*)malloc( strlen(ParentPath) + strlen(NodeName) + 2 ); + sprintf( DataPath, "%s/%s", ParentPath, NodeName ); + } else { + DataPath = strdup( NodeName ); + } + + if ((Children = ParamConfig->GetChild( "Children", false ))) { + // Data Branch + if (Children->isString()) { + // Load from file + ChildMap = new CDataMember(); + JSONparse->SetBase( ChildMap ); + if (!JSONparse->ReadFromFile( NULL, Children->GetStr() )) { + if (Log) Log->Message( LogLevel, dlLow, "%s/%s: Fail to load parameters from file: '%s'", + ProcessName, Name, Children->GetStr() ); + } + else { + ChildConfig = ChildMap->GetFirstChild(); + while (ChildConfig) { + InitDeviceParam( Device, ChildConfig, FullName, DataPath, DataNode ); + ChildConfig = ChildConfig->GetNextPeer(); + } + } + delete ChildMap; + } + else { + // Load children + ChildConfig = Children->GetFirstChild(); + while (ChildConfig) { + InitDeviceParam( Device, ChildConfig, FullName, DataPath, DataNode ); + } + } + } + else { + // Data Leaf + DataType = GetDataType((char*)ParamConfig->GetChStr( "Type", "Unsigned16", true )); + if ((Param = AddDeviceParam( Device, FullName, DataType, 1 ))) { + // Leaf + Read = ParamConfig->GetChBool( "Read", false, true ); + Write = ParamConfig->GetChBool( "Write", false, true ); SetParamAccess( Param, Read, Write ); - EventOut = (char*)ParamData->GetChStr( "EventChannel", NULL, false ); - EventInt = ParamData->GetChInt( "EventInterval", 0, false ); - SetParamEvent( Param, EventOut, EventInt ); + SetDataPath( Param, DataPath, DataNode ); - if ((InitVal = ParamData->GetChild( "InitValue", false ))) { + if ((InitVal = ParamConfig->GetChild( "InitValue", false ))) { if ((DataType == dtUnsigned16) || (DataType == dtUnsigned32_HL) || (DataType == dtUnsigned32_LH)) { UpdateUnsignedValue( Param, InitVal->GetInt(0), Read ); if (Write) @@ -255,10 +372,15 @@ bool CDeviceCore::InitDeviceParams( TDevice * Device, CDataMember * DeviceConfi SetStringValue( Param, InitVal->GetStr(""), InitVal->GetLen(), true ); } } + + EventOut = (char*)ParamConfig->GetChStr( "EventChannel", NULL, false ); + EventInt = ParamConfig->GetChInt( "EventInterval", 0, false ); + SetParamEvent( Param, EventOut, EventInt ); } - // Read + Event Out - ParamData = ParamData->GetNextPeer(); } + + if (FullName) free( FullName ); + if (DataPath) free( DataPath ); return true; } //--------------------------------------------------------------------------- @@ -394,7 +516,7 @@ bool CDeviceCore::CheckReplyTimeout() } //--------------------------------------------------------------------------- -TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName ) +TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName, const char * DataPath ) { TDevice ** DeviceType = GetDeviceTypePtr( DeviceTypeName ); @@ -410,7 +532,8 @@ TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName ) else { *DeviceType = new TDevice; - (*DeviceType)->Type = strdup( DeviceTypeName ); + (*DeviceType)->Type = strdup( DeviceTypeName ); + (*DeviceType)->DataPath = strdup( DataPath ); if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device type '%s'", ProcessName, Name, DeviceTypeName ); @@ -419,7 +542,8 @@ TDevice * CDeviceCore::AddDeviceType( const char * DeviceTypeName ) } //--------------------------------------------------------------------------- -TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * DeviceType, const int DeviceID, const char * DeviceAddress ) +TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * DeviceType, + const int DeviceID, const char * DeviceAddress, const char * DataPath ) { TDevice ** Device = &FirstDevice; @@ -463,6 +587,18 @@ TDevice * CDeviceCore::AddDevice( const char * DeviceName, const char * DeviceTy if (DeviceType && *DeviceType) { (*Device)->Type = strdup( DeviceType ); (*Device)->Template = GetDeviceType( DeviceType ); + + if (DataPath && *DataPath) { + (*Device)->DataPath = strdup( DataPath ); + (*Device)->DataNode = ValueTree->GetChild( (*Device)->DataPath, true ); + } + else if ((*Device)->Template && (*Device)->Template->DataPath) { + // Use Template path as prefix, then add device ID or address + int PathLen = strlen((*Device)->Template->DataPath) + strlen(DeviceName) + 1; + (*Device)->DataPath = (char*)malloc(PathLen +1); + sprintf( (*Device)->DataPath, "%s/%s", (*Device)->Template->DataPath, DeviceName ); + (*Device)->DataNode = ValueTree->GetChild( (*Device)->DataPath, true ); + } } if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Added device '%s' - Tp:'%s'%s, ID:%d, Addr:'%s'", @@ -491,6 +627,8 @@ bool CDeviceCore::DestroyDevice( TDevice ** Device ) free( (*Device)->Address ); if ((*Device)->Type) free( (*Device)->Type ); + if ((*Device)->DataPath) + free( (*Device)->DataPath ); // Destroy parameters & groups while ((*Device)->FirstParam) { @@ -647,6 +785,8 @@ bool CDeviceCore::DestroyDeviceParam( TDeviceParam ** Param ) free( (*Param)->Value ); if ((*Param)->SetValue) free( (*Param)->SetValue ); + if ((*Param)->DataPath) + free( (*Param)->DataPath ); // Destroy Param delete *Param; @@ -772,6 +912,23 @@ bool CDeviceCore::DestroyParamItem( TDeviceParamItem ** Item ) } //--------------------------------------------------------------------------- +bool CDeviceCore::SetDataPath( TDeviceParam * Param, const char * DataPath, CDataMember * DataNode ) +{ + if (!Param) + return false; + + Param->DataPath = strdup( DataPath ); + Param->DataNode = DataNode; + + if (Log) { + char * DeviceName = (Param->Device->Name)? Param->Device->Name : Param->Device->Type; + Log->Message( LogLevel, dlMedium, "%s/%s: Set param '%s/%s' data ref - P:%s, N:%s", + ProcessName, Name, DeviceName, Param->Name, DataPath, ((DataNode)? DataNode->GetName() : "(none)") ); + } + return true; +} +//--------------------------------------------------------------------------- + bool CDeviceCore::SetParamAccess( TDeviceParam * Param, bool Read, bool Write ) { if (!Param) @@ -825,6 +982,9 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val // Set new value & mark change *((u_int16_t*)Param->Value) = Value; + if (Param->DataNode) + Param->DataNode->SetInt( *((u_int16_t*)Param->Value) ); + // Mark change & log event Changed = true; if (Log) { @@ -842,6 +1002,9 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val // Set new value & mark change *((u_int32_t*)Param->Value) = Value; + if (Param->DataNode) + Param->DataNode->SetInt( *((u_int32_t*)Param->Value) ); + // Mark change & log event Changed = true; if (Log) { @@ -860,6 +1023,9 @@ bool CDeviceCore::UpdateUnsignedValue( TDeviceParam * Param, const u_int32_t Val // Set new value & mark change *((u_int32_t*)Param->Value) = Value; + if (Param->DataNode) + Param->DataNode->SetInt( *((u_int32_t*)Param->Value) ); + // Mark change & log event Changed = true; if (Log) { @@ -899,6 +1065,9 @@ bool CDeviceCore::UpdateSignedValue( TDeviceParam * Param, const int32_t Value, // Set new value & mark change *((int16_t*)Param->Value) = Value; + if (Param->DataNode) + Param->DataNode->SetInt( *((int16_t*)Param->Value) ); + // Mark change & log event Changed = true; if (Log) { @@ -916,6 +1085,9 @@ bool CDeviceCore::UpdateSignedValue( TDeviceParam * Param, const int32_t Value, // Set new value & mark change *((int32_t*)Param->Value) = Value; + if (Param->DataNode) + Param->DataNode->SetInt( *((int32_t*)Param->Value) ); + // Mark change & log event Changed = true; if (Log) { @@ -956,6 +1128,9 @@ bool CDeviceCore::UpdateFloatValue( TDeviceParam * Param, const float Value, boo // Set new value & mark change *((float*)Param->Value) = Value; + if (Param->DataNode) + Param->DataNode->SetFloat( *((float*)Param->Value) ); + // Mark change & log event Changed = true; if (Log) { @@ -1005,6 +1180,9 @@ bool CDeviceCore::UpdateStringValue( TDeviceParam * Param, const char * Value, c memset( &((char*)Param->Value)[Len], 0x0, (Param->Len - Len + 1) ); // Add null teriminate } + if (Param->DataNode) + Param->DataNode->SetStr( (char*)Param->Value ); + // Mark Change Changed = true; if (Log) { diff --git a/DeviceCore.h b/DeviceCore.h index b6fcdde..1253642 100644 --- a/DeviceCore.h +++ b/DeviceCore.h @@ -42,6 +42,8 @@ struct SDevice { char * Name = NULL; int ID = 0; char * Address = NULL; + char * DataPath = NULL; + CDataMember * DataNode = NULL; // Device Type char * Type = NULL; @@ -65,6 +67,10 @@ struct SDeviceParam { EDeviceDataType DataType = dtNone; TDevice * Device = Device; + // Data Path + char * DataPath = NULL; + CDataMember * DataNode = NULL; + // Last value (received from device) void * Value = NULL; int Len = 0; @@ -117,6 +123,7 @@ protected: // Configuration CDataMember * Config = NULL; CDataMember * ConfigTypes = NULL; + CDataMember * ValueTree = NULL; CJSONparse * JSONparse = NULL; bool DeviceInit = false; @@ -306,25 +313,30 @@ public: // Configuration virtual bool Init( CDataMember * FunctionConfig ); virtual bool InitDevices( CDataMember * FunctionConfig ); - virtual bool InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig ); + virtual bool InitDeviceParams( TDevice * Device, CDataMember * DeviceConfig, CDataMember * ParentNode ); + virtual bool CopyTemplateParam( TDevice * Device, TDeviceParam * Template, CDataMember * ParentNode ); + virtual bool InitDeviceParam( TDevice * Device, CDataMember * ParamConfig, + const char * ParentName, const char * ParentPath, CDataMember * ParentNode ); virtual bool InitParamGroups( TDevice * Device, CDataMember * DeviceConfig ); // Polling parameters bool SetPollParam( int pPollInterval ); bool SetReplyParam( int pReplyTimeout, int pMaxRetries ); + bool SetDataPath( TDeviceParam * Param, const char * DataPath, CDataMember * DataNode ); bool SetParamAccess( TDeviceParam * Param, bool Read, bool Write ); bool SetParamEvent( TDeviceParam * Param, const char * ChannelName, long pEventInterval ); // Manage Devices Types - TDevice * AddDeviceType( const char * DeviceTypeName ); + TDevice * AddDeviceType( const char * DeviceTypeName, const char * DataPath ); inline bool DestroyDeviceType( const char * DeviceTypeName ) { TDevice ** DeviceType = GetDeviceTypePtr(DeviceTypeName); return (DeviceType)? DestroyDevice( DeviceType ) : false; } // Manage Devices - TDevice * AddDevice( const char * DeviceName, const char * Type = NULL, const int ID = 0, const char * Address = NULL ); + TDevice * AddDevice( const char * DeviceName, const char * Type = NULL, + const int ID = 0, const char * Address = NULL, const char * DataPath = NULL ); inline bool DestroyDevice( const char * DeviceName ) { TDevice ** Device = GetDevicePtrByName(DeviceName); return (Device)? DestroyDevice( Device ) : false; diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index bca41c0..e38081d 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -15,31 +15,16 @@ //--------------------------------------------------------------------------- +CJSONparse::CJSONparse() +{ + SetBase( NULL ); +} +//--------------------------------------------------------------------------- + CJSONparse::CJSONparse( CDataMember * pDataTree ) { - // Object tree - DataTree = pDataTree; - - // File Operation - InputHandle = -1; - OutputHandle = -1; - - Buffer = NULL; - - // Parsing operation - BufPos = NULL; - Mark = NULL; - LineNo = 0; - CharNo = 0; - RefillBuffer = false; - - // Printing operation - Spacer[0] = 0; - SpacerLen = 0; - - // Error reporting - Error = false; - ErrorText[0] = 0; + if (!SetBase( pDataTree )) + DataTree = NULL; } //--------------------------------------------------------------------------- @@ -52,6 +37,18 @@ CJSONparse::~CJSONparse() } //--------------------------------------------------------------------------- +bool CJSONparse::SetBase( CDataMember * Object ) +{ + // Validate + if (Object && !Object->isObject() && !Object->isNull()) + return false; + + // Set + DataTree = Object; + return true; +} +//--------------------------------------------------------------------------- + bool CJSONparse::WriteToScreen( const char * BasePath, const int Indent ) { // Print to screen @@ -124,6 +121,8 @@ bool CJSONparse::WriteToHandle( const char * BasePath, const int Handle, const i // Validate if (!DataTree) { + Error = true; + sprintf( ErrorText, "No Data Tree set" ); return false; } @@ -187,11 +186,6 @@ bool CJSONparse::ReadFromFile( const char * BasePath, const char * FilePath ) int Handle = -1; bool result = false; - // Validate - if (!DataTree) { - return false; - } - // Clear Error Error = false; @@ -283,7 +277,14 @@ bool CJSONparse::ReadFromBuffer( const char * BasePath ) CDataMember * BaseMember = NULL; // Validate - if (!DataTree || !Buffer) { + if (!DataTree) { + Error = true; + sprintf( ErrorText, "No Data Tree set" ); + return false; + } + if (!Buffer) { + Error = true; + sprintf( ErrorText, "No Data Buffer defined" ); return false; } diff --git a/JSONparseCore.h b/JSONparseCore.h index 1938c86..e2ce0f4 100644 --- a/JSONparseCore.h +++ b/JSONparseCore.h @@ -21,28 +21,28 @@ class CJSONparse { private: - CDataMember * DataTree; + CDataMember * DataTree = NULL; // File operation - int InputHandle; - int OutputHandle; + int InputHandle = -1; + int OutputHandle = -1; - CShiftBuffer * Buffer; + CShiftBuffer * Buffer = NULL; // Parsing operation - char * BufPos; - char * Mark; - int LineNo; - int CharNo; - bool RefillBuffer; + char * BufPos = NULL; + char * Mark = NULL; + int LineNo = 0; + int CharNo = 0; + bool RefillBuffer = false; // Printing Operation - char Spacer[100]; - int SpacerLen; + char Spacer[100] = ""; + int SpacerLen = 0; // Error - bool Error; - char ErrorText[100]; + bool Error = false; + char ErrorText[100] = ""; // Parsing functions void SkipWhiteSpace(); @@ -57,9 +57,13 @@ private: bool PrintArray( CDataMember * Object, const int Indent ); public: + CJSONparse(); CJSONparse( CDataMember * pDataTree ); ~CJSONparse(); + // Tree + bool SetBase( CDataMember * Object ); + // Buffer operation bool CreateBuffer( int pBufLen ); bool FillBuffer();