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

📄 mitab_datfile.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    m_pasFieldDef[m_numFields-1].szName[10] = '\0';
    m_pasFieldDef[m_numFields-1].eTABType = eType;
    m_pasFieldDef[m_numFields-1].byLength = (GByte)nWidth;
    m_pasFieldDef[m_numFields-1].byDecimals = (GByte)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 TABFTime:
        m_pasFieldDef[m_numFields-1].cType = 'C';
        m_pasFieldDef[m_numFields-1].byLength = 4;
        break;
      case TABFDateTime:
        m_pasFieldDef[m_numFields-1].cType = 'C';
        m_pasFieldDef[m_numFields-1].byLength = 8;
        break;
      case TABFLogical:
        m_pasFieldDef[m_numFields-1].cType = 'L';
        m_pasFieldDef[m_numFields-1].byLength = 1;
        break;
      default:
        CPLError(CE_Failure, CPLE_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)
{
    // If current record has been deleted, then return an acceptable 
    // default value.
    if (m_bCurRecordDeletedFlag)
        return "";

    if (m_poRecordBlock == NULL)
    {
        CPLError(CE_Failure, CPLE_AssertionFailed,
                 "Can't read field value: file is not opened.");
        return "";
    }

    if (nWidth < 1 || nWidth > 255)
    {
        CPLError(CE_Failure, CPLE_AssertionFailed,
                 "Illegal width for a char field: %d", nWidth);
        return "";
    }

    if (m_poRecordBlock->ReadBytes(nWidth, (GByte*)m_szBuffer) != 0)
        return "";

    m_szBuffer[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(m_szBuffer)-1;
        while(nLen>=0 && m_szBuffer[nLen] == ' ')
            m_szBuffer[nLen--] = '\0';
    }

    return m_szBuffer;
}

/**********************************************************************
 *                   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.
 **********************************************************************/
GInt32 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)
    {
        CPLError(CE_Failure, CPLE_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.
 **********************************************************************/
GInt16 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)
    {
        CPLError(CE_Failure, CPLE_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)
    {
        CPLError(CE_Failure, CPLE_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)
{
    GByte bValue;

    // If current record has been deleted, then return an acceptable 
    // default value.
    if (m_bCurRecordDeletedFlag)
        return "F";

    if (m_poRecordBlock == NULL)
    {
        CPLError(CE_Failure, CPLE_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
    {
        // In Native tables, we are guaranteed it is 1 byte with 0/1 value
        bValue =  m_poRecordBlock->ReadByte();
    }

    return bValue? "T":"F";
}

/**********************************************************************
 *                   TABDATFile::ReadDateField()
 *
 * Read the logical field value at the current position in the data 
 * block.
 *
 * A date field is a 4 bytes binary value in which the first byte is
 * the day, followed by 1 byte for the month, and 2 bytes for the year.
 *
 * We return an 8 chars string in the format "YYYYMMDD"
 * 
 * Note: nWidth is used only with TABTableDBF types.
 *
 * 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::ReadDateField(int nWidth)
{
    int nDay, nMonth, nYear;

    // If current record has been deleted, then return an acceptable 
    // default value.
    if (m_bCurRecordDeletedFlag)
        return "";

    if (m_poRecordBlock == NULL)
    {
        CPLError(CE_Failure, CPLE_AssertionFailed,
                 "Can't read field value: file is not opened.");
        return "";
    }

    // With .DBF files, there is nothing to do... the value should already
    // be stored in YYYYMMDD format according to DBF specs.
    if (m_eTableType == TABTableDBF)
        return ReadCharField(nWidth);


    nYear  = m_poRecordBlock->ReadInt16();
    nMonth = m_poRecordBlock->ReadByte();
    nDay   = m_poRecordBlock->ReadByte();

    if (CPLGetLastErrorNo() != 0 || (nYear==0 && nMonth==0 && nDay==0))
        return "";

    sprintf(m_szBuffer, "%4.4d%2.2d%2.2d", nYear, nMonth, nDay);

    return m_szBuffer;
}

/**********************************************************************
 *                   TABDATFile::ReadTimeField()
 *
 * Read the Time field value at the current position in the data 
 * block.
 *
 * A time field is a 4 bytes binary value which represents the number
 * of milliseconds since midnight.
 *
 * We return a 9 char string in the format "HHMMSSMMM"
 * 
 * Note: nWidth is used only with TABTableDBF types.
 *
 * 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::ReadTimeField(int nWidth)
{
    GInt32 nS;
    static char szBuf[20];

    // If current record has been deleted, then return an acceptable 
    // default value.
    if (m_bCurRecordDeletedFlag)
        return "";

⌨️ 快捷键说明

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