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

📄 tabindfile.cpp

📁 linux下一款GIS程序源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        {            /*---------------------------------------------------------             * 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)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "TABINDFile: File has not been opened yet!");        return -1;    }    if (nIndexNumber < 1 || nIndexNumber > m_numIndexes ||        m_papoIndexRootNodes == NULL ||         m_papoIndexRootNodes[nIndexNumber-1] == NULL)    {        UGKError(ET_Failure, UGKErr_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, UGKBool 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 **********************************************************************/UGKByte *TABINDFile::BuildKey(int nIndexNumber, UGKInt32 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] = (UGKByte)(nValue & 0xff)+0x80;        break;      case 2:        m_papbyKeyBuffers[nIndexNumber-1][0] =                                        (UGKByte)(nValue/0x100 & 0xff)+0x80;        m_papbyKeyBuffers[nIndexNumber-1][1] = (UGKByte)(nValue & 0xff);        break;      case 4:        m_papbyKeyBuffers[nIndexNumber-1][0] =                                        (UGKByte)(nValue/0x1000000 &0xff)+0x80;        m_papbyKeyBuffers[nIndexNumber-1][1] = (UGKByte)(nValue/0x10000 & 0xff);        m_papbyKeyBuffers[nIndexNumber-1][2] = (UGKByte)(nValue/0x100 &0xff);        m_papbyKeyBuffers[nIndexNumber-1][3] = (UGKByte)(nValue & 0xff);        break;      default:        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "BuildKey(): %d bytes integer key length not supported",                 nKeyLength);        break;    }    return m_papbyKeyBuffers[nIndexNumber-1];}/********************************************************************** *                   TABINDFile::BuildKey() * * BuildKey() for string fields **********************************************************************/UGKByte *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] = (UGKByte)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 **********************************************************************/UGKByte *TABINDFile::BuildKey(int nIndexNumber, double dValue){    if (ValidateIndexNo(nIndexNumber) != 0)        return NULL;    int nKeyLength = m_papoIndexRootNodes[nIndexNumber-1]->GetKeyLength();    assert(nKeyLength == 8 && sizeof(double) == 8);    /*-----------------------------------------------------------------     * Convert double and decimal values...      * Reverse the sign of the value, and convert to MSB     *----------------------------------------------------------------*/    dValue = -dValue;    memcpy(m_papbyKeyBuffers[nIndexNumber-1], (UGKByte*)(&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 **********************************************************************/UGKInt32 TABINDFile::FindFirst(int nIndexNumber, UGKByte *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 **********************************************************************/UGKInt32 TABINDFile::FindNext(int nIndexNumber, UGKByte *pKeyValue){    if (ValidateIndexNo(nIndexNumber) != 0)        return -1;    return m_papoIndexRootNodes[nIndexNumber-1]->FindNext(pKeyValue);}/********************************************************************** *                   TABINDFile::CreateIndex() * * 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)    {        UGKError(ET_Failure, UGKErr_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**)UGK_Realloc( m_papoIndexRootNodes,                                                         m_numIndexes*                                                         sizeof(TABINDNode*));        m_papbyKeyBuffers = (UGKByte **)UGK_Realloc(m_papbyKeyBuffers,                                                 m_numIndexes*sizeof(UGKByte*));        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] = (UGKByte *)UGK_Calloc(nKeyLength+1,                                                        sizeof(UGKByte));    // 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, UGKByte *pKeyValue, UGKInt32 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. **********************************************************************/void 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);}

⌨️ 快捷键说明

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