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

📄 mitab_indfile.cpp

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {        /*-------------------------------------------------------------         * Read next index definition         *------------------------------------------------------------*/        GInt32 nRootNodePtr = poHeaderBlock->ReadInt32();        poHeaderBlock->ReadInt16();   // skip... max. num of entries per node        int nTreeDepth = poHeaderBlock->ReadByte();        int nKeyLength = poHeaderBlock->ReadByte();        poHeaderBlock->GotoByteRel(8); // skip next 8 bytes;        /*-------------------------------------------------------------         * And init root node for this index.         * Note that if nRootNodePtr==0 then this means that the          * corresponding index does not exist (i.e. has been deleted?)         * so we simply do not allocate the root node in this case.         * An error will be produced if the user tries to access this index         * later during execution.         *------------------------------------------------------------*/        if (nRootNodePtr > 0)        {            m_papoIndexRootNodes[iIndex] = new TABINDNode(m_eAccessMode);            if (m_papoIndexRootNodes[iIndex]->InitNode(m_fp, nRootNodePtr,                                                       nKeyLength, nTreeDepth,                                                       FALSE,                                                       &m_oBlockManager)!= 0)            {                // CPLError has already been called                delete poHeaderBlock;                return -1;            }            // Alloc a temporary key buffer for this index.            // This buffer will be used by the BuildKey() method            m_papbyKeyBuffers[iIndex] = (GByte *)CPLCalloc(nKeyLength+1,                                                            sizeof(GByte));        }        else        {            m_papoIndexRootNodes[iIndex] = NULL;            m_papbyKeyBuffers[iIndex] = NULL;        }    }    /*-----------------------------------------------------------------     * OK, we won't need the header block any more... free it.     *----------------------------------------------------------------*/    delete poHeaderBlock;    return 0;}/********************************************************************** *                   TABINDFile::WriteHeader() * * (private method) * Write the header block based on current index information. * * Returns 0 on success, -1 on error. **********************************************************************/int TABINDFile::WriteHeader(){    CPLAssert(m_fp);    CPLAssert(m_eAccessMode == TABWrite || m_eAccessMode == TABReadWrite);    /*-----------------------------------------------------------------     * Write the 48 bytes of file header     *----------------------------------------------------------------*/    TABRawBinBlock *poHeaderBlock;    poHeaderBlock = new TABRawBinBlock(m_eAccessMode, TRUE);    poHeaderBlock->InitNewBlock(m_fp, 512, 0);    poHeaderBlock->WriteInt32( IND_MAGIC_COOKIE );    poHeaderBlock->WriteInt16( 100 );   // ???    poHeaderBlock->WriteInt16( 512 );   // ???    poHeaderBlock->WriteInt32( 0 );     // ???    poHeaderBlock->WriteInt16( m_numIndexes );    poHeaderBlock->WriteInt16( 0x15e7); // ???    poHeaderBlock->WriteInt16( 10 );    // ???    poHeaderBlock->WriteInt16( 0x611d); // ???    poHeaderBlock->WriteZeros( 28 );    /*-----------------------------------------------------------------     * The first index definition starts at byte 48     *----------------------------------------------------------------*/    for(int iIndex=0; iIndex<m_numIndexes; iIndex++)    {        TABINDNode *poRootNode = m_papoIndexRootNodes[iIndex];        if (poRootNode)        {            /*---------------------------------------------------------             * Write next index definition             *--------------------------------------------------------*/            poHeaderBlock->WriteInt32(poRootNode->GetNodeBlockPtr());            poHeaderBlock->WriteInt16(poRootNode->GetMaxNumEntries());            poHeaderBlock->WriteByte( poRootNode->GetSubTreeDepth());            poHeaderBlock->WriteByte( poRootNode->GetKeyLength());            poHeaderBlock->WriteZeros( 8 );        }        else        {            /*---------------------------------------------------------             * NULL Root Node: This index has likely been deleted             *--------------------------------------------------------*/            poHeaderBlock->WriteZeros( 16 );        }    }    /*-----------------------------------------------------------------     * OK, we won't need the header block any more... write and free it.     *----------------------------------------------------------------*/    if (poHeaderBlock->CommitToFile() != 0)        return -1;    delete poHeaderBlock;    return 0;}/********************************************************************** *                   TABINDFile::ValidateIndexNo() * * Private method to validate the index no parameter of some methods... * returns 0 if index no. is OK, or produces an error ands returns -1 * if index no is not valid.  **********************************************************************/int TABINDFile::ValidateIndexNo(int nIndexNumber){    if (m_fp == NULL)    {        CPLError(CE_Failure, CPLE_AssertionFailed,                 "TABINDFile: File has not been opened yet!");        return -1;    }    if (nIndexNumber < 1 || nIndexNumber > m_numIndexes ||        m_papoIndexRootNodes == NULL ||         m_papoIndexRootNodes[nIndexNumber-1] == NULL)    {        CPLError(CE_Failure, CPLE_AssertionFailed,                 "No field index number %d in %s: Valid range is [1..%d].",                 nIndexNumber, m_pszFname, m_numIndexes);        return -1;    }    return 0;  // Index seems valid}/********************************************************************** *                   TABINDFile::SetIndexFieldType() * * Sets the field type for the specified index. * This information will then be used in building the key values, etc. * * Returns 0 on success, -1 on error. **********************************************************************/int TABINDFile::SetIndexFieldType(int nIndexNumber, TABFieldType eType){    if (ValidateIndexNo(nIndexNumber) != 0)        return -1;    return m_papoIndexRootNodes[nIndexNumber-1]->SetFieldType(eType);}/********************************************************************** *                   TABINDFile::SetIndexUnique() * * Indicate that an index's keys are unique.  This allows for some  * optimization with read access.  By default, an index is treated as if * its keys could have duplicates. * * Returns 0 on success, -1 on error. **********************************************************************/int TABINDFile::SetIndexUnique(int nIndexNumber, GBool bUnique/*=TRUE*/){    if (ValidateIndexNo(nIndexNumber) != 0)        return -1;    m_papoIndexRootNodes[nIndexNumber-1]->SetUnique(bUnique);    return 0;}/********************************************************************** *                   TABINDFile::BuildKey() * * Encode a field value in the form required to be compared with index * keys in the specified index. *  * Note that index numbers are positive values starting at 1. * * Returns a reference to an internal buffer that is valid only until the * next call to BuildKey().  (should not be freed by the caller). * Returns NULL if field index is invalid. * * The first flavour of the function handles integer type of values, this * corresponds to MapInfo types: integer, smallint, logical and date **********************************************************************/GByte *TABINDFile::BuildKey(int nIndexNumber, GInt32 nValue){    if (ValidateIndexNo(nIndexNumber) != 0)        return NULL;    int nKeyLength = m_papoIndexRootNodes[nIndexNumber-1]->GetKeyLength();        /*-----------------------------------------------------------------     * Convert all int values to MSB using the right number of bytes     * Note:     * The most significant bit has to be unset for negative values,     * and to be set for positive ones... that's the reverse of what it     * should usually be.  Adding 0x80 to the MSB byte will do the job.     *----------------------------------------------------------------*/    switch(nKeyLength)    {      case 1:        m_papbyKeyBuffers[nIndexNumber-1][0] = (GByte)(nValue & 0xff)+0x80;        break;      case 2:        m_papbyKeyBuffers[nIndexNumber-1][0] =                                        (GByte)(nValue/0x100 & 0xff)+0x80;        m_papbyKeyBuffers[nIndexNumber-1][1] = (GByte)(nValue & 0xff);        break;      case 4:        m_papbyKeyBuffers[nIndexNumber-1][0] =                                        (GByte)(nValue/0x1000000 &0xff)+0x80;        m_papbyKeyBuffers[nIndexNumber-1][1] = (GByte)(nValue/0x10000 & 0xff);        m_papbyKeyBuffers[nIndexNumber-1][2] = (GByte)(nValue/0x100 &0xff);        m_papbyKeyBuffers[nIndexNumber-1][3] = (GByte)(nValue & 0xff);        break;      default:        CPLError(CE_Failure, CPLE_AssertionFailed,                 "BuildKey(): %d bytes integer key length not supported",                 nKeyLength);        break;    }    return m_papbyKeyBuffers[nIndexNumber-1];}/********************************************************************** *                   TABINDFile::BuildKey() * * BuildKey() for string fields **********************************************************************/GByte *TABINDFile::BuildKey(int nIndexNumber, const char *pszStr){    if (ValidateIndexNo(nIndexNumber) != 0 || pszStr == NULL)        return NULL;    int nKeyLength = m_papoIndexRootNodes[nIndexNumber-1]->GetKeyLength();    /*-----------------------------------------------------------------     * Strings keys are all in uppercase, and padded with '\0'     *----------------------------------------------------------------*/    int i=0;    for (i=0; i<nKeyLength && pszStr[i] != '\0'; i++)    {        m_papbyKeyBuffers[nIndexNumber-1][i] = (GByte)toupper(pszStr[i]);    }    /* Pad the end of the buffer with '\0' */    for( ; i<nKeyLength; i++)    {           m_papbyKeyBuffers[nIndexNumber-1][i] = '\0';    }            return m_papbyKeyBuffers[nIndexNumber-1];}/********************************************************************** *                   TABINDFile::BuildKey() * * BuildKey() for float and decimal fields **********************************************************************/GByte *TABINDFile::BuildKey(int nIndexNumber, double dValue){    if (ValidateIndexNo(nIndexNumber) != 0)        return NULL;    int nKeyLength = m_papoIndexRootNodes[nIndexNumber-1]->GetKeyLength();    CPLAssert(nKeyLength == 8 && sizeof(double) == 8);    /*-----------------------------------------------------------------     * Convert double and decimal values...      * Reverse the sign of the value, and convert to MSB     *----------------------------------------------------------------*/    dValue = -dValue;#ifndef CPL_MSB    CPL_SWAPDOUBLE(&dValue);#endif    memcpy(m_papbyKeyBuffers[nIndexNumber-1], (GByte*)(&dValue), nKeyLength);    return m_papbyKeyBuffers[nIndexNumber-1];}/********************************************************************** *                   TABINDFile::FindFirst() * * Search one of the indexes for a key value.   * * Note that index numbers are positive values starting at 1. * * Return value: *  - the key's corresponding record number in the .DAT file (greater than 0) *  - 0 if the key was not found *  - or -1 if an error happened **********************************************************************/GInt32 TABINDFile::FindFirst(int nIndexNumber, GByte *pKeyValue){    if (ValidateIndexNo(nIndexNumber) != 0)        return -1;    return m_papoIndexRootNodes[nIndexNumber-1]->FindFirst(pKeyValue);}/********************************************************************** *                   TABINDFile::FindNext() * * Continue the Search for pKeyValue previously initiated by FindFirst().   * NOTE: FindFirst() MUST have been previously called for this call to *       work... * * Note that index numbers are positive values starting at 1. * * Return value: *  - the key's corresponding record number in the .DAT file (greater than 0) *  - 0 if the key was not found *  - or -1 if an error happened **********************************************************************/GInt32 TABINDFile::FindNext(int nIndexNumber, GByte *pKeyValue){    if (ValidateIndexNo(nIndexNumber) != 0)        return -1;    return m_papoIndexRootNodes[nIndexNumber-1]->FindNext(pKeyValue);}/********************************************************************** *                   TABINDFile::CreateIndex()

⌨️ 快捷键说明

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