📄 mitab_datfile.cpp
字号:
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 + -