📄 mitab_tabfile.cpp
字号:
* We found the list of table fields
* Just remember number of fields... the field types will be
* parsed inside ParseTABFileFields() later...
*--------------------------------------------------------*/
bFoundTableFields = TRUE;
numFields = atoi(papszTok[1]);
if (numFields < 1 || numFields>2048 || iLine+numFields >= numLines)
{
if (!bTestOpenNoError)
CPLError(CE_Failure, CPLE_FileIO,
"Invalid number of fields (%s) at line %d in file %s",
papszTok[1], iLine+1, m_pszFname);
CSLDestroy(papszTok);
return -1;
}
bInsideTableDef = FALSE;
}/* end of fields section*/
else
{
// Simply Ignore unrecognized lines
}
}
CSLDestroy(papszTok);
if (m_pszCharset == NULL)
m_pszCharset = CPLStrdup("Neutral");
if (numFields == 0)
{
if (!bTestOpenNoError)
CPLError(CE_Failure, CPLE_NotSupported,
"%s contains no table field definition. "
"This type of .TAB file cannot be read by this library.",
m_pszFname);
return -1;
}
return 0;
}
/**********************************************************************
* TABFile::ParseTABFileFields()
*
* Extract the field definition from the TAB header file, validate
* with what we have in the previously opened .DAT or .DBF file, and
* finally build the m_poDefn OGRFeatureDefn for this dataset.
*
* This private method should be used only during the Open() call and after
* ParseTABFileFirstPass() has been called.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABFile::ParseTABFileFields()
{
int iLine, numLines=0, numTok, nStatus;
char **papszTok=NULL;
OGRFieldDefn *poFieldDefn;
if (m_eAccessMode != TABRead)
{
CPLError(CE_Failure, CPLE_NotSupported,
"ParseTABFile() can be used only with Read access.");
return -1;
}
char *pszFeatureClassName = TABGetBasename(m_pszFname);
m_poDefn = new OGRFeatureDefn(pszFeatureClassName);
CPLFree(pszFeatureClassName);
// Ref count defaults to 0... set it to 1
m_poDefn->Reference();
/*-------------------------------------------------------------
* Scan for fields.
*------------------------------------------------------------*/
numLines = CSLCount(m_papszTABFile);
for(iLine=0; iLine<numLines; iLine++)
{
/*-------------------------------------------------------------
* Tokenize the next .TAB line, and check first keyword
*------------------------------------------------------------*/
const char *pszStr = m_papszTABFile[iLine];
while(*pszStr != '\0' && isspace((unsigned char)*pszStr))
pszStr++;
if (EQUALN(pszStr, "Fields", 6))
{
/*---------------------------------------------------------
* We found the list of table fields
*--------------------------------------------------------*/
int iField, numFields;
numFields = atoi(pszStr+7);
if (numFields < 1 || numFields > 2048 ||
iLine+numFields >= numLines)
{
CPLError(CE_Failure, CPLE_FileIO,
"Invalid number of fields (%s) at line %d in file %s",
pszStr+7, iLine+1, m_pszFname);
CSLDestroy(papszTok);
return -1;
}
// Alloc the array to keep track of indexed fields
m_panIndexNo = (int *)CPLCalloc(numFields, sizeof(int));
iLine++;
poFieldDefn = NULL;
for(iField=0; iField<numFields; iField++, iLine++)
{
/*-----------------------------------------------------
* For each field definition found in the .TAB:
* Pass the info to the DAT file object. It will validate
* the info with what is found in the .DAT header, and will
* also use this info later to interpret field values.
*
* We also create the OGRFieldDefn at the same time to
* initialize the OGRFeatureDefn
*----------------------------------------------------*/
CSLDestroy(papszTok);
papszTok = CSLTokenizeStringComplex(m_papszTABFile[iLine],
" \t(),;",
TRUE, FALSE);
numTok = CSLCount(papszTok);
nStatus = -1;
CPLAssert(m_poDefn);
if (numTok >= 3 && EQUAL(papszTok[1], "char"))
{
/*-------------------------------------------------
* CHAR type
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFChar,
atoi(papszTok[2]),
0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString);
poFieldDefn->SetWidth(atoi(papszTok[2]));
}
else if (numTok >= 2 && EQUAL(papszTok[1], "integer"))
{
/*-------------------------------------------------
* INTEGER type
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFInteger,
0,
0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTInteger);
}
else if (numTok >= 2 && EQUAL(papszTok[1], "smallint"))
{
/*-------------------------------------------------
* SMALLINT type
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFSmallInt,
0,
0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTInteger);
}
else if (numTok >= 4 && EQUAL(papszTok[1], "decimal"))
{
/*-------------------------------------------------
* DECIMAL type
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFDecimal,
atoi(papszTok[2]),
atoi(papszTok[3]));
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTReal);
poFieldDefn->SetWidth(atoi(papszTok[2]));
poFieldDefn->SetPrecision(atoi(papszTok[3]));
}
else if (numTok >= 2 && EQUAL(papszTok[1], "float"))
{
/*-------------------------------------------------
* FLOAT type
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFFloat,
0, 0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTReal);
}
else if (numTok >= 2 && EQUAL(papszTok[1], "date"))
{
/*-------------------------------------------------
* DATE type (returned as a string: "DD/MM/YYYY")
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFDate,
0,
0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString);
poFieldDefn->SetWidth(10);
}
else if (numTok >= 2 && EQUAL(papszTok[1], "time"))
{
/*-------------------------------------------------
* TIME type (returned as a string: "HH:MM:SS")
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFTime,
0,
0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString);
poFieldDefn->SetWidth(8);
}
else if (numTok >= 2 && EQUAL(papszTok[1], "datetime"))
{
/*-------------------------------------------------
* DATETIME type (returned as a string: "DD/MM/YYYY HH:MM:SS")
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFDateTime,
0,
0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString);
poFieldDefn->SetWidth(19);
}
else if (numTok >= 2 && EQUAL(papszTok[1], "logical"))
{
/*-------------------------------------------------
* LOGICAL type (value "T" or "F")
*------------------------------------------------*/
nStatus = m_poDATFile->ValidateFieldInfoFromTAB(iField,
papszTok[0],
TABFLogical,
0,
0);
poFieldDefn = new OGRFieldDefn(papszTok[0], OFTString);
poFieldDefn->SetWidth(1);
}
else
nStatus = -1; // Unrecognized field type or line corrupt
if (nStatus != 0)
{
CPLError(CE_Failure, CPLE_FileIO,
"Failed to parse field definition at line %d in file %s",
iLine+1, m_pszFname);
CSLDestroy(papszTok);
return -1;
}
/*-----------------------------------------------------
* Keep track of index number if present
*----------------------------------------------------*/
if (numTok >= 4 && EQUAL(papszTok[numTok-2], "index"))
{
m_panIndexNo[iField] = atoi(papszTok[numTok-1]);
}
else
{
m_panIndexNo[iField] = 0;
}
/*-----------------------------------------------------
* Add the FieldDefn to the FeatureDefn and continue with
* the next one.
*----------------------------------------------------*/
m_poDefn->AddFieldDefn(poFieldDefn);
// AddFieldDenf() takes a copy, so we delete the original
if (poFieldDefn) delete poFieldDefn;
poFieldDefn = NULL;
}
/*---------------------------------------------------------
* OK, we're done... end the loop now.
*--------------------------------------------------------*/
break;
}/* end of fields section*/
else
{
// Simply Ignore unrecognized lines
}
}
CSLDestroy(papszTok);
if (m_poDefn->GetFieldCount() == 0)
{
CPLError(CE_Failure, CPLE_NotSupported,
"%s contains no table field definition. "
"This type of .TAB file cannot be read by this library.",
m_pszFname);
return -1;
}
return 0;
}
/**********************************************************************
* TABFile::WriteTABFile()
*
* Generate the .TAB file using mainly the attribute fields definition.
*
* This private method should be used only during the Close() call with
* write access mode.
*
* Returns 0 on success, -1 on error.
**********************************************************************/
int TABFile::WriteTABFile()
{
FILE *fp;
if (m_eAccessMode != TABWrite)
{
CPLError(CE_Failure, CPLE_NotSupported,
"WriteTABFile() can be used only with Write access.");
return -1;
}
if ( (fp = VSIFOpen(m_pszFname, "wt")) != NULL)
{
fprintf(fp, "!table\n");
fprintf(fp, "!version %d\n", m_nVersion);
fprintf(fp, "!charset %s\n", m_pszCharset);
fprintf(fp, "\n");
if (m_poDefn && m_poDefn->GetFieldCount() > 0)
{
int iField;
OGRFieldDefn *poFieldDefn;
const char *pszFieldType;
fprintf(fp, "Definition Table\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -