blob: 25ba606726302547547a9a1418a224e79dc0061a [file] [log] [blame]
/*===========================================================================
FILE:
CoreDatabase.h
DESCRIPTION:
Declaration of cCoreDatabase class
PUBLIC CLASSES AND METHODS:
cCoreDatabase
This class represents the run-time (read only) version of the
core library database
Copyright (c) 2011, Code Aurora Forum. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Code Aurora Forum nor
the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
===========================================================================*/
//---------------------------------------------------------------------------
// Pragmas
//---------------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------------
// Include Files
//---------------------------------------------------------------------------
#include <list>
#include <map>
#include <set>
#include <vector>
#include "DB2TextFile.h"
//---------------------------------------------------------------------------
// Forward Declarations
//---------------------------------------------------------------------------
class cDB2NavTree;
//---------------------------------------------------------------------------
// Prototypes
//---------------------------------------------------------------------------
// Convert a string (in quotes) to a string (minus) quotes and copy into
// an allocated buffer
LPCSTR CopyQuotedString( LPSTR pString );
//---------------------------------------------------------------------------
// Definitions
//---------------------------------------------------------------------------
// An empty (but not NULL) string
extern LPCSTR EMPTY_STRING;
// Value seperator for database text
extern LPCSTR DB2_VALUE_SEP;
// Sub-value (i.e. within a particular value) seperator for database text
extern LPCSTR DB2_SUBVAL_SEP;
// Database table file names
extern LPCSTR DB2_FILE_PROTOCOL_FIELD;
extern LPCSTR DB2_FILE_PROTOCOL_STRUCT;
extern LPCSTR DB2_FILE_PROTOCOL_ENTITY;
extern LPCSTR DB2_FILE_ENUM_MAIN;
extern LPCSTR DB2_FILE_ENUM_ENTRY;
// Database start pointers
extern const int _binary_QMI_Field_txt_start;
extern const int _binary_QMI_Struct_txt_start;
extern const int _binary_QMI_Entity_txt_start;
extern const int _binary_QMI_Enum_txt_start;
extern const int _binary_QMI_EnumEntry_txt_start;
// Database end pointers
extern const int _binary_QMI_Field_txt_end;
extern const int _binary_QMI_Struct_txt_end;
extern const int _binary_QMI_Entity_txt_end;
extern const int _binary_QMI_Enum_txt_end;
extern const int _binary_QMI_EnumEntry_txt_end;
// Status levels for DB2 logging
enum eDB2StatusLevel
{
eDB2_STATUS_BEGIN = -1,
eDB2_STATUS_INFO, // Informational string
eDB2_STATUS_WARNING, // Warning string
eDB2_STATUS_ERROR, // Error string
eDB2_STATUS_END
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2StatusLevel validity check
PARAMETERS:
lvl [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2StatusLevel lvl )
{
bool retVal = false;
if (lvl > eDB2_STATUS_BEGIN && lvl < eDB2_STATUS_END)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// Class cDB2StatusLog
//
// Class that defines status logging interface for DB2 initialization
// and exit related information
/*=========================================================================*/
class cDB2StatusLog
{
public:
// Log an error string
virtual void Log(
LPCSTR pLog,
eDB2StatusLevel lvl = eDB2_STATUS_ERROR ) = 0;
// Log an error string
virtual void Log(
const std::string & log,
eDB2StatusLevel lvl = eDB2_STATUS_ERROR ) = 0;
};
/*=========================================================================*/
// Class cDB2TraceLog
// Default error logging interface for DB2 initialization and exit
// related information - sends output to TRACE
/*=========================================================================*/
class cDB2TraceLog : public cDB2StatusLog
{
public:
// (Inline) Constructor
cDB2TraceLog() { };
// (Inline) Destructor
~cDB2TraceLog() { };
// (Inline) Log an error string
virtual void Log(
LPCSTR pLog,
eDB2StatusLevel lvl = eDB2_STATUS_ERROR )
{
if (pLog != 0 && pLog[0] != 0)
{
std::string formatString = "[0x%02X] ";
formatString += pLog;
formatString += '\n';
//Note: TRACE is just an alias for printf if DEBUG is used
TRACE( formatString.c_str(), lvl );
}
};
// (Inline) Log an error string
virtual void Log(
const std::string & log,
eDB2StatusLevel lvl = eDB2_STATUS_ERROR )
{
if (log.size() > 0)
{
Log( log.c_str(), lvl );
}
};
};
// The default logger (for backwards compatibility)
extern cDB2TraceLog gDB2DefaultLog;
/*===========================================================================
METHOD:
LoadDB2Table (Free Public Method)
DESCRIPTION:
Load a database table
PARAMETERS:
pFile [ I ] - The file to load the table from
cont [I/0] - The current/resulting database table
bDuplicatesOK [ I ] - Duplicate keys acceptable?
pName [ I ] - Name (for error reporting)
log [I/O] - Where to log errors
RETURN VALUE:
bool
===========================================================================*/
template <class Container>
bool LoadDB2Table(
LPCSTR pFile,
Container & cont,
bool bDuplicatesOK = false,
LPCSTR pName = 0,
cDB2StatusLog & log = gDB2DefaultLog )
{
// Assume success
bool bRC = true;
// Sanity check error reporting name
if (pName == 0 || pName[0] == 0)
{
pName = "?";
}
// Sanity check file name
if (pFile == 0 || pFile[0] == 0)
{
// Bad file
std::ostringstream tmp;
tmp << "DB [" << pName << "] Invalid file name";
log.Log( tmp.str(), eDB2_STATUS_ERROR );
return false;
}
ULONG lineNum = 0;
// Attempt to open the file
cDB2TextFile inFile( pFile );
if (inFile.IsValid() == true)
{
std::string line;
while (inFile.ReadLine( line ) == true)
{
std::string lineCopy = line;
int nLineSize = lineCopy.size();
LPSTR pLine = new CHAR[ nLineSize + 1 ];
if (pLine == NULL)
{
return false;
}
memcpy( pLine, line.c_str(), nLineSize );
// Enforce null terminator
pLine[ nLineSize ] = 0;
typename Container::mapped_type theType;
bool bOK = theType.FromString( pLine );
if (bOK == true)
{
// Grab key
typename Container::key_type theKey = theType.GetKey();
// Key already exists?
typename Container::iterator pIter;
pIter = cont.find( theKey );
if (pIter != cont.end() && bDuplicatesOK == false)
{
// The key already exists which indicates a (recoverable) error
std::ostringstream tmp;
tmp << "DB [" << pName << "] Duplicate key, line "
<< lineNum << " (" << line.c_str() << ")";
log.Log( tmp.str(), eDB2_STATUS_WARNING );
// Free the current object
pIter->second.FreeAllocatedStrings();
// ... and then replace it
pIter->second = theType;
}
else
{
typename Container::value_type entry( theKey, theType );
cont.insert( entry );
}
}
else if (lineCopy.size() > 0)
{
// Error parsing line
std::ostringstream tmp;
tmp << "DB [" << pName << "] Parsing error, line "
<< lineNum << " (" << line.c_str() << ")";
log.Log( tmp.str(), eDB2_STATUS_ERROR );
theType.FreeAllocatedStrings();
bRC = false;
}
delete [] pLine;
lineNum++;
}
}
else
{
#ifdef DEBUG
// Could not open the file
std::ostringstream tmp;
tmp << "DB [" << pName << "] Error opening file";
log.Log( tmp.str(), eDB2_STATUS_WARNING );
#endif
bRC = false;
}
return bRC;
};
/*===========================================================================
METHOD:
LoadDB2Table (Free Public Method)
DESCRIPTION:
Load a database table
PARAMETERS:
pStart [ I ] - Start location of database
nSize [ I ] - Size of database
cont [I/0] - The current/resulting database table
bDuplicatesOK [ I ] - Duplicate keys acceptable?
pName [ I ] - Name (for error reporting)
log [I/O] - Where to log errors
RETURN VALUE:
bool
===========================================================================*/
template <class Container>
bool LoadDB2Table(
const char * pStart,
const int nSize,
Container & cont,
bool bDuplicatesOK = false,
LPCSTR pName = 0,
cDB2StatusLog & log = gDB2DefaultLog )
{
// Assume success
bool bRC = true;
// Sanity check error reporting name
if (pName == 0 || pName[0] == 0)
{
pName = "?";
}
ULONG lineNum = 0;
// Attempt to open the file
cDB2TextFile inFile( pStart, nSize );
if (inFile.IsValid() == true)
{
std::string line;
while (inFile.ReadLine( line ) == true)
{
std::string lineCopy = line;
int nLineSize = lineCopy.size();
LPSTR pLine = new CHAR[ nLineSize + 1 ];
if (pLine == NULL)
{
return false;
}
memcpy( pLine, lineCopy.c_str(), nLineSize );
// Enforce null terminator
pLine[ nLineSize ] = 0;
typename Container::mapped_type theType;
bool bOK = theType.FromString( pLine );
if (bOK == true)
{
// Grab key
typename Container::key_type theKey = theType.GetKey();
// Key already exists?
typename Container::iterator pIter;
pIter = cont.find( theKey );
if (pIter != cont.end() && bDuplicatesOK == false)
{
// The key already exists which indicates a (recoverable) error
std::ostringstream tmp;
tmp << "DB [" << pName << "] Duplicate key, line "
<< lineNum << " (" << line.c_str() << ")";
log.Log( tmp.str(), eDB2_STATUS_WARNING );
// Free the current object
pIter->second.FreeAllocatedStrings();
// ... and then replace it
pIter->second = theType;
}
else
{
typename Container::value_type entry( theKey, theType );
cont.insert( entry );
}
}
else if (lineCopy.size() > 0)
{
// Error parsing line
std::ostringstream tmp;
tmp << "DB [" << pName << "] Parsing error, line "
<< lineNum << " (" << line.c_str() << ")";
log.Log( tmp.str(), eDB2_STATUS_ERROR );
theType.FreeAllocatedStrings();
bRC = false;
}
delete [] pLine;
lineNum++;
}
}
else
{
#ifdef DEBUG
// Could not open the file
std::ostringstream tmp;
tmp << "DB [" << pName << "] Error opening file";
log.Log( tmp.str(), eDB2_STATUS_WARNING );
#endif
bRC = false;
}
return bRC;
};
/*===========================================================================
METHOD:
FreeDB2Table (Free Public Method)
DESCRIPTION:
Free up the string allocations in a database table, emptying the
table in the process
PARAMETERS:
cont [ I ] - The database table
RETURN VALUE:
None
===========================================================================*/
template <class Container>
void FreeDB2Table( Container & cont )
{
typename Container::iterator pIter = cont.begin();
while (pIter != cont.end())
{
typename Container::mapped_type & theType = pIter->second;
theType.FreeAllocatedStrings();
pIter++;
}
cont.clear();
};
/*=========================================================================*/
// eDB2EntityType Enumeration
//
// Database protocol entity header/payload type enumeration
/*=========================================================================*/
enum eDB2EntityType
{
eDB2_ET_ENUM_BEGIN = -1,
eDB2_ET_DIAG_REQ, // 0 Synchronous request
eDB2_ET_DIAG_RSP, // 1 Synchronous response
eDB2_ET_DIAG_SUBSYS_REQ, // 2 Synchronous subsystem dispatch request
eDB2_ET_DIAG_SUBSYS_RSP, // 3 Synchronous subsystem dispatch response
eDB2_ET_DIAG_EVENT, // 4 Asynchronous event
eDB2_ET_DIAG_LOG, // 5 Asynchronous log
eDB2_ET_DIAG_NV_ITEM, // 6 NVRAM item read/write
eDB2_ET_RESERVED7, // 7 Reserved
eDB2_ET_RESERVED8, // 8 Reserved
eDB2_ET_DIAG_SUBSYS2_REQ, // 9 Sync subsystem V2 dispatch request
eDB2_ET_DIAG_SUBSYS2_RSP, // 10 Sync subsystem V2 dispatch response
eDB2_ET_DIAG_SUBSYS2_ASYNC, // 11 Async subsystem V2 dispatch response
eDB2_ET_QMI_BEGIN = 29, // 29 Start of QMI section
eDB2_ET_QMI_CTL_REQ, // 30 QMI CTL request
eDB2_ET_QMI_CTL_RSP, // 31 QMI CTL response
eDB2_ET_QMI_CTL_IND, // 32 QMI CTL indication
eDB2_ET_QMI_WDS_REQ, // 33 QMI WDS request
eDB2_ET_QMI_WDS_RSP, // 34 QMI WDS response
eDB2_ET_QMI_WDS_IND, // 35 QMI WDS indication
eDB2_ET_QMI_DMS_REQ, // 36 QMI DMS request
eDB2_ET_QMI_DMS_RSP, // 37 QMI DMS response
eDB2_ET_QMI_DMS_IND, // 38 QMI DMS indication
eDB2_ET_QMI_NAS_REQ, // 39 QMI NAS request
eDB2_ET_QMI_NAS_RSP, // 40 QMI NAS response
eDB2_ET_QMI_NAS_IND, // 41 QMI NAS indication
eDB2_ET_QMI_QOS_REQ, // 42 QMI QOS request
eDB2_ET_QMI_QOS_RSP, // 43 QMI QOS response
eDB2_ET_QMI_QOS_IND, // 44 QMI QOS indication
eDB2_ET_QMI_WMS_REQ, // 45 QMI WMS request
eDB2_ET_QMI_WMS_RSP, // 46 QMI WMS response
eDB2_ET_QMI_WMS_IND, // 47 QMI WMS indication
eDB2_ET_QMI_PDS_REQ, // 48 QMI PDS request
eDB2_ET_QMI_PDS_RSP, // 49 QMI PDS response
eDB2_ET_QMI_PDS_IND, // 50 QMI PDS indication
eDB2_ET_QMI_AUTH_REQ, // 51 QMI AUTH request
eDB2_ET_QMI_AUTH_RSP, // 52 QMI AUTH response
eDB2_ET_QMI_AUTH_IND, // 53 QMI AUTH indication
eDB2_ET_QMI_CAT_REQ, // 54 QMI CAT request
eDB2_ET_QMI_CAT_RSP, // 55 QMI CAT response
eDB2_ET_QMI_CAT_IND, // 56 QMI CAT indication
eDB2_ET_QMI_RMS_REQ, // 57 QMI RMS request
eDB2_ET_QMI_RMS_RSP, // 58 QMI RMS response
eDB2_ET_QMI_RMS_IND, // 59 QMI RMS indication
eDB2_ET_QMI_OMA_REQ, // 60 QMI OMA request
eDB2_ET_QMI_OMA_RSP, // 61 QMI OMA response
eDB2_ET_QMI_OMA_IND, // 62 QMI OMA indication
eDB2_ET_QMI_VOICE_REQ, // 63 QMI voice request
eDB2_ET_QMI_VOICE_RSP, // 64 QMI voice response
eDB2_ET_QMI_VOICE_IND, // 65 QMI voice indication
eDB2_ET_QMI_END, // 63 End of QMI section
eDB2_ET_ENUM_END
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2EntityType validity check
PARAMETERS:
et [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2EntityType et )
{
bool retVal = false;
if ( (et > eDB2_ET_ENUM_BEGIN && et <= eDB2_ET_DIAG_SUBSYS2_ASYNC)
|| (et > eDB2_ET_QMI_BEGIN && et < eDB2_ET_QMI_END) )
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsDiagEntityType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the DIAG protocol?
PARAMETERS:
entityType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsDiagEntityType( eDB2EntityType entityType )
{
bool retVal = false;
if (entityType == eDB2_ET_DIAG_REQ
|| entityType == eDB2_ET_DIAG_RSP
|| entityType == eDB2_ET_DIAG_SUBSYS_REQ
|| entityType == eDB2_ET_DIAG_SUBSYS_RSP
|| entityType == eDB2_ET_DIAG_EVENT
|| entityType == eDB2_ET_DIAG_LOG
|| entityType == eDB2_ET_DIAG_NV_ITEM
|| entityType == eDB2_ET_DIAG_SUBSYS2_REQ
|| entityType == eDB2_ET_DIAG_SUBSYS2_RSP
|| entityType == eDB2_ET_DIAG_SUBSYS2_ASYNC)
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsDiagEntityRequestType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the DIAG protocol and if so
does it represent a request?
PARAMETERS:
entityType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsDiagEntityRequestType( eDB2EntityType entityType )
{
bool retVal = false;
if (entityType == eDB2_ET_DIAG_REQ
|| entityType == eDB2_ET_DIAG_SUBSYS_REQ
|| entityType == eDB2_ET_DIAG_SUBSYS2_REQ)
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsDiagEntityResponseType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the DIAG protocol and if so
does it represent a response?
PARAMETERS:
entityType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsDiagEntityResponseType( eDB2EntityType entityType )
{
bool retVal = false;
if (entityType == eDB2_ET_DIAG_RSP
|| entityType == eDB2_ET_DIAG_SUBSYS_RSP
|| entityType == eDB2_ET_DIAG_SUBSYS2_RSP)
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsDiagEntityAsyncType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the DIAG protocol and if so
does it represent asynchronous incoming data?
PARAMETERS:
entityType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsDiagEntityAsyncType( eDB2EntityType entityType )
{
bool retVal = false;
if (entityType == eDB2_ET_DIAG_EVENT
|| entityType == eDB2_ET_DIAG_LOG
|| entityType == eDB2_ET_DIAG_SUBSYS2_ASYNC)
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsQMIEntityType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the QMI protocol?
PARAMETERS:
et [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsQMIEntityType( eDB2EntityType et )
{
bool retVal = false;
if (et > eDB2_ET_QMI_BEGIN && et < eDB2_ET_QMI_END)
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsQMIEntityRequestType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the QMI protocol and if so
does it represent a request?
PARAMETERS:
entityType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsQMIEntityRequestType( eDB2EntityType entityType )
{
bool retVal = false;
// One QMI service is always a triplet of REQ/RSP/IND
DWORD baseVal = (DWORD)eDB2_ET_QMI_BEGIN + 1;
if ((DWORD)entityType % baseVal == 0)
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsQMIEntityResponseType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the QMI protocol and if so
does it represent a response?
PARAMETERS:
entityType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsQMIEntityResponseType( eDB2EntityType entityType )
{
bool retVal = false;
// One QMI service is always a triplet of REQ/RSP/IND
DWORD baseVal = (DWORD)eDB2_ET_QMI_BEGIN + 1;
if ((DWORD)entityType % baseVal == 1)
{
retVal = true;
}
return retVal;
};
/*===========================================================================
METHOD:
IsQMIEntityIndicationType (Inline Method)
DESCRIPTION:
Does the eDB2EntityType value represent the QMI protocol and if so
does it represent an indication?
PARAMETERS:
entityType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsQMIEntityIndicationType( eDB2EntityType entityType )
{
bool retVal = false;
// One QMI service is always a triplet of REQ/RSP/IND
DWORD baseVal = (DWORD)eDB2_ET_QMI_BEGIN + 1;
if ((DWORD)entityType % baseVal == 2)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// eDB2FragmentType Enumeration
//
// Database fragment type enumeration - determines in what table
// (or manner) the fragment is described
/*=========================================================================*/
enum eDB2FragmentType
{
eDB2_FRAGMENT_TYPE_ENUM_BEGIN = -1,
eDB2_FRAGMENT_FIELD, // 0 Simple field fragment
eDB2_FRAGMENT_STRUCT, // 1 Structure fragment
eDB2_FRAGMENT_CONSTANT_PAD, // 2 Pad fragment, fixed length (bits)
eDB2_FRAGMENT_VARIABLE_PAD_BITS, // 3 Pad fragment, variable (bits)
eDB2_FRAGMENT_VARIABLE_PAD_BYTES, // 4 Pad fragment, variable (bytes)
eDB2_FRAGMENT_FULL_BYTE_PAD, // 5 Pad fragment, pad to a full byte
eDB2_FRAGMENT_MSB_2_LSB, // 6 Switch to MSB -> LSB order
eDB2_FRAGMENT_LSB_2_MSB, // 7 Switch to LSB -> MSB order
eDB2_FRAGMENT_TYPE_ENUM_END
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2FragmentType validity check
PARAMETERS:
fragType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2FragmentType fragType )
{
bool retVal = false;
if (fragType > eDB2_FRAGMENT_TYPE_ENUM_BEGIN
&& fragType < eDB2_FRAGMENT_TYPE_ENUM_END)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// eDB2ModifierType Enumeration
//
// Database fragment modifier type enumeration - determines how a
// fragment is modified/used
/*=========================================================================*/
enum eDB2ModifierType
{
eDB2_MOD_TYPE_ENUM_BEGIN = -1,
eDB2_MOD_NONE, // 0 Modifier is not used
eDB2_MOD_CONSTANT_ARRAY, // 1 Constant (elements) array
eDB2_MOD_VARIABLE_ARRAY, // 2 Variable (elements) array
eDB2_MOD_OBSOLETE_3, // 3 Constant (bits) array [OBS]
eDB2_MOD_OBSOLETE_4, // 4 Variable (bits) array [OBS]
eDB2_MOD_OPTIONAL, // 5 Fragment is optional
eDB2_MOD_VARIABLE_ARRAY2, // 6 Variable (elements) array, start/stop given
eDB2_MOD_VARIABLE_ARRAY3, // 7 Variable (elements) array, simple expression
eDB2_MOD_VARIABLE_STRING1, // 8 Variable length string (bit length)
eDB2_MOD_VARIABLE_STRING2, // 9 Variable length string (byte length)
eDB2_MOD_VARIABLE_STRING3, // 10 Variable length string (character length)
eDB2_MOD_TYPE_ENUM_END
};
/*===========================================================================
METHOD:
ModifiedToArray (Inline Method)
DESCRIPTION:
Does this modifier indicate an array?
PARAMETERS:
modType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool ModifiedToArray( eDB2ModifierType modType )
{
bool bRC = false;
if ( (modType == eDB2_MOD_CONSTANT_ARRAY)
|| (modType == eDB2_MOD_VARIABLE_ARRAY)
|| (modType == eDB2_MOD_VARIABLE_ARRAY2)
|| (modType == eDB2_MOD_VARIABLE_ARRAY3) )
{
bRC = true;
}
return bRC;
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2ModifierType validity check
PARAMETERS:
modType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2ModifierType modType )
{
bool retVal = false;
if (modType > eDB2_MOD_TYPE_ENUM_BEGIN
&& modType < eDB2_MOD_TYPE_ENUM_END)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// eDB2FieldType Enumeration
//
// Database field type enumeration - determines whether the field in
// question is a standard type or an enumeration
/*=========================================================================*/
enum eDB2FieldType
{
eDB2_FIELD_TYPE_ENUM_BEGIN = -1,
eDB2_FIELD_STD, // 0 Field is a standard type (see below)
eDB2_FIELD_ENUM_UNSIGNED, // 1 Field is an unsigned enumerated type
eDB2_FIELD_ENUM_SIGNED, // 2 Field is a signed enumerated type
eDB2_FIELD_TYPE_ENUM_END
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2FieldType validity check
PARAMETERS:
fieldType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2FieldType fieldType )
{
bool retVal = false;
if (fieldType > eDB2_FIELD_TYPE_ENUM_BEGIN
&& fieldType < eDB2_FIELD_TYPE_ENUM_END)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// eDB2StdFieldType Enumeration
//
// Database standard field type enumeration
/*=========================================================================*/
enum eDB2StdFieldType
{
eDB2_FIELD_STDTYPE_ENUM_BEGIN = -1,
eDB2_FIELD_STDTYPE_BOOL, // 0 Field is a boolean (0/1, false/true)
eDB2_FIELD_STDTYPE_INT8, // 1 Field is 8-bit signed integer
eDB2_FIELD_STDTYPE_UINT8, // 2 Field is 8-bit unsigned integer
eDB2_FIELD_STDTYPE_INT16, // 3 Field is 16-bit signed integer
eDB2_FIELD_STDTYPE_UINT16, // 4 Field is 16-bit unsigned integer
eDB2_FIELD_STDTYPE_INT32, // 5 Field is 32-bit signed integer
eDB2_FIELD_STDTYPE_UINT32, // 6 Field is 32-bit unsigned integer
eDB2_FIELD_STDTYPE_INT64, // 7 Field is 64-bit signed integer
eDB2_FIELD_STDTYPE_UINT64, // 8 Field is 64-bit unsigned integer
eDB2_FIELD_STDTYPE_STRING_A, // 9 ANSI fixed length string
eDB2_FIELD_STDTYPE_STRING_U, // 10 UNICODE fixed length string
eDB2_FIELD_STDTYPE_STRING_ANT, // 11 ANSI NULL terminated string
eDB2_FIELD_STDTYPE_STRING_UNT, // 12 UNICODE NULL terminated string
eDB2_FIELD_STDTYPE_FLOAT32, // 13 Field is 32-bit floating point value
eDB2_FIELD_STDTYPE_FLOAT64, // 14 Field is 64-bit floating point value
eDB2_FIELD_STDTYPE_STRING_U8, // 15 UTF-8 encoded fixed length string
eDB2_FIELD_STDTYPE_STRING_U8NT, // 16 UTF-8 encoded NULL terminated string
eDB2_FIELD_STDTYPE_ENUM_END
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2StdFieldType validity check
PARAMETERS:
fieldType [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2StdFieldType fieldType )
{
bool retVal = false;
if (fieldType > eDB2_FIELD_STDTYPE_ENUM_BEGIN
&& fieldType < eDB2_FIELD_STDTYPE_ENUM_END)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// eDB2Operator Enumeration
//
// Database conditional fragment operator type enumeration
/*=========================================================================*/
enum eDB2Operator
{
eDB2_OP_TYPE_ENUM_BEGIN = -1,
eDB2_OP_LT,
eDB2_OP_LTE,
eDB2_OP_EQ,
eDB2_OP_NEQ,
eDB2_OP_GTE,
eDB2_OP_GT,
eDB2_OP_DIV,
eDB2_OP_NDIV,
eDB2_OP_TYPE_ENUM_END
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2Operator validity check
PARAMETERS:
op [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2Operator op )
{
bool retVal = false;
if (op > eDB2_OP_TYPE_ENUM_BEGIN
&& op < eDB2_OP_TYPE_ENUM_END)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// eDB2ExpOperator Enumeration
//
// Database simple expression operator type enumeration
/*=========================================================================*/
enum eDB2ExpOperator
{
eDB2_EXPOP_TYPE_ENUM_BEGIN = -1,
eDB2_EXPOP_ADD,
eDB2_EXPOP_SUB,
eDB2_EXPOP_MUL,
eDB2_EXPOP_DIV,
eDB2_EXPOP_REM,
eDB2_EXPOP_MIN,
eDB2_EXPOP_MAX,
eDB2_EXPOP_TYPE_ENUM_END
};
/*===========================================================================
METHOD:
IsValid (Inline Method)
DESCRIPTION:
eDB2ExpOperator validity check
PARAMETERS:
op [ I ] - Enum value being verified
RETURN VALUE:
bool
===========================================================================*/
inline bool IsValid( eDB2ExpOperator op )
{
bool retVal = false;
if (op > eDB2_EXPOP_TYPE_ENUM_BEGIN
&& op < eDB2_EXPOP_TYPE_ENUM_END)
{
retVal = true;
}
return retVal;
};
/*=========================================================================*/
// Struct sDB2ProtocolEntity
//
// Structure that defines the schema for the protocol entity table
/*=========================================================================*/
struct sDB2ProtocolEntity
{
public:
// (Inline) Default constructor
sDB2ProtocolEntity()
: mType( eDB2_ET_ENUM_BEGIN ),
mStructID( -1 ),
mFormatID( -1 ),
mbInternal( false ),
mFormatExID( -1 ),
mpName( EMPTY_STRING )
{ };
// (Inline) Free up our allocated strings
void FreeAllocatedStrings()
{
if (mpName != 0 && mpName != EMPTY_STRING)
{
delete [] mpName;
mpName = 0;
}
};
// (Inline) Return object key
std::vector <ULONG> GetKey() const
{
return mID;
};
// Populate this object from a string
bool FromString( LPSTR pStr );
// Is this object valid?
bool IsValid() const;
/* Type of protocol entity 'header/payload' */
eDB2EntityType mType;
/* Multi-value ID (includes above type) */
std::vector <ULONG> mID;
/* Associated structure ID (-1 = no structure) */
int mStructID;
/* Associated format specifier (-1 = none) */
int mFormatID;
/* Is this protocol entity internal only? */
bool mbInternal;
/* Associated extended format specifier (-1 = none) */
int mFormatExID;
/* Name of protocol entity */
LPCSTR mpName;
};
/*=========================================================================*/
// Struct sDB2Fragment
//
// Structure that defines the schema for the protocol structure table
/*=========================================================================*/
struct sDB2Fragment
{
public:
// (Inline) Default constructor
sDB2Fragment()
: mStructID( 0 ),
mFragmentOrder( 0 ),
mFragmentOffset( 0 ),
mFragmentType( eDB2_FRAGMENT_TYPE_ENUM_BEGIN ),
mFragmentValue( 0 ),
mModifierType( eDB2_MOD_TYPE_ENUM_BEGIN ),
mpModifierValue( EMPTY_STRING ),
mpName( EMPTY_STRING )
{ };
// (Inline) Free up our allocated strings
void FreeAllocatedStrings()
{
if (mpName != 0 && mpName != EMPTY_STRING)
{
delete [] mpName;
mpName = 0;
}
if (mpModifierValue != 0 && mpModifierValue != EMPTY_STRING)
{
delete [] mpModifierValue;
mpModifierValue = 0;
}
};
// (Inline) Return object key
std::pair <ULONG, ULONG> GetKey() const
{
std::pair <ULONG, ULONG> key( mStructID, mFragmentOrder );
return key;
};
// Populate this object from a string
bool FromString( LPSTR pStr );
// Is this object valid?
bool IsValid() const;
// Build a simple condition string
static std::string BuildCondition(
ULONG id,
eDB2Operator op,
LONGLONG val,
bool bF2F );
// Evaluate a simple condition
static bool EvaluateCondition(
LONGLONG valA,
eDB2Operator op,
LONGLONG valB );
// Parse a simple condition
static bool ParseCondition(
LPCSTR pCondition,
ULONG & id,
eDB2Operator & op,
LONGLONG & val,
bool & bF2F );
// Build a simple expression string
static std::string BuildExpression(
ULONG id,
eDB2ExpOperator op,
LONGLONG val,
bool bF2F );
// Evaluate a simple expression
static bool EvaluateExpression(
LONGLONG valA,
eDB2ExpOperator op,
LONGLONG valB,
LONGLONG & res );
// Parse a simple expression
static bool ParseExpression(
LPCSTR pExpr,
ULONG & id,
eDB2ExpOperator & op,
LONGLONG & val,
bool & bF2F );
/* Enclosing structure ID */
ULONG mStructID;
/* Order of fragment within structure */
ULONG mFragmentOrder;
/* Offset (in bits) of fragment from beginning of enclosing structure */
int mFragmentOffset;
/* Fragment type, how to interpret the following fragment value */
eDB2FragmentType mFragmentType;
/* Fragment Value */
ULONG mFragmentValue;
/* Modifier type, how to interpret the following modifier value */
eDB2ModifierType mModifierType;
/* Modifier value */
LPCSTR mpModifierValue;
/* Fragment Name */
LPCSTR mpName;
};
/*=========================================================================*/
// Struct sDB2Field
//
// Structure that defines the schema for the protocol field table
/*=========================================================================*/
struct sDB2Field
{
public:
// (Inline) Default constructor
sDB2Field()
: mID( 0 ),
mSize( 0 ),
mType( eDB2_FIELD_TYPE_ENUM_BEGIN ),
mTypeVal( 0 ),
mbHex( false ),
mbInternal( false ),
mDescriptionID( -1 ),
mpName( EMPTY_STRING )
{ };
// (Inline) Free up our allocated strings
void FreeAllocatedStrings()
{
if ( (mpName != 0)
&& (mpName != EMPTY_STRING) )
{
delete [] mpName;
mpName = 0;
}
};
// (Inline) Return object key
ULONG GetKey() const
{
return mID;
};
// Populate this object from a string
bool FromString( LPSTR pStr );
// Is this object valid?
bool IsValid() const;
/* Field ID */
ULONG mID;
/* Size of field (in bits, maximum is 64 bits for integral types) */
ULONG mSize;
/* Field type */
eDB2FieldType mType;
/* Actual field type (eDB2StdFieldType or enum ID) */
ULONG mTypeVal;
/* Display integral fields as hexadecimal? */
bool mbHex;
/* Is this field internal only? */
bool mbInternal;
/* Description of field */
int mDescriptionID;
/* Field name */
LPCSTR mpName;
};
/*=========================================================================*/
// Struct sDB2Category
//
// Structure that defines the generic category table schema, gives
// category ID, category name, category description, and parent
// category relationship (specified as a category ID into the very
// same table)
/*=========================================================================*/
struct sDB2Category
{
public:
// (Inline) Default constructor
sDB2Category()
: mID( 0 ),
mParentID( -1 ),
mpName( EMPTY_STRING ),
mDescriptionID( -1 )
{ };
// (Inline) Free up our allocated strings
void FreeAllocatedStrings()
{
if (mpName != 0 && mpName != EMPTY_STRING)
{
delete [] mpName;
mpName = 0;
}
};
// (Inline) Return object key
ULONG GetKey() const
{
return mID;
};
// Populate this object from a string
bool FromString( LPSTR pStr );
// Is this object valid?
bool IsValid() const;
/* Category ID */
ULONG mID;
/* Category ID of parent, -1 implies no parent/category is at root */
int mParentID;
/* Category display name */
LPCSTR mpName;
/* Description of category */
int mDescriptionID;
};
/*===========================================================================
METHOD:
ValidateDB2Categories (Public Method)
DESCRIPTION:
Validate the relationship between a pair of DB category/reference tables
NOTE: Discovered problems will be repaired, i.e. bogus/problematic
category IDs are reset to -1
PARAMETERS:
catMap [ I ] - The category table
refMap [ I ] - The reference table
pName [ I ] - Table name (for error reporting)
log [ I ] - Error log
RETURN VALUE:
bool
===========================================================================*/
template <class Key, class NamedType>
bool ValidateDB2Categories(
std::map <ULONG, sDB2Category> & catMap,
std::map <Key, NamedType> & refMap,
LPCSTR pName,
cDB2StatusLog & log = gDB2DefaultLog )
{
// Assume success
bool bRC = true;
std::string err;
// Sanity check table name
if (pName == 0 || pName[0] == 0)
{
pName = "?";
}
// First validate/repair category map; stage 1: bad parent IDs
std::map <ULONG, sDB2Category>::iterator pCats = catMap.begin();
while (pCats != catMap.end())
{
sDB2Category & cat = pCats->second;
pCats++;
if (cat.IsValid() == false)
{
continue;
}
// The parent ID must be -1 or exist in the category map
if (cat.mParentID != -1)
{
if (catMap.find( cat.mParentID ) == catMap.end())
{
// Unable to locate parent category
std::ostringstream tmp;
tmp << "DB [" << pName << "] Missing ID, parent ID "
<< cat.mParentID;
log.Log( tmp.str(), eDB2_STATUS_ERROR );
cat.mParentID = -1;
bRC = false;
}
}
}
// Validate/repair category map; stage 2: loop detection
pCats = catMap.begin();
while (pCats != catMap.end())
{
std::set <int> catsVisited;
sDB2Category & cat = pCats->second;
// Itererate up through parents
int parentID = cat.mParentID;
while (parentID != -1)
{
// Have we already been here?
if (catsVisited.find( parentID ) == catsVisited.end())
{
// Nope, add ID and go on to the next one
catsVisited.insert( parentID );
std::map <ULONG, sDB2Category>::iterator pParent;
pParent = catMap.find( parentID );
parentID = pParent->second.mParentID;
}
else
{
// Yes, we are caught in a loop
std::ostringstream tmp;
tmp << "DB [" << pName << "] Loop in category, parent ID "
<< cat.mParentID;
log.Log( tmp.str(), eDB2_STATUS_ERROR );
cat.mParentID = -1;
bRC = false;
break;
}
}
pCats++;
}
// Validate that each reference references valid category IDs
typename std::map <Key, NamedType>::iterator pTypes = refMap.begin();
while (pTypes != refMap.end())
{
NamedType & theType = pTypes->second;
std::set <int> cats = theType.mCategoryIDs;
std::set <int>::iterator pRefCats = cats.begin();
while (pRefCats != cats.end())
{
if (*pRefCats != -1)
{
pCats = catMap.find( *pRefCats );
if (pCats == catMap.end())
{
// Unable to locate category
std::ostringstream tmp;
tmp << "DB [" << pName << "] Missing ID, category ID "
<< *pRefCats << ", reference " << theType.mpName;
log.Log( tmp.str(), eDB2_STATUS_ERROR );
cats.erase(pRefCats);
cats.insert(-1);
bRC = false;
}
}
pRefCats++;
}
pTypes++;
}
return bRC;
};
/*=========================================================================*/
// Struct sDB2NVItem
//
// NVRAM item structure for database schema
/*=========================================================================*/
struct sDB2NVItem
{
public:
// (Inline) Default constructor
sDB2NVItem()
: mItem( 0 ),
mpName( EMPTY_STRING ),
mDescriptionID( -1 )
{ };
// (Inline) Free up our allocated strings
void FreeAllocatedStrings()
{
if (mpName != 0 && mpName != EMPTY_STRING)
{
delete [] mpName;
mpName = 0;
}
};
// (Inline) Return object key
ULONG GetKey() const
{
return mItem;
};
// Populate this object from a string
bool FromString( LPSTR pStr );
// Is this object valid?
bool IsValid() const;
/* Category IDs (indices into NV items category table) */
std::set <int> mCategoryIDs;
/* Item number */
ULONG mItem;
/* NV item display name */
LPCSTR mpName;
/* Description of NV item */
int mDescriptionID;
};
/*=========================================================================*/
// Struct sDB2Enum
//
// Structure that defines the schema for the enum table
/*=========================================================================*/
struct sDB2Enum
{
public:
// (Inline) Default constructor
sDB2Enum()
: mID( 0 ),
mbInternal( false ),
mpName( EMPTY_STRING ),
mDescriptionID( -1 )
{ };
// (Inline) Free up our allocated strings
void FreeAllocatedStrings()
{
if (mpName != 0 && mpName != EMPTY_STRING)
{
delete [] mpName;
mpName = 0;
}
};
// (Inline) Return object key
ULONG GetKey() const
{
return mID;
};
// Populate this object from a string
bool FromString( LPSTR pStr );
// Is this object valid?
bool IsValid() const;
/* Enum ID */
ULONG mID;
/* Is this enum used internally? */
bool mbInternal;
/* Description of enum */
int mDescriptionID;
/* Name of enum */
LPCSTR mpName;
};
/*=========================================================================*/
// Struct sDB2EnumEntry
//
// Structure that defines the schema for the enum entry table
/*=========================================================================*/
struct sDB2EnumEntry
{
public:
// (Inline) Default constructor
sDB2EnumEntry()
: mID( 0 ),
mValue( -1 ),
mbHex( false ),
mpName( EMPTY_STRING ),
mDescriptionID( -1 )
{ };
// (Inline) Free up our allocated strings
void FreeAllocatedStrings()
{
if (mpName != 0 && mpName != EMPTY_STRING)
{
delete [] mpName;
mpName = 0;
}
};
// (Inline) Return object key
std::pair <ULONG, int> GetKey() const
{
std::pair <ULONG, int> key( mID, mValue );
return key;
};
// (Inline) Populate this object from a string
bool FromString( LPSTR pStr );
// Is this object valid?
bool IsValid() const;
/* Enum ID */
ULONG mID;
/* Enum entry value */
int mValue;
/* Hexadecimal flag */
bool mbHex;
/* Enum value name */
LPCSTR mpName;
/* Description of enum value */
int mDescriptionID;
};
/*=========================================================================*/
// Struct sDB2SimpleCondition
//
// Structure that defines a (parsed) simple condition modifier
/*=========================================================================*/
struct sDB2SimpleCondition
{
public:
// (Inline) Default constructor
sDB2SimpleCondition()
: mID( 0 ),
mOperator( eDB2_OP_TYPE_ENUM_BEGIN ),
mValue( 0 ),
mbF2F( false )
{ };
// (Inline) Is this object valid?
bool IsValid() const
{
return ::IsValid( mOperator );
};
/* ID of field whose value is to be used */
ULONG mID;
/* Operator to be used */
eDB2Operator mOperator;
/* Value (or field ID) to compare against */
LONGLONG mValue;
/* Field to field expression? */
bool mbF2F;
};
/*=========================================================================*/
// Struct sDB2SimpleExpression
//
// Structure that defines a (parsed) simple expression
/*=========================================================================*/
struct sDB2SimpleExpression
{
public:
// (Inline) Default constructor
sDB2SimpleExpression()
: mID( 0 ),
mOperator( eDB2_EXPOP_TYPE_ENUM_BEGIN ),
mValue( 0 ),
mbF2F( false )
{ };
// (Inline) Is this object valid?
bool IsValid() const
{
return (::IsValid( mOperator ) && mValue != 0);
};
/* ID of field whose value is to be used */
ULONG mID;
/* Operator to be used */
eDB2ExpOperator mOperator;
/* Value (or field ID) to compare against */
LONGLONG mValue;
/* Field to field expression? */
bool mbF2F;
};
/*=========================================================================*/
// Struct sLPCSTRCmp
//
// Structure that defines the '<' operator for string comparison
/*=========================================================================*/
struct sLPCSTRCmp
{
public:
// (Inline) Is A < B?
bool operator () (
LPCSTR pStrA,
LPCSTR pStrB ) const
{
bool bLess = false;
if (pStrA != 0 && pStrB != 0)
{
bLess = (strcmp( pStrA, pStrB ) < 0);
}
return bLess;
};
};
/*=========================================================================*/
// Case insensitive compare function
/*=========================================================================*/
inline bool InsensitiveCompare( CHAR first, CHAR second )
{
return tolower( first ) < tolower( second );
}
/*=========================================================================*/
// Struct sLPCSTRCmpI
//
// Structure that defines the '<' operator for string comparison
// (case insensitive version)
/*=========================================================================*/
struct sLPCSTRCmpI
{
public:
// (Inline) Is A < B?
bool operator () (
LPCSTR pStrA,
LPCSTR pStrB ) const
{
bool bLess = false;
if (pStrA != 0 && pStrB != 0)
{
// Is there a simpler stl function for this?
bLess = std::lexicographical_compare( pStrA,
pStrA +
strlen( pStrA ),
pStrB,
pStrB +
strlen( pStrB ),
InsensitiveCompare );
}
return bLess;
};
};
//---------------------------------------------------------------------------
// Typedefs
//---------------------------------------------------------------------------
// The protocol entity table expressed as a type
typedef std::multimap <std::vector <ULONG>, sDB2ProtocolEntity> tDB2EntityMap;
// Protocol entity entity name to ID (reverse) table
typedef std::map <LPCSTR, std::vector <ULONG>, sLPCSTRCmpI> tDB2EntityNameMap;
// The struct table expressed as a type
typedef std::map <std::pair <ULONG, ULONG>, sDB2Fragment> tDB2FragmentMap;
// The field table expressed as a type
typedef std::map <ULONG, sDB2Field> tDB2FieldMap;
// A generic category table expressed as a type
typedef std::map <ULONG, sDB2Category> tDB2CategoryMap;
// NV item table expressed as a map type
typedef std::map <ULONG, sDB2NVItem> tDB2NVMap;
// Enum table expressed as a map type
typedef std::map <ULONG, sDB2Enum> tDB2EnumNameMap;
// Enum entry table expressed as a map type
typedef std::map <std::pair <ULONG, int>, sDB2EnumEntry> tDB2EnumEntryMap;
// The built enumeration map
typedef std::pair < ULONG, std::map <int, LPCSTR> > tDB2EnumMapPair;
typedef std::map <LPCSTR, tDB2EnumMapPair, sLPCSTRCmp> tDB2EnumMap;
// Parsed fragment modifier map - optional fragment
typedef std::map <LPCSTR, sDB2SimpleCondition> tDB2OptionalModMap;
// Parsed fragment modifier map - simple expression based sizes
typedef std::map <LPCSTR, sDB2SimpleExpression> tDB2ExpressionModMap;
// Parsed fragment modifier map - element count specified arrays
typedef std::map <LPCSTR, ULONG> tDB2Array1ModMap;
// Parsed fragment modifier map - start/stop index specified arrays
typedef std::map <LPCSTR, std::pair <ULONG, ULONG> > tDB2Array2ModMap;
// A protocol entity navigation map expressed as a type
typedef std::map <std::vector <ULONG>, cDB2NavTree *> tDB2EntityNavMap;
/*=========================================================================*/
// Class cCoreDatabase
/*=========================================================================*/
class cCoreDatabase
{
public:
// Constructor
cCoreDatabase();
// Destructor
virtual ~cCoreDatabase();
// Initialize the database - must be done once (and only once) prior
// to any database object access
virtual bool Initialize( LPCSTR pBasePath );
virtual bool Initialize();
// Exit (cleanup) the database
virtual void Exit();
// Get the entity navigation tree for the given protocol entity, if
// none exists one will be built and returned
const cDB2NavTree * GetEntityNavTree(
const std::vector <ULONG> & key ) const;
// Find the protocol entity with the specified key
bool FindEntity(
const std::vector <ULONG> & key,
sDB2ProtocolEntity & entity ) const;
// Find the protocol entity with the specified name
bool FindEntity(
LPCSTR pEntityName,
sDB2ProtocolEntity & entity ) const;
// Map a protocol entity name to an ID
bool MapEntityNameToID(
LPCSTR pName,
std::vector <ULONG> & key ) const;
// Map the given enum value (specified by enum ID, and enum value)
// to the enum value name string
std::string MapEnumToString(
ULONG enumID,
int enumVal,
bool bSimpleErrFmt = false,
bool bHex = false ) const;
// Map the given enum value (specified by enum name, and enum value)
// to the enum value name string
std::string MapEnumToString(
LPCSTR pEnumName,
int enumVal,
bool bSimpleErrFmt = false,
bool bHex = false ) const;
// (Inline) Set status log (object must exist for the duration of
// the DB or at least until being reset)
void SetLog( cDB2StatusLog * pLog )
{
if (pLog != 0)
{
mpLog = pLog;
}
};
// (Inline) Return protocol entities
const tDB2EntityMap & GetProtocolEntities() const
{
return mProtocolEntities;
};
// (Inline) Return protocol entity names
const tDB2EntityNameMap & GetProtocolEntityNames() const
{
return mEntityNames;
};
// (Inline) Return protocol structures
const tDB2FragmentMap & GetProtocolStructs() const
{
return mEntityStructs;
};
// (Inline) Return protocol fields
const tDB2FieldMap & GetProtocolFields() const
{
return mEntityFields;
};
// (Inline) Return assembled enumeration map
const tDB2EnumMap & GetEnums() const
{
return mEnumMap;
};
// (Inline) Return raw enumeration map
const tDB2EnumNameMap & GetRawEnums() const
{
return mEnumNameMap;
};
// (Inline) Return raw enumeration entry map
const tDB2EnumEntryMap & GetRawEnumEntries() const
{
return mEnumEntryMap;
};
// (Inline) Return parsed fragment modifier map - optional
const tDB2OptionalModMap & GetOptionalMods() const
{
return mOptionalModMap;
};
// (Inline) Return parsed fragment modifier map - expressions
const tDB2ExpressionModMap & GetExpressionMods() const
{
return mExpressionModMap;
};
// (Inline) Return parsed fragment modifier map - element
// count specified arrays
const tDB2Array1ModMap & GetArray1Mods() const
{
return mArray1ModMap;
};
// (Inline) Return parsed fragment modifier map - start/stop
// index specified arrays
const tDB2Array2ModMap & GetArray2Mods() const
{
return mArray2ModMap;
};
protected:
// Assemble the internal enum map
bool AssembleEnumMap();
// Assemble the internal protocol entity name map
bool AssembleEntityNameMap();
// Build the modifier tables
bool BuildModifierTables();
// Check and set the passed in path to something that is useful
std::string CheckAndSetBasePath( LPCSTR pBasePath ) const;
// Load all tables related to structure (entity, struct, field)
bool LoadStructureTables( LPCSTR pBasePath );
bool LoadStructureTables();
// Load all enumeration related tables
bool LoadEnumTables( LPCSTR pBasePath );
bool LoadEnumTables();
// Validate (and attempt repair of) structure related tables
bool ValidateStructures();
// Validate a single structure
bool ValidateStructure(
ULONG structID,
std::set <ULONG> & fields,
ULONG depth );
// Validate a single field
bool ValidateField(
ULONG structID,
ULONG fieldID,
std::set <ULONG> & fields );
// Validate an array specifier
bool ValidateArraySpecifier(
const sDB2Fragment & frag,
const std::set <ULONG> & fields );
// Validate a simple optional fragment specifier
bool ValidateOptionalSpecifier(
const sDB2Fragment & frag,
const std::set <ULONG> & fields );
// Validate a simple expression fragment specifier
bool ValidateExpressionSpecifier(
const sDB2Fragment & frag,
const std::set <ULONG> & fields );
/* Status log */
cDB2StatusLog * mpLog;
/* Protocol entity table, referenced by multi-value key */
tDB2EntityMap mProtocolEntities;
/* Protocol entity keys, referenced by indexed by entity name */
tDB2EntityNameMap mEntityNames;
/* The on-demand Protocol entity navigation map */
mutable tDB2EntityNavMap mEntityNavMap;
/* Protocol entity struct table, indexed by struct ID & fragment order */
tDB2FragmentMap mEntityStructs;
/* Protocol entity field table, indexed by field ID */
tDB2FieldMap mEntityFields;
/* Enum map, indexed by enum ID */
tDB2EnumNameMap mEnumNameMap;
/* Enum entry map, indexed by enum ID/value pair */
tDB2EnumEntryMap mEnumEntryMap;
/* The assembled enum map */
tDB2EnumMap mEnumMap;
/* Parsed fragment modifier map - optional fragments */
tDB2OptionalModMap mOptionalModMap;
/* Parsed fragment modifier map - expression fragments */
tDB2ExpressionModMap mExpressionModMap;
/* Parsed fragment modifier map - element count specified arrays */
tDB2Array1ModMap mArray1ModMap;
/* Parsed fragment modifier map - start/stop index specified arrays */
tDB2Array2ModMap mArray2ModMap;
};