windows-nt/Source/XPSP1/NT/net/snmp/compiler/mibccv2/oidtof.cpp
2020-09-26 16:20:57 +08:00

253 lines
6 KiB
C++

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <fstream.h>
#include <afx.h>
#include <afxtempl.h>
#include <objbase.h>
#include <afxwin.h>
#include <afxole.h>
#include <afxmt.h>
#include <wchar.h>
#include <process.h>
#include <objbase.h>
#include <initguid.h>
#include <bool.hpp>
#include <nString.hpp>
#include <ui.hpp>
#include <symbol.hpp>
#include <type.hpp>
#include <value.hpp>
#include <valueRef.hpp>
#include <typeRef.hpp>
#include <oidValue.hpp>
#include <objType.hpp>
#include <objTypV1.hpp>
#include <objTypV2.hpp>
#include <objId.hpp>
#include <trapType.hpp>
#include <notType.hpp>
#include <group.hpp>
#include <notGroup.hpp>
#include <module.hpp>
#include <sValues.hpp>
#include <lex_yy.hpp>
#include <ytab.hpp>
#include <errorMsg.hpp>
#include <errorCon.hpp>
#include <scanner.hpp>
#include <parser.hpp>
#include <apTree.hpp>
#include <oidTree.hpp>
#include <pTree.hpp>
#include "Debug.hpp"
#include "Oid.hpp"
#include "OidToF.hpp"
#include "Configs.hpp"
extern Configs theConfigs;
OidToFile::OidToFile()
{
m_hMibFile = NULL;
m_pszMibFilename = NULL;
}
// DESCRIPTION:
// wrapper for the base class Scan();
// it find first the sizes of subtrees (subtree's root node included)
// RETURN VALUE:
// 0 on success
// -1 on failure;
int OidToFile::Scan()
{
SIMCOidTreeNode *pOidNode;
SIMCNodeList recursionTrace;
// get the root node from the oid tree,
// return "error" if no tree or no root
_VERIFY(m_pOidTree != NULL, -1);
pOidNode = (SIMCOidTreeNode *)m_pOidTree->GetRoot();
_VERIFY(pOidNode != NULL, -1);
// node hasn't been scanned; _lParam=number of dependencies
pOidNode->_lParam = (DWORD)pOidNode->GetListOfChildNodes()->GetCount();
// initialize the recursionTree with the root node
_VERIFY(recursionTrace.AddHead(pOidNode)!=NULL, -1);
// start to scan the tree
while (!recursionTrace.IsEmpty())
{
const SIMCNodeList *pLstChildren;
// allways pick up the node in the head of the list
pOidNode = recursionTrace.GetHead();
// get the dependencies list
pLstChildren = pOidNode->GetListOfChildNodes();
// if there are no more dependencies to process
// sum the children values and add to its own
if (pOidNode->_lParam == 0)
{
SIMCOidTreeNode *pParent;
const char * cszSymbol = NULL;
_VERIFY(GetNodeSymbol(pOidNode, cszSymbol)==0, -1);
pOidNode->_lParam = sizeof(T_FILE_NODE_EX) + (cszSymbol != NULL ? strlen(cszSymbol) : 0);
// compute the cumulated size of the subtree
for (POSITION p = pLstChildren->GetHeadPosition(); p != NULL;)
{
const SIMCOidTreeNode *pChild;
pChild = pLstChildren->GetNext(p);
_VERIFY(pChild!=NULL, -1);
// Modify here!!!!
pOidNode->_lParam += pChild->_lParam;
}
// decrease the number of dependencies from the parent node
pParent = m_pOidTree->GetParentOf(pOidNode);
if ( pParent != NULL)
{
pParent->_lParam--;
}
// delete the node from the list
recursionTrace.RemoveHead();
}
else
{
// add the children list to the front of the recursionTrace
for (POSITION p = pLstChildren->GetHeadPosition(); p != NULL;)
{
SIMCOidTreeNode *pChild;
pChild = pLstChildren->GetNext(p);
_VERIFY(pChild!=NULL, -1);
pChild->_lParam = (DWORD)pChild->GetListOfChildNodes()->GetCount();
_VERIFY(recursionTrace.AddHead(pChild)!=NULL, -1);
}
}
}
return OidTreeScanner::Scan();
}
// DESCRIPTION:
// Creates the output file, containing the OID encoding
// PARAMETERS:
// (in) pointer to the output file name
// RETURN VALUE:
// 0 on success, -1 on failure
int OidToFile::SetMibFilename(const char * pszMibFilename)
{
if (m_pszMibFilename != NULL)
{
delete (void *)m_pszMibFilename;
m_pszMibFilename = NULL;
}
if (pszMibFilename != NULL)
{
_VERIFY(strlen(pszMibFilename) != 0, -1);
m_pszMibFilename = new char [strlen(pszMibFilename) + 1];
_VERIFY(m_pszMibFilename != NULL, -1);
strcpy((char *)m_pszMibFilename, pszMibFilename);
}
return 0;
}
// DESCRIPTION:
// "callback" function, called each time a
// tree node passes through the scan.
// in pOidNode->_lParam there is the cumulated size
// of the hole subtree, root included.
// size = sizeof(T_FILE_NODE_EX) + strlen(node symbol)
// PARAMETERS:
// (in) Pointer to the current node in the tree.
// Nodes are supplied in lexicographic order.
// RETURN VALUE:
// 0 - the scanner should continue
// -1 - the scanner should abort.
int OidToFile::OnScanNode(const SIMCOidTreeNode *pOidNode)
{
T_FILE_NODE_EX fileNode;
char *nodeSymbol = NULL;
// skip the '0' root of the OID tree
if (m_pOidTree->GetParentOf(pOidNode) == NULL)
return 0;
if (theConfigs.m_dwFlags & CFG_PRINT_TREE)
{
Oid oid;
_VERIFY(GetNodeOid(pOidNode, oid)==0, -1);
cout << oid << "\n";
}
if (theConfigs.m_dwFlags & CFG_PRINT_NODE)
{
cout << "."; cout.flush();
}
// if no need to write output file, return success
if (m_pszMibFilename == NULL)
return 0;
_VERIFY(GetNodeSymbol(pOidNode, nodeSymbol) == 0, -1);
// build the T_FILE_NODE_EX structure
fileNode.uNumChildren = (UINT)pOidNode->GetListOfChildNodes()->GetCount();
fileNode.uReserved = 0;
fileNode.uNumSubID = pOidNode->GetValue();
if (nodeSymbol == NULL)
{
fileNode.lNextOffset = pOidNode->_lParam - sizeof(T_FILE_NODE_EX);
fileNode.uStrLen = 0;
}
else
{
fileNode.uStrLen = strlen(nodeSymbol);
fileNode.lNextOffset = pOidNode->_lParam - fileNode.uStrLen - sizeof(T_FILE_NODE_EX);
}
// create / write_open file if not already created
if (m_hMibFile == NULL)
{
OFSTRUCT of;
_VERIFY(m_pszMibFilename != NULL, -1);
m_hMibFile = OpenFile(m_pszMibFilename, &of, OF_CREATE|OF_WRITE|OF_SHARE_EXCLUSIVE);
_VERIFY(m_hMibFile != -1, -1);
}
// write fileNode to file
_VERIFY(_lwrite(m_hMibFile, (LPSTR)&fileNode, sizeof(T_FILE_NODE_EX)) == sizeof(T_FILE_NODE_EX), -1);
// write node's symbol if exists
if (fileNode.uStrLen != 0)
{
_VERIFY(_lwrite(m_hMibFile, nodeSymbol, fileNode.uStrLen) == fileNode.uStrLen, -1);
}
return 0;
}
OidToFile::~OidToFile()
{
if (m_pszMibFilename != NULL)
delete (void *)m_pszMibFilename;
if (m_hMibFile != NULL)
_lclose(m_hMibFile);
}