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

📄 tabdatfile.cpp

📁 linux下一款GIS程序源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            WriteHeader();        }        m_numRecords = MAX(nRecordId, m_numRecords);        nFileOffset = m_nFirstRecordPtr+(nRecordId-1)*m_nRecordSize;        m_poRecordBlock->InitNewBlock(m_fp, m_nRecordSize, nFileOffset);        /*-------------------------------------------------------------         * The first char of the record is the active/deleted flag.         * Automatically set it to ' ' (active).         *------------------------------------------------------------*/        m_poRecordBlock->WriteByte(' ');    }    m_nCurRecordId = nRecordId;    return m_poRecordBlock;}/********************************************************************** *                   TABDATFile::CommitRecordToFile() * * Commit the data record previously initialized with GetRecordBlock() * to the file.  This function must be called after writing the data * values to a record otherwise the record will never make it to the * file. * * Returns 0 on success, -1 on error. **********************************************************************/int  TABDATFile::CommitRecordToFile(){    if (m_eAccessMode != TABWrite || m_poRecordBlock == NULL)        return -1;    return m_poRecordBlock->CommitToFile();}/********************************************************************** *                   TABDATFile::ValidateFieldInfoFromTAB() * * Check that the value read from the .TAB file by the caller are  * consistent with what is found in the .DAT header. * * Note that field ids are positive and start at 0. * * We have to use this function when opening a file for reading since  * the .DAT file does not contain the full field types information... * a .DAT file is actually a .DBF file in which the .DBF types are * handled in a special way... type 'C' fields are used to store binary  * values for most MapInfo types. * * For TABTableDBF, we actually have no validation to do since all types * are stored as strings internally, so we'll just convert from string. * * Returns a value >= 0 if OK, -1 on error. **********************************************************************/int  TABDATFile::ValidateFieldInfoFromTAB(int iField, const char *pszName,                                          TABFieldType eType,                                          int nWidth, int nPrecision){    int i = iField;  // Just to make things shorter    assert(m_pasFieldDef);    if (m_pasFieldDef == NULL || iField < 0 || iField >= m_numFields)    {        UGKError(ET_Failure, UGKErr_FileIO,          "Invalid field %d (%s) in .TAB header. %s contains only %d fields.",                 iField+1, pszName, m_pszFname, m_pasFieldDef? m_numFields:0);        return -1;    }    /*-----------------------------------------------------------------     * We used to check that the .TAB field name matched the .DAT     * name stored internally, but apparently some tools that rename table     * field names only update the .TAB file and not the .DAT, so we won't     * do that name validation any more... we'll just check the type.     *     * With TABTableNative, we have to validate the field sizes as well     * because .DAT files use char fields to store binary values.     * With TABTableDBF, no need to validate field type since all     * fields are stored as strings internally.     *----------------------------------------------------------------*/    if ((m_eTableType == TABTableNative &&          ((eType == TABFChar && (m_pasFieldDef[i].cType != 'C' ||                                m_pasFieldDef[i].byLength != nWidth )) ||          (eType == TABFDecimal && (m_pasFieldDef[i].cType != 'N' ||                                  m_pasFieldDef[i].byLength != nWidth||                                   m_pasFieldDef[i].byDecimals!=nPrecision)) ||          (eType == TABFInteger && (m_pasFieldDef[i].cType != 'C' ||                                   m_pasFieldDef[i].byLength != 4  )) ||          (eType == TABFSmallInt && (m_pasFieldDef[i].cType != 'C' ||                                    m_pasFieldDef[i].byLength != 2 )) ||          (eType == TABFFloat && (m_pasFieldDef[i].cType != 'C' ||                                 m_pasFieldDef[i].byLength != 8    )) ||          (eType == TABFDate && (m_pasFieldDef[i].cType != 'C' ||                                m_pasFieldDef[i].byLength != 4     )) ||          (eType == TABFLogical && (m_pasFieldDef[i].cType != 'L' ||                                   m_pasFieldDef[i].byLength != 1  ))   ) ))    {        UGKError(ET_Failure, UGKErr_FileIO,                 "Definition of field %d (%s) from .TAB file does not match "                 "what is found in %s (name=%s, type=%c, width=%d, prec=%d)",                 iField+1, pszName, m_pszFname,                 m_pasFieldDef[i].szName, m_pasFieldDef[i].cType,       				m_pasFieldDef[i].byLength, m_pasFieldDef[i].byDecimals);        return -1;    }    m_pasFieldDef[i].eTABType = eType;    return 0;}/********************************************************************** *                   TABDATFile::AddField() * * Create a new field (column) in a newly created table.  This function * must be called after the file has been opened, but before writing the * first record. * * Returns the new field index (a value >= 0) if OK, -1 on error. **********************************************************************/int  TABDATFile::AddField(const char *pszName, TABFieldType eType,                          int nWidth, int nPrecision /*=0*/){    if (m_eAccessMode != TABWrite || m_bWriteHeaderInitialized ||        m_eTableType != TABTableNative)    {        UGKError(ET_Failure, UGKErr_NotSupported,                 "Addition of new table fields is not supported after the "                 "first data item has been written.");        return -1;    }    /*-----------------------------------------------------------------     * Validate field width... must be <= 254     *----------------------------------------------------------------*/    if (nWidth > 254)    {        UGKError(ET_Failure, UGKErr_IllegalArg,                 "Invalid size (%d) for field '%s'.  "                 "Size must be 254 or less.", nWidth, pszName);        return -1;    }    /*-----------------------------------------------------------------     * Map fields with width=0 (variable length in UGK) to a valid default     *----------------------------------------------------------------*/    if (eType == TABFDecimal && nWidth == 0)        nWidth=20;    else if (nWidth == 0)        nWidth=254; /* char fields */    if (m_numFields < 0)        m_numFields = 0;    m_numFields++;    m_pasFieldDef = (TABDATFieldDef*)UGK_Realloc(m_pasFieldDef,                                           m_numFields*sizeof(TABDATFieldDef));    strncpy(m_pasFieldDef[m_numFields-1].szName, pszName, 10);    m_pasFieldDef[m_numFields-1].szName[10] = '\0';    m_pasFieldDef[m_numFields-1].eTABType = eType;    m_pasFieldDef[m_numFields-1].byLength = (UGKByte)nWidth;    m_pasFieldDef[m_numFields-1].byDecimals = (UGKByte)nPrecision;    switch(eType)    {      case TABFChar:        m_pasFieldDef[m_numFields-1].cType = 'C';        break;      case TABFDecimal:        m_pasFieldDef[m_numFields-1].cType = 'N';        break;      case TABFInteger:        m_pasFieldDef[m_numFields-1].cType = 'C';        m_pasFieldDef[m_numFields-1].byLength = 4;        break;      case TABFSmallInt:        m_pasFieldDef[m_numFields-1].cType = 'C';        m_pasFieldDef[m_numFields-1].byLength = 2;        break;      case TABFFloat:        m_pasFieldDef[m_numFields-1].cType = 'C';        m_pasFieldDef[m_numFields-1].byLength = 8;        break;      case TABFDate:        m_pasFieldDef[m_numFields-1].cType = 'C';        m_pasFieldDef[m_numFields-1].byLength = 4;        break;      case TABFLogical:        m_pasFieldDef[m_numFields-1].cType = 'L';        m_pasFieldDef[m_numFields-1].byLength = 1;        break;      default:        UGKError(ET_Failure, UGKErr_NotSupported,                 "Unsupported field type for field `%s'", pszName);        return -1;    }    return 0;}/********************************************************************** *                   TABDATFile::GetFieldType() * * Returns the native field type for field # nFieldId as previously set * by ValidateFieldInfoFromTAB(). * * Note that field ids are positive and start at 0. **********************************************************************/TABFieldType TABDATFile::GetFieldType(int nFieldId){    if (m_pasFieldDef == NULL || nFieldId < 0 || nFieldId >= m_numFields)        return TABFUnknown;    return m_pasFieldDef[nFieldId].eTABType;}/********************************************************************** *                   TABDATFile::GetFieldWidth() * * Returns the width for field # nFieldId as previously read from the * .DAT header. * * Note that field ids are positive and start at 0. **********************************************************************/int   TABDATFile::GetFieldWidth(int nFieldId){    if (m_pasFieldDef == NULL || nFieldId < 0 || nFieldId >= m_numFields)        return 0;    return m_pasFieldDef[nFieldId].byLength;}/********************************************************************** *                   TABDATFile::GetFieldPrecision() * * Returns the precision for field # nFieldId as previously read from the * .DAT header. * * Note that field ids are positive and start at 0. **********************************************************************/int   TABDATFile::GetFieldPrecision(int nFieldId){    if (m_pasFieldDef == NULL || nFieldId < 0 || nFieldId >= m_numFields)        return 0;    return m_pasFieldDef[nFieldId].byDecimals;}/********************************************************************** *                   TABDATFile::ReadCharField() * * Read the character field value at the current position in the data  * block. *  * Use GetRecordBlock() to position the data block to the beginning of * a record before attempting to read values. * * nWidth is the field length, as defined in the .DAT header. * * Returns a reference to an internal buffer that will be valid only until * the next field is read, or "" if the operation failed, in which case * CPLError() will have been called. **********************************************************************/const char *TABDATFile::ReadCharField(int nWidth){    // We know that character strings are limited to 254 chars in MapInfo    static char szBuf[256];    // If current record has been deleted, then return an acceptable     // default value.    if (m_bCurRecordDeletedFlag)        return "";    if (m_poRecordBlock == NULL)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "Can't read field value: file is not opened.");        return "";    }    if (nWidth < 1 || nWidth > 255)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "Illegal width for a char field: %d", nWidth);        return "";    }    if (m_poRecordBlock->ReadBytes(nWidth, (UGKByte*)szBuf) != 0)        return "";    szBuf[nWidth] = '\0';    // NATIVE tables are padded with '\0' chars, but DBF tables are padded    // with spaces... get rid of the trailing spaces.    if (m_eTableType == TABTableDBF)    {        int nLen = strlen(szBuf)-1;        while(nLen>=0 && szBuf[nLen] == ' ')            szBuf[nLen--] = '\0';    }    return szBuf;}/********************************************************************** *                   TABDATFile::ReadIntegerField() * * Read the integer field value at the current position in the data  * block. *  * Note: nWidth is used only with TABTableDBF types. * * CPLError() will have been called if something fails. **********************************************************************/UGKInt32 TABDATFile::ReadIntegerField(int nWidth){    // If current record has been deleted, then return an acceptable     // default value.    if (m_bCurRecordDeletedFlag)        return 0;    if (m_poRecordBlock == NULL)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "Can't read field value: file is not opened.");        return 0;    }    if (m_eTableType == TABTableDBF)        return atoi(ReadCharField(nWidth));    return m_poRecordBlock->ReadInt32();}/********************************************************************** *                   TABDATFile::ReadSmallIntField() * * Read the smallint field value at the current position in the data  * block. *  * Note: nWidth is used only with TABTableDBF types. * * CPLError() will have been called if something fails. **********************************************************************/UGKInt16 TABDATFile::ReadSmallIntField(int nWidth){    // If current record has been deleted, then return an acceptable     // default value.    if (m_bCurRecordDeletedFlag)        return 0;    if (m_poRecordBlock == NULL)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "Can't read field value: file is not opened.");        return 0;    }    if (m_eTableType == TABTableDBF)        return atoi(ReadCharField(nWidth));    return m_poRecordBlock->ReadInt16();}/********************************************************************** *                   TABDATFile::ReadFloatField() * * Read the float field value at the current position in the data  * block. *  * Note: nWidth is used only with TABTableDBF types. * * CPLError() will have been called if something fails. **********************************************************************/double TABDATFile::ReadFloatField(int nWidth){    // If current record has been deleted, then return an acceptable     // default value.    if (m_bCurRecordDeletedFlag)        return 0.0;    if (m_poRecordBlock == NULL)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "Can't read field value: file is not opened.");        return 0.0;    }    if (m_eTableType == TABTableDBF)        return atof(ReadCharField(nWidth));    return m_poRecordBlock->ReadDouble();}/********************************************************************** *                   TABDATFile::ReadLogicalField() * * Read the logical field value at the current position in the data  * block. * * The file contains either 0 or 1, and we return a string with  * "F" (false) or "T" (true) *  * Note: nWidth is used only with TABTableDBF types. * * CPLError() will have been called if something fails. **********************************************************************/const char *TABDATFile::ReadLogicalField(int nWidth){    UGKByte bValue;    // If current record has been deleted, then return an acceptable     // default value.    if (m_bCurRecordDeletedFlag)        return "F";    if (m_poRecordBlock == NULL)    {        UGKError(ET_Failure, UGKErr_AssertionFailed,                 "Can't read field value: file is not opened.");        return "";    }    if (m_eTableType == TABTableDBF)    {        const char *pszVal = ReadCharField(nWidth);        bValue = (pszVal && strchr("1YyTt", pszVal[0]) != NULL);    }    else    {

⌨️ 快捷键说明

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