26#include "cpl_string.h"
31#define STRCASECMP(a, b) (_stricmp(a, b))
33#define STRCASECMP(a, b) (stricmp(a, b))
36#define STRCASECMP(a, b) (strcasecmp(a, b))
42#define snprintf _snprintf
46#define snprintf _snprintf
50#define CPLsprintf sprintf
51#define CPLsnprintf snprintf
60#define XBASE_FILEHDR_SZ 32
62#define HEADER_RECORD_TERMINATOR 0x0D
65#define END_OF_FILE_CHARACTER 0x1A
72#define CPL_IGNORE_RET_VAL_INT(x) x
88 if (!
psDBF->bNoHeader)
125 if (
psDBF->nHeaderLength >
134 if (
psDBF->nRecords == 0 &&
psDBF->bWriteEndOfFileChar) {
149 if (
psDBF->bCurrentRecordModified &&
psDBF->nCurrentRecord > -1) {
153 psDBF->nRecordLength *
155 psDBF->nHeaderLength;
163 if (
psDBF->bRequireNextWriteSeek ||
169 "Failure seeking to position before writing DBF record %d.",
170 psDBF->nCurrentRecord);
176 if (
psDBF->sHooks.FWrite(
psDBF->pszCurrentRecord,
psDBF->nRecordLength,
180 "Failure writing DBF record %d.",
psDBF->nCurrentRecord);
192 if (
psDBF->nCurrentRecord ==
psDBF->nRecords - 1) {
193 if (
psDBF->bWriteEndOfFileChar) {
210 if (!DBFFlushRecord(
psDBF))
215 psDBF->nHeaderLength;
220 "fseek(%ld) failed on DBF file.",
230 "fread(%d) failed on DBF file.",
psDBF->nRecordLength);
254 if (
psDBF->bNoHeader)
255 DBFWriteHeader(
psDBF);
257 if (!DBFFlushRecord(
psDBF))
313static int DBFGetLenWithoutExtension(
const char *
pszBasename)
316 for (
int i =
nLen - 1;
391 psDBF->nCurrentRecord = -1;
397 const int nBufSize = 500;
435 psDBF->nFields = nFields;
439 if (!
psDBF->pszCurrentRecord) {
459 if (
psDBF->pszCodePage)
466 psDBF->iLanguageDriver);
469 if (
psDBF->pszCodePage)
507 if (!
psDBF->panFieldOffset || !
psDBF->panFieldSize ||
508 !
psDBF->panFieldDecimals || !
psDBF->pachFieldType) {
552 psDBF->nRecordLength) {
576 if (
psDBF->bNoHeader)
577 DBFWriteHeader(
psDBF);
628 const char *pszCodePage)
644 const char *pszCodePage,
679 if (
strncmp(pszCodePage,
"LDID/", 5) == 0) {
712 psDBF->nRecordLength = 1;
713 psDBF->nHeaderLength =
722 psDBF->nCurrentRecord = -1;
733 if (
psDBF->pszCodePage)
773static char DBFGetNullCharacter(
char chType)
799 if (!DBFFlushRecord(
psDBF))
805 "Cannot add field %s. Header length limit reached "
806 "(max 65535 bytes, 2046 fields).",
824 "Cannot add field %s. Record length limit reached "
825 "(max 65535 bytes).",
841 sizeof(
int) * (
psDBF->nFields + 1)));
845 sizeof(
int) * (
psDBF->nFields + 1)));
849 sizeof(
int) * (
psDBF->nFields + 1)));
853 sizeof(
char) * (
psDBF->nFields + 1)));
881 psDBF->sHooks.Error(
"Out of memory");
887 if (!
psDBF->bNoHeader) {
890 psDBF->sHooks.Error(
"Out of memory");
931 if (
psDBF->bNoHeader)
932 return (
psDBF->nFields - 1);
941 for (
int i =
psDBF->nRecords - 1; i >= 0; --i) {
957 psDBF->nHeaderLength;
964 if (
psDBF->bWriteEndOfFileChar) {
969 psDBF->nHeaderLength;
982 psDBF->nCurrentRecord = -1;
986 return (
psDBF->nFields - 1);
1013 const unsigned char *pabyRec =
1022 psDBF->pszWorkField =
1049 psDBF->fieldValue.dfDoubleField =
1058#ifdef TRIM_DBF_WHITESPACE
1175static bool DBFIsValueNULL(
char chType,
const char *
pszValue,
int size)
1191 for (
int i = 0;
pszValue[i] !=
'\0'; i++) {
1211 for (
int i = 0; i < size; i++)
1255 return (
psDBF->nFields);
1266 return (
psDBF->nRecords);
1335 if (
psDBF->bNoHeader)
1336 DBFWriteHeader(
psDBF);
1342 if (!DBFFlushRecord(
psDBF))
1346 for (
int i = 0; i <
psDBF->nRecordLength; i++)
1347 psDBF->pszCurrentRecord[i] =
' ';
1359 unsigned char *pabyRec =
1372 DBFGetNullCharacter(
psDBF->pachFieldType[
iField]),
1460 if (
psDBF->bNoHeader)
1461 DBFWriteHeader(
psDBF);
1467 if (!DBFFlushRecord(
psDBF))
1471 for (
int i = 0; i <
psDBF->nRecordLength; i++)
1472 psDBF->pszCurrentRecord[i] =
' ';
1485 unsigned char *pabyRec =
1620 if (
psDBF->bNoHeader)
1621 DBFWriteHeader(
psDBF);
1627 if (!DBFFlushRecord(
psDBF))
1631 for (
int i = 0; i <
psDBF->nRecordLength; i++)
1632 psDBF->pszCurrentRecord[i] =
' ';
1644 unsigned char *pabyRec =
1692 if (
psDBF->pszHeader) {
1702 sizeof(
int) *
psDBF->nFields);
1706 sizeof(
int) *
psDBF->nFields);
1707 newDBF->panFieldDecimals =
1710 sizeof(
int) *
psDBF->nFields);
1714 sizeof(
char) *
psDBF->nFields);
1718 newDBF->bWriteEndOfFileChar =
psDBF->bWriteEndOfFileChar;
1724 newDBF->bWriteEndOfFileChar =
psDBF->bWriteEndOfFileChar;
1793 return psDBF->pszCurrentRecord[0] ==
'*';
1838 return psDBF->pszCodePage;
1853 if (!DBFFlushRecord(
psDBF))
1863 for (
int i =
iField + 1; i <
psDBF->nFields; i++) {
1864 psDBF->panFieldOffset[i - 1] =
1866 psDBF->panFieldSize[i - 1] =
psDBF->panFieldSize[i];
1867 psDBF->panFieldDecimals[i - 1] =
psDBF->panFieldDecimals[i];
1868 psDBF->pachFieldType[i - 1] =
psDBF->pachFieldType[i];
1903 if (
psDBF->bNoHeader &&
psDBF->nRecords == 0)
1929 psDBF->nHeaderLength;
1934 psDBF->sHooks.FWrite(
1940 if (
psDBF->bWriteEndOfFileChar) {
1944 psDBF->nHeaderLength;
1955 psDBF->nCurrentRecord = -1;
1974 if (
psDBF->nFields == 0)
1978 if (!DBFFlushRecord(
psDBF))
1995 if (!(
psDBF->bNoHeader &&
psDBF->nRecords == 0)) {
2004 (!(
psDBF->bNoHeader &&
psDBF->nRecords == 0) &&
2013 psDBF->sHooks.Error(
"Out of memory");
2018 for (
int i = 0; i <
psDBF->nFields; i++) {
2026 for (
int i = 1; i <
psDBF->nFields; i++) {
2037 if (!(
psDBF->bNoHeader &&
psDBF->nRecords == 0)) {
2046 psDBF->nHeaderLength;
2058 for (
int i = 0; i <
psDBF->nFields; i++) {
2080 psDBF->nCurrentRecord = -1;
2096 psDBF->nCurrentRecord = -1;
2117 if (!DBFFlushRecord(
psDBF))
2196 if (
psDBF->bNoHeader &&
psDBF->nRecords == 0) {
2215 psDBF->nHeaderLength;
2251 psDBF->nHeaderLength;
2263 psDBF->nHeaderLength;
2277 psDBF->nHeaderLength;
2317 psDBF->nHeaderLength;
2329 psDBF->nHeaderLength;
2340 psDBF->nCurrentRecord = -1;
2346 psDBF->nCurrentRecord = -1;
DBFHandle DBFCloneEmpty(const DBFHandle psDBF, const char *pszFilename)
const char * DBFGetCodePage(const DBFHandle psDBF)
int DBFWriteIntegerAttribute(DBFHandle psDBF, int iRecord, int iField, int nValue)
const char * DBFReadTuple(DBFHandle psDBF, int hEntity)
DBFHandle DBFCreate(const char *pszFilename)
int DBFWriteStringAttribute(DBFHandle psDBF, int iRecord, int iField, const char *pszValue)
int DBFGetFieldCount(const DBFHandle psDBF)
int DBFMarkRecordDeleted(DBFHandle psDBF, int iShape, int bIsDeleted)
int DBFWriteLogicalAttribute(DBFHandle psDBF, int iRecord, int iField, const char lValue)
DBFHandle DBFOpenLL(const char *pszFilename, const char *pszAccess, const SAHooks *psHooks)
int DBFDeleteField(DBFHandle psDBF, int iField)
void DBFClose(DBFHandle psDBF)
int DBFAddField(DBFHandle psDBF, const char *pszFieldName, DBFFieldType eType, int nWidth, int nDecimals)
int DBFAlterFieldDefn(DBFHandle psDBF, int iField, const char *pszFieldName, char chType, int nWidth, int nDecimals)
int DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField)
SHPDate DBFReadDateAttribute(DBFHandle psDBF, int iRecord, int iField)
int DBFIsRecordDeleted(const DBFHandle psDBF, int iShape)
void DBFSetWriteEndOfFileChar(DBFHandle psDBF, int bWriteFlag)
int DBFReadIntegerAttribute(DBFHandle psDBF, int iRecord, int iField)
DBFHandle DBFCreateEx(const char *pszFilename, const char *pszCodePage)
int DBFIsAttributeNULL(const DBFHandle psDBF, int iRecord, int iField)
DBFFieldType DBFGetFieldInfo(const DBFHandle psDBF, int iField, char *pszFieldName, int *pnWidth, int *pnDecimals)
int DBFReorderFields(DBFHandle psDBF, const int *panMap)
const char * DBFReadLogicalAttribute(DBFHandle psDBF, int iRecord, int iField)
int DBFWriteDoubleAttribute(DBFHandle psDBF, int iRecord, int iField, double dValue)
double DBFReadDoubleAttribute(DBFHandle psDBF, int iRecord, int iField)
#define HEADER_RECORD_TERMINATOR
void DBFSetLastModifiedDate(DBFHandle psDBF, int nYYSince1900, int nMM, int nDD)
void DBFUpdateHeader(DBFHandle psDBF)
char DBFGetNativeFieldType(const DBFHandle psDBF, int iField)
DBFHandle DBFCreateLL(const char *pszFilename, const char *pszCodePage, const SAHooks *psHooks)
int DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName, char chType, int nWidth, int nDecimals)
#define END_OF_FILE_CHARACTER
int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, const void *pValue)
int DBFGetRecordCount(const DBFHandle psDBF)
const char * DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField)
int DBFWriteDateAttribute(DBFHandle psDBF, int iRecord, int iField, const SHPDate *lValue)
int DBFWriteTuple(DBFHandle psDBF, int hEntity, const void *pRawTuple)
DBFHandle DBFOpen(const char *pszFilename, const char *pszAccess)
int DBFGetFieldIndex(const DBFHandle psDBF, const char *pszFieldName)
#define CPL_IGNORE_RET_VAL_INT(x)
#define assert(condition)
void SASetupDefaultHooks(SAHooks *psHooks)
#define XBASE_FLDNAME_LEN_WRITE
#define XBASE_FLDNAME_LEN_READ
#define XBASE_FLD_MAX_WIDTH
#define STATIC_CAST(type, x)
#define REINTERPRET_CAST(type, x)
#define CONST_CAST(type, x)