diff options
Diffstat (limited to 'gobi-api/GobiAPI_1.0.40/Core/DB2NavTree.cpp')
-rwxr-xr-x | gobi-api/GobiAPI_1.0.40/Core/DB2NavTree.cpp | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/gobi-api/GobiAPI_1.0.40/Core/DB2NavTree.cpp b/gobi-api/GobiAPI_1.0.40/Core/DB2NavTree.cpp new file mode 100755 index 0000000..3705dcf --- /dev/null +++ b/gobi-api/GobiAPI_1.0.40/Core/DB2NavTree.cpp @@ -0,0 +1,434 @@ +/*=========================================================================== +FILE: + ProtocolEntityNavTree.cpp + +DESCRIPTION: + Implementation of cDB2NavTree + +PUBLIC CLASSES AND METHODS: + sDB2NavFragment + cDB2NavTree + This class distills the database description of a protocol + entity into a simple tree structure more suited to + efficient navigation for parsing/packing + +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. +===========================================================================*/ + +//--------------------------------------------------------------------------- +// Include Files +//--------------------------------------------------------------------------- +#include "StdAfx.h" +#include "DB2NavTree.h" + +//--------------------------------------------------------------------------- +// Definitions +//--------------------------------------------------------------------------- + +/*=========================================================================*/ +// sDB2NavFragment Methods +/*=========================================================================*/ + +/*=========================================================================== +METHOD: + sDB2NavFragment (Public Method) + +DESCRIPTION: + Constructor + +RETURN VALUE: + None +===========================================================================*/ +sDB2NavFragment::sDB2NavFragment() + : mpField( 0 ), + mpFragment( 0 ), + mpNextFragment( 0 ), + mpLinkFragment( 0 ) +{ + // Nothing to do +} + +/*=========================================================================*/ +// cDB2NavTree Methods +/*=========================================================================*/ + +/*=========================================================================== +METHOD: + cDB2NavTree (Public Method) + +DESCRIPTION: + Constructor + +PARAMETERS: + db [ I ] - Database to use + +RETURN VALUE: + None +===========================================================================*/ +cDB2NavTree::cDB2NavTree( const cCoreDatabase & db ) + : mDB( db ) +{ + // Nothing to do +} + +/*=========================================================================== +METHOD: + ~cDB2NavTree (Public Method) + +DESCRIPTION: + Destructor + +RETURN VALUE: + None +===========================================================================*/ +cDB2NavTree::~cDB2NavTree() +{ + // Clean-up our fragment allocations + std::list <sDB2NavFragment *>::iterator pIter; + for (pIter = mFragments.begin(); pIter != mFragments.end(); pIter++) + { + sDB2NavFragment * pFrag = *pIter; + if (pFrag != 0) + { + delete pFrag; + } + } +} + +/*=========================================================================== +METHOD: + BuildTree (Internal Method) + +DESCRIPTION: + Build nav tree for the entity described by the given key/name + +PARAMETERS: + key [ I ] - Key into the protocol entity table + +RETURN VALUE: + bool +===========================================================================*/ +bool cDB2NavTree::BuildTree( const std::vector <ULONG> & key ) +{ + // Assume failure + bool bRC = false; + + // Look up entity definition + bool bFound = mDB.FindEntity( key, mEntity ); + + // Did we find it? + if (bFound == false) + { + // No definition in database + return bRC; + } + + // A structure to navigate? + if (mEntity.mStructID == -1) + { + bRC = true; + return bRC; + } + + const tDB2FragmentMap & structTable = mDB.GetProtocolStructs(); + + // Grab first fragment of structure + std::pair <ULONG, ULONG> id( mEntity.mStructID, 0 ); + tDB2FragmentMap::const_iterator pFrag = structTable.find( id ); + + // Nothing to navigate? + if (pFrag == structTable.end()) + { + ASSERT( 0 ); + return bRC; + } + + // No name? + if (mEntity.mpName == 0 || mEntity.mpName[0] == 0) + { + ASSERT( 0 ); + return bRC; + } + + // Process the initial structure + bRC = ProcessStruct( &pFrag->second, 0 ); + return bRC; +} + +/*=========================================================================== +METHOD: + ProcessStruct (Internal Method) + +DESCRIPTION: + Process a structure described by the given initial fragment + +PARAMETERS: + frag [ I ] - Entry point for structure + pOwner [ I ] - Owning fragment + +RETURN VALUE: + bool +===========================================================================*/ +bool cDB2NavTree::ProcessStruct( + const sDB2Fragment * pFrag, + sDB2NavFragment * pOwner ) +{ + // Assume success + bool bRC = true; + + // Grab struct ID/fragment ID from fragment + std::pair <ULONG, ULONG> key = pFrag->GetKey(); + ULONG structID = key.first; + + const tDB2FragmentMap & structTable = mDB.GetProtocolStructs(); + const tDB2FieldMap & fieldTable = mDB.GetProtocolFields(); + + // Sync iterator to fragment + tDB2FragmentMap::const_iterator pFragIter = structTable.find( key ); + if (pFragIter == structTable.end()) + { + // This should not happen + ASSERT( 0 ); + + bRC = false; + return bRC; + } + + // Fragments we allocate along the way + sDB2NavFragment * pOld = 0; + sDB2NavFragment * pNew = 0; + + // Process each fragment in the structure + while ( (pFragIter != structTable.end()) + && (pFragIter->second.mStructID == structID) ) + { + pFrag = &pFragIter->second; + + // Allocate our new fragment + pNew = new sDB2NavFragment; + if (pNew == 0) + { + bRC = false; + break; + } + + // Store DB fragemnt + pNew->mpFragment = pFrag; + mFragments.push_back( pNew ); + + // Hook previous up to us + if (pOld != 0 && pOld->mpNextFragment == 0) + { + pOld->mpNextFragment = pNew; + } + + // Hook owner up to us + if (pOwner != 0 && pOwner->mpLinkFragment == 0) + { + pOwner->mpLinkFragment = pNew; + } + + // Modified? + switch (pFrag->mModifierType) + { + case eDB2_MOD_VARIABLE_ARRAY: + case eDB2_MOD_VARIABLE_STRING1: + case eDB2_MOD_VARIABLE_STRING2: + case eDB2_MOD_VARIABLE_STRING3: + { + const tDB2Array1ModMap & arrays1 = mDB.GetArray1Mods(); + + tDB2Array1ModMap::const_iterator pTmp; + pTmp = arrays1.find( pFrag->mpModifierValue ); + + if (pTmp != arrays1.end()) + { + // We need to track the value of the given field + std::pair <bool, LONGLONG> entry( false, 0 ); + mTrackedFields[pTmp->second] = entry; + } + else + { + bRC = false; + } + } + break; + + case eDB2_MOD_VARIABLE_ARRAY2: + { + const tDB2Array2ModMap & arrays2 = mDB.GetArray2Mods(); + + tDB2Array2ModMap::const_iterator pTmp; + pTmp = arrays2.find( pFrag->mpModifierValue ); + + if (pTmp != arrays2.end()) + { + // We need to track the value of the given fields + std::pair <bool, LONGLONG> entry( false, 0 ); + mTrackedFields[pTmp->second.first] = entry; + mTrackedFields[pTmp->second.second] = entry; + } + else + { + bRC = false; + } + } + break; + + case eDB2_MOD_OPTIONAL: + { + const tDB2OptionalModMap & conditions = mDB.GetOptionalMods(); + + tDB2OptionalModMap::const_iterator pTmp; + pTmp = conditions.find( pFrag->mpModifierValue ); + + if (pTmp != conditions.end()) + { + const sDB2SimpleCondition & con = pTmp->second; + + // We need to track the value of the given field + std::pair <bool, LONGLONG> entry( false, 0 ); + mTrackedFields[con.mID] = entry; + + if (con.mbF2F == true) + { + // We need to track the value of the given field + std::pair <bool, LONGLONG> entry( false, 0 ); + mTrackedFields[(ULONG)con.mValue] = entry; + } + } + else + { + bRC = false; + } + } + break; + + case eDB2_MOD_VARIABLE_ARRAY3: + { + const tDB2ExpressionModMap & exprs = mDB.GetExpressionMods(); + + tDB2ExpressionModMap::const_iterator pTmp; + pTmp = exprs.find( pFrag->mpModifierValue ); + + if (pTmp != exprs.end()) + { + const sDB2SimpleExpression & expr = pTmp->second; + + // We need to track the value of the given field + std::pair <bool, LONGLONG> entry( false, 0 ); + mTrackedFields[expr.mID] = entry; + + if (expr.mbF2F == true) + { + // We need to track the value of the given field + std::pair <bool, LONGLONG> entry( false, 0 ); + mTrackedFields[(ULONG)expr.mValue] = entry; + } + } + else + { + bRC = false; + } + } + break; + }; + + // What type of fragment is this? + switch (pFrag->mFragmentType) + { + case eDB2_FRAGMENT_FIELD: + { + // Grab field ID + ULONG fieldID = pFrag->mFragmentValue; + + // Find field representation in database + tDB2FieldMap::const_iterator pField = fieldTable.find( fieldID ); + if (pField != fieldTable.end()) + { + pNew->mpField = &pField->second; + } + else + { + bRC = false; + } + } + break; + + case eDB2_FRAGMENT_STRUCT: + { + // Grab structure ID + ULONG structID = pFrag->mFragmentValue; + + // Grab first fragment of structure + std::pair <ULONG, ULONG> id( structID, 0 ); + tDB2FragmentMap::const_iterator pFragIterTmp; + pFragIterTmp = structTable.find( id ); + if (pFragIterTmp != structTable.end()) + { + pFrag = &pFragIterTmp->second; + bRC = ProcessStruct( pFrag, pNew ); + } + else + { + bRC = false; + } + } + break; + + case eDB2_FRAGMENT_VARIABLE_PAD_BITS: + case eDB2_FRAGMENT_VARIABLE_PAD_BYTES: + { + // We need to track the value of the given field + std::pair <bool, LONGLONG> entry( false, 0 ); + mTrackedFields[pFrag->mFragmentValue] = entry; + + bRC = true; + } + break; + + default: + bRC = true; + break; + } + + if (bRC == true) + { + pFragIter++; + + pOld = pNew; + pNew = 0; + } + else + { + break; + } + } + + return bRC; +} |