⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mitab_indfile.cpp

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 * * Create a new index with the specified field type and size. * Field size applies only to char field type... the other types have a * predefined key length. * * Key length is limited to 128 chars. char fields longer than 128 chars * will have their key truncated to 128 bytes. * * Note that a .IND file can contain only a maximum of 29 indexes. * * Returns the new field index on success (greater than 0), or -1 on error. **********************************************************************/int TABINDFile::CreateIndex(TABFieldType eType, int nFieldSize){    int i, nNewIndexNo = -1;    if (m_fp == NULL ||         (m_eAccessMode != TABWrite && m_eAccessMode != TABReadWrite))        return -1;    /*-----------------------------------------------------------------     * Look for an empty slot in the current array, if there is none     * then extend the array.     *----------------------------------------------------------------*/    for(i=0; m_papoIndexRootNodes && i<m_numIndexes; i++)    {        if (m_papoIndexRootNodes[i] == NULL)        {            nNewIndexNo = i;            break;        }    }    if (nNewIndexNo == -1 && m_numIndexes >= 29)    {        CPLError(CE_Failure, CPLE_AppDefined,                 "Cannot add new index to %s.  A dataset can contain only a "                 "maximum of 29 indexes.", m_pszFname);        return -1;    }    if (nNewIndexNo == -1)    {        /*-------------------------------------------------------------         * Add a slot for new index at the end of the nodes array.         *------------------------------------------------------------*/        m_numIndexes++;        m_papoIndexRootNodes = (TABINDNode**)CPLRealloc( m_papoIndexRootNodes,                                                         m_numIndexes*                                                         sizeof(TABINDNode*));        m_papbyKeyBuffers = (GByte **)CPLRealloc(m_papbyKeyBuffers,                                                 m_numIndexes*sizeof(GByte*));        nNewIndexNo = m_numIndexes-1;    }    /*-----------------------------------------------------------------     * Alloc and init new node     * The call to InitNode() automatically allocates storage space for     * the node in the file.     * New nodes are created with a subtree_depth=1 since they start as     * leaf nodes, i.e. their entries point directly to .DAT records     *----------------------------------------------------------------*/    int nKeyLength = ((eType == TABFInteger)  ? 4:                      (eType == TABFSmallInt) ? 2:                      (eType == TABFFloat)    ? 8:                      (eType == TABFDecimal)  ? 8:                      (eType == TABFDate)     ? 4:                      (eType == TABFLogical)  ? 4: MIN(128,nFieldSize));    m_papoIndexRootNodes[nNewIndexNo] = new TABINDNode(m_eAccessMode);    if (m_papoIndexRootNodes[nNewIndexNo]->InitNode(m_fp, 0, nKeyLength,                                                     1,  // subtree depth=1                                                    FALSE, // not unique                                                    &m_oBlockManager,                                                     NULL, 0, 0)!= 0)    {        // CPLError has already been called        return -1;    }    // Alloc a temporary key buffer for this index.    // This buffer will be used by the BuildKey() method    m_papbyKeyBuffers[nNewIndexNo] = (GByte *)CPLCalloc(nKeyLength+1,                                                        sizeof(GByte));    // Return 1-based index number    return nNewIndexNo+1;}/********************************************************************** *                   TABINDFile::AddEntry() * * Add an .DAT record entry for pKeyValue in the specified index. * * Note that index numbers are positive values starting at 1. * nRecordNo is the .DAT record number, record numbers start at 1. * * Returns 0 on success, -1 on error **********************************************************************/int TABINDFile::AddEntry(int nIndexNumber, GByte *pKeyValue, GInt32 nRecordNo){    if ((m_eAccessMode != TABWrite && m_eAccessMode != TABReadWrite) ||         ValidateIndexNo(nIndexNumber) != 0)        return -1;    return m_papoIndexRootNodes[nIndexNumber-1]->AddEntry(pKeyValue,nRecordNo);}/********************************************************************** *                   TABINDFile::Dump() * * Dump block contents... available only in DEBUG mode. **********************************************************************/#ifdef DEBUGvoid TABINDFile::Dump(FILE *fpOut /*=NULL*/){    if (fpOut == NULL)        fpOut = stdout;    fprintf(fpOut, "----- TABINDFile::Dump() -----\n");    if (m_fp == NULL)    {        fprintf(fpOut, "File is not opened.\n");    }    else    {        fprintf(fpOut, "File is opened: %s\n", m_pszFname);        fprintf(fpOut, "   m_numIndexes   = %d\n", m_numIndexes);        for(int i=0; i<m_numIndexes && m_papoIndexRootNodes; i++)        {            if (m_papoIndexRootNodes[i])            {                fprintf(fpOut, "  ----- Index # %d -----\n", i+1);                m_papoIndexRootNodes[i]->Dump(fpOut);            }        }    }    fflush(fpOut);}#endif // DEBUG/*===================================================================== *                      class TABINDNode *====================================================================*//********************************************************************** *                   TABINDNode::TABINDNode() * * Constructor. **********************************************************************/TABINDNode::TABINDNode(TABAccess eAccessMode /*=TABRead*/){    m_fp = NULL;    m_poCurChildNode = NULL;    m_nSubTreeDepth = 0;    m_nKeyLength = 0;    m_eFieldType = TABFUnknown;    m_poDataBlock = NULL;    m_numEntriesInNode = 0;    m_nCurIndexEntry = 0;    m_nPrevNodePtr = 0;    m_nNextNodePtr = 0;    m_poBlockManagerRef = NULL;    m_poParentNodeRef = NULL;    m_bUnique = FALSE;    m_eAccessMode = eAccessMode;}/********************************************************************** *                   TABINDNode::~TABINDNode() * * Destructor. **********************************************************************/TABINDNode::~TABINDNode(){    if (m_poCurChildNode)        delete m_poCurChildNode;    if (m_poDataBlock)        delete m_poDataBlock;}/********************************************************************** *                   TABINDNode::InitNode() * * Init a node... this function can be used either to initialize a new * node, or to make it point to a new data block in the file. * * By default, this call will read the data from the file at the * specified location if necessary, and leave the object ready to be searched. * * In write access, if the block does not exist (i.e. nBlockPtr=0) then a * new one is created and initialized. * * poParentNode is used in write access in order to update the parent node * when this node becomes full and has to be split. * * Returns 0 on success, -1 on error. **********************************************************************/int TABINDNode::InitNode(FILE *fp, int nBlockPtr,                          int nKeyLength, int nSubTreeDepth,                          GBool bUnique,                         TABBinBlockManager *poBlockMgr /*=NULL*/,                         TABINDNode *poParentNode /*=NULL*/,                         int nPrevNodePtr /*=0*/, int nNextNodePtr /*=0*/){    /*-----------------------------------------------------------------     * If the block already points to the right block, then don't do      * anything here.     *----------------------------------------------------------------*/    if (m_fp == fp && nBlockPtr> 0 && m_nCurDataBlockPtr == nBlockPtr)        return 0;    // Keep track of some info    m_fp = fp;    m_nKeyLength = nKeyLength;    m_nSubTreeDepth = nSubTreeDepth;    m_nCurDataBlockPtr = nBlockPtr;    m_bUnique = bUnique;    // Do not overwrite the following values if we receive NULL (the defaults)    if (poBlockMgr)        m_poBlockManagerRef = poBlockMgr;    if (poParentNode)        m_poParentNodeRef = poParentNode;    // Set some defaults    m_numEntriesInNode = 0;    m_nPrevNodePtr = nPrevNodePtr;    m_nNextNodePtr = nNextNodePtr;    m_nCurIndexEntry = 0;    /*-----------------------------------------------------------------     * Init RawBinBlock     * The node's buffer has to be created with read/write access since     * the index is a very dynamic structure!     *----------------------------------------------------------------*/    if (m_poDataBlock == NULL)        m_poDataBlock = new TABRawBinBlock(TABReadWrite, TRUE);    if ((m_eAccessMode == TABWrite || m_eAccessMode == TABReadWrite) &&         nBlockPtr == 0 && m_poBlockManagerRef)    {        /*-------------------------------------------------------------         * Write access: Create and init a new block         *------------------------------------------------------------*/        m_nCurDataBlockPtr = m_poBlockManagerRef->AllocNewBlock();        m_poDataBlock->InitNewBlock(m_fp, 512, m_nCurDataBlockPtr);        m_poDataBlock->WriteInt32( m_numEntriesInNode );        m_poDataBlock->WriteInt32( m_nPrevNodePtr );        m_poDataBlock->WriteInt32( m_nNextNodePtr );    }    else    {        CPLAssert(m_nCurDataBlockPtr > 0);        /*-------------------------------------------------------------         * Read the data block from the file, applies to read access, or         * to write access (to modify an existing block)         *------------------------------------------------------------*/        if (m_poDataBlock->ReadFromFile(m_fp, m_nCurDataBlockPtr, 512) != 0)        {            // CPLError() has already been called.            return -1;        }        m_poDataBlock->GotoByteInBlock(0);        m_numEntriesInNode = m_poDataBlock->ReadInt32();        m_nPrevNodePtr = m_poDataBlock->ReadInt32();        m_nNextNodePtr = m_poDataBlock->ReadInt32();    }    // m_poDataBlock is now positioned at the beginning of the key entries    return 0;}/********************************************************************** *                   TABINDNode::GotoNodePtr() * * Move to the specified node ptr, and read the new node data from the file. * * This is just a cover funtion on top of InitNode() **********************************************************************/int TABINDNode::GotoNodePtr(GInt32 nNewNodePtr){    // First flush current changes if any.    if ((m_eAccessMode == TABWrite || m_eAccessMode == TABReadWrite) &&         m_poDataBlock && m_poDataBlock->CommitToFile() != 0)        return -1;    CPLAssert(nNewNodePtr % 512 == 0);    // Then move to the requested location.    return InitNode(m_fp, nNewNodePtr, m_nKeyLength, m_nSubTreeDepth,                     m_bUnique);}/********************************************************************** *                   TABINDNode::ReadIndexEntry() * * Read the key value and record/node ptr for the specified index entry * inside the current node data. * * nEntryNo is the 0-based index of the index entry that we are interested * in inside the current node. * * Returns the record/node ptr, and copies the key value inside the * buffer pointed to by *pKeyValue... this assumes that *pKeyValue points * to a buffer big enough to hold the key value (m_nKeyLength bytes). * If pKeyValue == NULL, then this parameter is ignored and the key value * is not copied. **********************************************************************/GInt32 TABINDNode::ReadIndexEntry(int nEntryNo, GByte *pKeyValue){    GInt32 nRecordPtr = 0;    if (nEntryNo >= 0 && nEntryNo < m_numEntriesInNode)    {        if (pKeyValue)        {            m_poDataBlock->GotoByteInBlock(12 + nEntryNo*(m_nKeyLength+4));            m_poDataBlock->ReadBytes(m_nKeyLength, pKeyValue);        }        else        {            m_poDataBlock->GotoByteInBlock(12 + nEntryNo*(m_nKeyLength+4)+                                                                 m_nKeyLength);        }        nRecordPtr = m_poDataBlock->ReadInt32();    }    return nRecordPtr;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -