183 return ((
void *)
malloc(nNewSize));
185 return ((
void *)realloc(pMem, nNewSize));
203 if (!psDBF->bNoHeader)
206 psDBF->bNoHeader =
FALSE;
223 abyHeader[8] = (
unsigned char)(psDBF->nHeaderLength % 256);
224 abyHeader[9] = (
unsigned char)(psDBF->nHeaderLength / 256);
226 abyHeader[10] = (
unsigned char)(psDBF->nRecordLength % 256);
227 abyHeader[11] = (
unsigned char)(psDBF->nRecordLength / 256);
229 abyHeader[29] = (
unsigned char)(psDBF->iLanguageDriver);
235 psDBF->sHooks.FSeek(psDBF->fp, 0, 0);
237 psDBF->sHooks.FWrite(psDBF->pszHeader,
XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp);
242 if (psDBF->nHeaderLength > 32 * psDBF->nFields + 32)
247 psDBF->sHooks.FWrite(&cNewline, 1, 1, psDBF->fp);
262 if (psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1)
264 psDBF->bCurrentRecordModified =
FALSE;
266 nRecordOffset = psDBF->nRecordLength * (
SAOffset)psDBF->nCurrentRecord + psDBF->nHeaderLength;
268 if (psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0) != 0 ||
269 psDBF->sHooks.FWrite(psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp) != 1)
272 sprintf(szMessage,
"Failure writing DBF record %d.", psDBF->nCurrentRecord);
273 psDBF->sHooks.Error(szMessage);
288 if (psDBF->nCurrentRecord != iRecord)
295 nRecordOffset = psDBF->nRecordLength * (
SAOffset)iRecord + psDBF->nHeaderLength;
297 if (psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, SEEK_SET) != 0)
300 sprintf(szMessage,
"fseek(%ld) failed on DBF file.\n", (
long)nRecordOffset);
301 psDBF->sHooks.Error(szMessage);
305 if (psDBF->sHooks.FRead(psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp) != 1)
308 sprintf(szMessage,
"fread(%d) failed on DBF file.\n", psDBF->nRecordLength);
309 psDBF->sHooks.Error(szMessage);
313 psDBF->nCurrentRecord = iRecord;
326 unsigned char abyFileHeader[32];
328 if (psDBF->bNoHeader)
333 psDBF->sHooks.FSeek(psDBF->fp, 0, 0);
334 psDBF->sHooks.FRead(abyFileHeader, 32, 1, psDBF->fp);
336 abyFileHeader[4] = (
unsigned char)(psDBF->nRecords % 256);
337 abyFileHeader[5] = (
unsigned char)((psDBF->nRecords / 256) % 256);
338 abyFileHeader[6] = (
unsigned char)((psDBF->nRecords / (256 * 256)) % 256);
339 abyFileHeader[7] = (
unsigned char)((psDBF->nRecords / (256 * 256 * 256)) % 256);
341 psDBF->sHooks.FSeek(psDBF->fp, 0, 0);
342 psDBF->sHooks.FWrite(abyFileHeader, 32, 1, psDBF->fp);
344 psDBF->sHooks.FFlush(psDBF->fp);
354 DBFOpen(
const char *pszFilename,
const char *pszAccess)
360 return DBFOpenLL(pszFilename, pszAccess, &sHooks);
374 unsigned char *pabyBuf;
375 int nFields, nHeadLen, iField, i;
376 char *pszBasename, *pszFullname;
382 if (strcmp(pszAccess,
"r") != 0 && strcmp(pszAccess,
"r+") != 0 && strcmp(pszAccess,
"rb") != 0 &&
383 strcmp(pszAccess,
"rb+") != 0 && strcmp(pszAccess,
"r+b") != 0)
386 if (strcmp(pszAccess,
"r") == 0)
389 if (strcmp(pszAccess,
"r+") == 0)
396 pszBasename = (
char *)
malloc(strlen(pszFilename) + 5);
397 strcpy(pszBasename, pszFilename);
398 for (i = strlen(pszBasename) - 1;
399 i > 0 && pszBasename[i] !=
'.' && pszBasename[i] !=
'/' && pszBasename[i] !=
'\\';
403 if (pszBasename[i] ==
'.')
404 pszBasename[i] =
'\0';
406 pszFullname = (
char *)
malloc(strlen(pszBasename) + 5);
407 sprintf(pszFullname,
"%s.dbf", pszBasename);
409 psDBF = (DBFHandle)calloc(1,
sizeof(DBFInfo));
410 psDBF->fp = psHooks->
FOpen(pszFullname, pszAccess);
411 memcpy(&(psDBF->sHooks), psHooks,
sizeof(
SAHooks));
413 if (psDBF->fp == NULL)
415 sprintf(pszFullname,
"%s.DBF", pszBasename);
416 psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess);
419 sprintf(pszFullname,
"%s.cpg", pszBasename);
420 pfCPG = psHooks->
FOpen(pszFullname,
"r");
423 sprintf(pszFullname,
"%s.CPG", pszBasename);
424 pfCPG = psHooks->
FOpen(pszFullname,
"r");
430 if (psDBF->fp == NULL)
438 psDBF->bNoHeader =
FALSE;
439 psDBF->nCurrentRecord = -1;
440 psDBF->bCurrentRecordModified =
FALSE;
445 pabyBuf = (
unsigned char *)
malloc(nBufSize);
446 if (psDBF->sHooks.FRead(pabyBuf, 32, 1, psDBF->fp) != 1)
448 psDBF->sHooks.FClose(psDBF->fp);
450 psDBF->sHooks.FClose(pfCPG);
456 psDBF->nRecords = pabyBuf[4] + pabyBuf[5] * 256 + pabyBuf[6] * 256 * 256 + pabyBuf[7] * 256 * 256 * 256;
458 psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9] * 256;
459 psDBF->nRecordLength = pabyBuf[10] + pabyBuf[11] * 256;
460 psDBF->iLanguageDriver = pabyBuf[29];
464 psDBF->sHooks.FClose(psDBF->fp);
466 psDBF->sHooks.FClose(pfCPG);
472 psDBF->nFields = nFields = (nHeadLen - 32) / 32;
474 psDBF->pszCurrentRecord = (
char *)
malloc(psDBF->nRecordLength);
480 psDBF->pszCodePage = NULL;
484 memset(pabyBuf, 0, nBufSize);
485 psDBF->sHooks.FRead(pabyBuf, nBufSize - 1, 1, pfCPG);
486 n = strcspn((
char *)pabyBuf,
"\n\r");
490 psDBF->pszCodePage = (
char *)
malloc(n + 1);
491 memcpy(psDBF->pszCodePage, pabyBuf, n + 1);
493 psDBF->sHooks.FClose(pfCPG);
495 if ((psDBF->pszCodePage == NULL) && (psDBF->iLanguageDriver != 0))
497 sprintf((
char *)pabyBuf,
"LDID/%d", psDBF->iLanguageDriver);
498 psDBF->pszCodePage = (
char *)
malloc(strlen((
char *)pabyBuf) + 1);
499 strcpy(psDBF->pszCodePage, (
char *)pabyBuf);
506 pabyBuf = (
unsigned char *)
SfRealloc(pabyBuf, nHeadLen);
507 psDBF->pszHeader = (
char *)pabyBuf;
509 psDBF->sHooks.FSeek(psDBF->fp, 32, 0);
510 if (psDBF->sHooks.FRead(pabyBuf, nHeadLen - 32, 1, psDBF->fp) != 1)
512 psDBF->sHooks.FClose(psDBF->fp);
514 free(psDBF->pszCurrentRecord);
519 psDBF->panFieldOffset = (
int *)
malloc(
sizeof(
int) * nFields);
520 psDBF->panFieldSize = (
int *)
malloc(
sizeof(
int) * nFields);
521 psDBF->panFieldDecimals = (
int *)
malloc(
sizeof(
int) * nFields);
522 psDBF->pachFieldType = (
char *)
malloc(
sizeof(
char) * nFields);
524 for (iField = 0; iField < nFields; iField++)
526 unsigned char *pabyFInfo;
528 pabyFInfo = pabyBuf + iField * 32;
530 if (pabyFInfo[11] ==
'N' || pabyFInfo[11] ==
'F')
532 psDBF->panFieldSize[iField] = pabyFInfo[16];
533 psDBF->panFieldDecimals[iField] = pabyFInfo[17];
537 psDBF->panFieldSize[iField] = pabyFInfo[16];
538 psDBF->panFieldDecimals[iField] = 0;
550 psDBF->pachFieldType[iField] = (char)pabyFInfo[11];
552 psDBF->panFieldOffset[iField] = 1;
554 psDBF->panFieldOffset[iField] =
555 psDBF->panFieldOffset[iField - 1] + psDBF->panFieldSize[iField - 1];
574 if (psDBF->bNoHeader)
589 psDBF->sHooks.FClose(psDBF->fp);
591 if (psDBF->panFieldOffset != NULL)
593 free(psDBF->panFieldOffset);
594 free(psDBF->panFieldSize);
595 free(psDBF->panFieldDecimals);
596 free(psDBF->pachFieldType);
599 if (psDBF->pszWorkField != NULL)
600 free(psDBF->pszWorkField);
602 free(psDBF->pszHeader);
603 free(psDBF->pszCurrentRecord);
604 free(psDBF->pszCodePage);
634 return DBFCreateLL(pszFilename, pszCodePage, &sHooks);
648 char *pszFullname, *pszBasename;
656 pszBasename = (
char *)
malloc(strlen(pszFilename) + 5);
657 strcpy(pszBasename, pszFilename);
658 for (i = strlen(pszBasename) - 1;
659 i > 0 && pszBasename[i] !=
'.' && pszBasename[i] !=
'/' && pszBasename[i] !=
'\\';
663 if (pszBasename[i] ==
'.')
664 pszBasename[i] =
'\0';
666 pszFullname = (
char *)
malloc(strlen(pszBasename) + 5);
667 sprintf(pszFullname,
"%s.dbf", pszBasename);
672 fp = psHooks->
FOpen(pszFullname,
"wb");
680 psHooks->
FWrite(&chZero, 1, 1, fp);
683 fp = psHooks->
FOpen(pszFullname,
"rb+");
691 sprintf(pszFullname,
"%s.cpg", pszBasename);
692 if (pszCodePage != NULL)
694 if (strncmp(pszCodePage,
"LDID/", 5) == 0)
696 ldid = atoi(pszCodePage + 5);
703 psHooks->
FWrite((
char *)pszCodePage, strlen(pszCodePage), 1, fpCPG);
707 if (pszCodePage == NULL || ldid >= 0)
709 psHooks->
Remove(pszFullname);
718 psDBF = (DBFHandle)calloc(1,
sizeof(DBFInfo));
720 memcpy(&(psDBF->sHooks), psHooks,
sizeof(
SAHooks));
724 psDBF->nRecordLength = 1;
725 psDBF->nHeaderLength = 33;
727 psDBF->panFieldOffset = NULL;
728 psDBF->panFieldSize = NULL;
729 psDBF->panFieldDecimals = NULL;
730 psDBF->pachFieldType = NULL;
731 psDBF->pszHeader = NULL;
733 psDBF->nCurrentRecord = -1;
734 psDBF->bCurrentRecordModified =
FALSE;
735 psDBF->pszCurrentRecord = NULL;
737 psDBF->bNoHeader =
TRUE;
739 psDBF->iLanguageDriver = ldid > 0 ? ldid : 0;
740 psDBF->pszCodePage = NULL;
743 psDBF->pszCodePage = (
char *)
malloc(strlen(pszCodePage) + 1);
744 strcpy(psDBF->pszCodePage, pszCodePage);
757 DBFAddField(DBFHandle psDBF,
const char *pszFieldName, DBFFieldType eType,
int nWidth,
int nDecimals)
759 char chNativeType =
'C';
761 if (eType == FTLogical)
763 else if (eType == FTString)
765 else if (eType == FTDate)
806 int nOldRecordLength, nOldHeaderLength;
824 nOldRecordLength = psDBF->nRecordLength;
825 nOldHeaderLength = psDBF->nHeaderLength;
833 psDBF->panFieldOffset = (
int *)
SfRealloc(psDBF->panFieldOffset,
sizeof(
int) * psDBF->nFields);
835 psDBF->panFieldSize = (
int *)
SfRealloc(psDBF->panFieldSize,
sizeof(
int) * psDBF->nFields);
837 psDBF->panFieldDecimals = (
int *)
SfRealloc(psDBF->panFieldDecimals,
sizeof(
int) * psDBF->nFields);
839 psDBF->pachFieldType = (
char *)
SfRealloc(psDBF->pachFieldType,
sizeof(
char) * psDBF->nFields);
844 psDBF->panFieldOffset[psDBF->nFields - 1] = psDBF->nRecordLength;
845 psDBF->nRecordLength += nWidth;
846 psDBF->panFieldSize[psDBF->nFields - 1] = nWidth;
847 psDBF->panFieldDecimals[psDBF->nFields - 1] = nDecimals;
848 psDBF->pachFieldType[psDBF->nFields - 1] = chType;
853 psDBF->nHeaderLength += 32;
854 psDBF->bUpdated =
FALSE;
856 psDBF->pszHeader = (
char *)
SfRealloc(psDBF->pszHeader, psDBF->nFields * 32);
858 pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields - 1);
860 for (i = 0; i < 32; i++)
863 memcpy(pszFInfo, pszFieldName, 10);
865 pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields - 1];
869 pszFInfo[16] = (
unsigned char)(nWidth % 256);
870 pszFInfo[17] = (
unsigned char)(nWidth / 256);
874 pszFInfo[16] = (
unsigned char)nWidth;
875 pszFInfo[17] = (
unsigned char)nDecimals;
881 psDBF->pszCurrentRecord = (
char *)
SfRealloc(psDBF->pszCurrentRecord, psDBF->nRecordLength);
884 if (psDBF->bNoHeader)
885 return (psDBF->nFields - 1);
892 pszRecord = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
896 for (i = psDBF->nRecords - 1; i >= 0; --i)
898 nRecordOffset = nOldRecordLength * (
SAOffset)i + nOldHeaderLength;
901 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
902 psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp);
905 memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
907 nRecordOffset = psDBF->nRecordLength * (
SAOffset)i + psDBF->nHeaderLength;
910 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
911 psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
918 psDBF->bNoHeader =
TRUE;
921 psDBF->nCurrentRecord = -1;
922 psDBF->bCurrentRecordModified =
FALSE;
924 return (psDBF->nFields - 1);
936 unsigned char *pabyRec;
937 void *pReturnField = NULL;
942 if (hEntity < 0 || hEntity >= psDBF->nRecords)
945 if (iField < 0 || iField >= psDBF->nFields)
954 pabyRec = (
unsigned char *)psDBF->pszCurrentRecord;
959 if (psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength)
961 psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100;
962 if (psDBF->pszWorkField == NULL)
963 psDBF->pszWorkField = (
char *)
malloc(psDBF->nWorkFieldLength);
965 psDBF->pszWorkField = (
char *)realloc(psDBF->pszWorkField, psDBF->nWorkFieldLength);
972 psDBF->pszWorkField, ((
const char *)pabyRec) + psDBF->panFieldOffset[iField], psDBF->panFieldSize[iField]);
973 psDBF->pszWorkField[psDBF->panFieldSize[iField]] =
'\0';
975 pReturnField = psDBF->pszWorkField;
980 if (chReqType ==
'N')
982 psDBF->dfDoubleField = psDBF->sHooks.Atof(psDBF->pszWorkField);
984 pReturnField = &(psDBF->dfDoubleField);
990 #ifdef TRIM_DBF_WHITESPACE
993 char *pchSrc, *pchDst;
995 pchDst = pchSrc = psDBF->pszWorkField;
996 while (*pchSrc ==
' ')
999 while (*pchSrc !=
'\0')
1000 *(pchDst++) = *(pchSrc++);
1003 while (pchDst != psDBF->pszWorkField && *(--pchDst) ==
' ')
1008 return (pReturnField);
1024 if (pdValue == NULL)
1027 return ((
int)*pdValue);
1043 if (pdValue == NULL)
1084 if (pszValue == NULL)
1096 if (pszValue[0] ==
'*')
1099 for (i = 0; pszValue[i] !=
'\0'; i++)
1101 if (pszValue[i] !=
' ')
1108 if (pszValue[0] ==
'\0' ||
1109 strncmp(pszValue,
"00000000", 8) == 0 || strncmp(pszValue,
" ", 8) == 0)
1121 if (pszValue[0] ==
'\0' || pszValue[0] ==
'?')
1132 return strlen(pszValue) == 0;
1147 const char *pszValue;
1151 if (pszValue == NULL)
1166 return (psDBF->nFields);
1178 return (psDBF->nRecords);
1188 DBFGetFieldInfo(DBFHandle psDBF,
int iField,
char *pszFieldName,
int *pnWidth,
int *pnDecimals)
1190 if (iField < 0 || iField >= psDBF->nFields)
1193 if (pnWidth != NULL)
1194 *pnWidth = psDBF->panFieldSize[iField];
1196 if (pnDecimals != NULL)
1197 *pnDecimals = psDBF->panFieldDecimals[iField];
1199 if (pszFieldName != NULL)
1203 strncpy(pszFieldName, (
char *)psDBF->pszHeader + iField * 32, 11);
1204 pszFieldName[11] =
'\0';
1205 for (i = 10; i > 0 && pszFieldName[i] ==
' '; i--)
1206 pszFieldName[i] =
'\0';
1209 if (psDBF->pachFieldType[iField] ==
'L')
1212 else if (psDBF->pachFieldType[iField] ==
'D')
1215 else if (psDBF->pachFieldType[iField] ==
'N' || psDBF->pachFieldType[iField] ==
'F')
1217 if (psDBF->panFieldDecimals[iField] > 0 || psDBF->panFieldSize[iField] > 10)
1237 int i, j, nRetResult =
TRUE;
1238 unsigned char *pabyRec;
1239 char szSField[400], szFormat[20];
1244 if (hEntity < 0 || hEntity > psDBF->nRecords)
1247 if (psDBF->bNoHeader)
1253 if (hEntity == psDBF->nRecords)
1259 for (i = 0; i < psDBF->nRecordLength; i++)
1260 psDBF->pszCurrentRecord[i] =
' ';
1262 psDBF->nCurrentRecord = hEntity;
1272 pabyRec = (
unsigned char *)psDBF->pszCurrentRecord;
1274 psDBF->bCurrentRecordModified =
TRUE;
1275 psDBF->bUpdated =
TRUE;
1284 memset((
char *)(pabyRec + psDBF->panFieldOffset[iField]),
1286 psDBF->panFieldSize[iField]);
1293 switch (psDBF->pachFieldType[iField])
1298 if (psDBF->panFieldDecimals[iField] == 0)
1300 int nWidth = psDBF->panFieldSize[iField];
1302 if ((
int)
sizeof(szSField) - 2 < nWidth)
1303 nWidth =
sizeof(szSField) - 2;
1305 sprintf(szFormat,
"%%%dd", nWidth);
1306 sprintf(szSField, szFormat, (
int)*((
double *)pValue));
1307 if ((
int)strlen(szSField) > psDBF->panFieldSize[iField])
1309 szSField[psDBF->panFieldSize[iField]] =
'\0';
1313 (
char *)(pabyRec + psDBF->panFieldOffset[iField]), szSField, psDBF->panFieldSize[iField]);
1317 int nWidth = psDBF->panFieldSize[iField];
1319 if ((
int)
sizeof(szSField) - 2 < nWidth)
1320 nWidth =
sizeof(szSField) - 2;
1322 sprintf(szFormat,
"%%%d.%df", nWidth, psDBF->panFieldDecimals[iField]);
1323 sprintf(szSField, szFormat, *((
double *)pValue));
1324 if ((
int)strlen(szSField) > psDBF->panFieldSize[iField])
1326 szSField[psDBF->panFieldSize[iField]] =
'\0';
1330 (
char *)(pabyRec + psDBF->panFieldOffset[iField]), szSField, psDBF->panFieldSize[iField]);
1335 if (psDBF->panFieldSize[iField] >= 1 && (*(
char *)pValue ==
'F' || *(
char *)pValue ==
'T'))
1336 *(pabyRec + psDBF->panFieldOffset[iField]) = *(
char *)pValue;
1340 if ((
int)strlen((
char *)pValue) > psDBF->panFieldSize[iField])
1342 j = psDBF->panFieldSize[iField];
1347 memset(pabyRec + psDBF->panFieldOffset[iField],
' ', psDBF->panFieldSize[iField]);
1348 j = strlen((
char *)pValue);
1350 memcpy((
char *)(pabyRec + psDBF->panFieldOffset[iField]), (
char *)pValue, j);
1369 unsigned char *pabyRec;
1374 if (hEntity < 0 || hEntity > psDBF->nRecords)
1377 if (psDBF->bNoHeader)
1383 if (hEntity == psDBF->nRecords)
1389 for (i = 0; i < psDBF->nRecordLength; i++)
1390 psDBF->pszCurrentRecord[i] =
' ';
1392 psDBF->nCurrentRecord = hEntity;
1402 pabyRec = (
unsigned char *)psDBF->pszCurrentRecord;
1407 if ((
int)strlen((
char *)pValue) > psDBF->panFieldSize[iField])
1408 j = psDBF->panFieldSize[iField];
1411 memset(pabyRec + psDBF->panFieldOffset[iField],
' ', psDBF->panFieldSize[iField]);
1412 j = strlen((
char *)pValue);
1415 memcpy((
char *)(pabyRec + psDBF->panFieldOffset[iField]), (
char *)pValue, j);
1417 psDBF->bCurrentRecordModified =
TRUE;
1418 psDBF->bUpdated =
TRUE;
1444 double dValue = nValue;
1495 unsigned char *pabyRec;
1500 if (hEntity < 0 || hEntity > psDBF->nRecords)
1503 if (psDBF->bNoHeader)
1509 if (hEntity == psDBF->nRecords)
1515 for (i = 0; i < psDBF->nRecordLength; i++)
1516 psDBF->pszCurrentRecord[i] =
' ';
1518 psDBF->nCurrentRecord = hEntity;
1528 pabyRec = (
unsigned char *)psDBF->pszCurrentRecord;
1530 memcpy(pabyRec, pRawTuple, psDBF->nRecordLength);
1532 psDBF->bCurrentRecordModified =
TRUE;
1533 psDBF->bUpdated =
TRUE;
1548 if (hEntity < 0 || hEntity >= psDBF->nRecords)
1554 return (
const char *)psDBF->pszCurrentRecord;
1568 newDBF =
DBFCreateEx(pszFilename, psDBF->pszCodePage);
1572 newDBF->nFields = psDBF->nFields;
1573 newDBF->nRecordLength = psDBF->nRecordLength;
1574 newDBF->nHeaderLength = psDBF->nHeaderLength;
1576 newDBF->pszHeader = (
char *)
malloc(newDBF->nHeaderLength);
1577 memcpy(newDBF->pszHeader, psDBF->pszHeader, newDBF->nHeaderLength);
1579 newDBF->panFieldOffset = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1580 memcpy(newDBF->panFieldOffset, psDBF->panFieldOffset,
sizeof(
int) * psDBF->nFields);
1581 newDBF->panFieldSize = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1582 memcpy(newDBF->panFieldSize, psDBF->panFieldSize,
sizeof(
int) * psDBF->nFields);
1583 newDBF->panFieldDecimals = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1584 memcpy(newDBF->panFieldDecimals, psDBF->panFieldDecimals,
sizeof(
int) * psDBF->nFields);
1585 newDBF->pachFieldType = (
char *)
malloc(
sizeof(
char) * psDBF->nFields);
1586 memcpy(newDBF->pachFieldType, psDBF->pachFieldType,
sizeof(
char) * psDBF->nFields);
1588 newDBF->bNoHeader =
TRUE;
1589 newDBF->bUpdated =
TRUE;
1594 newDBF =
DBFOpen(pszFilename,
"rb+");
1613 if (iField >= 0 && iField < psDBF->nFields)
1614 return psDBF->pachFieldType[iField];
1629 len = strlen(
string);
1632 if (isalpha(
string[i]) && islower(
string[i]))
1633 string[i] = (char)toupper((
int)
string[i]);
1647 char name[12], name1[12], name2[12];
1650 snprintf(name1, 11,
"%s", pszFieldName);
1657 snprintf(name2, 12,
"%s", name);
1660 if (!strncmp(name1, name2, 10))
1679 if (iShape < 0 || (psDBF->nRecords > 0 && iShape >= psDBF->nRecords))
1691 return psDBF->pszCurrentRecord[0] ==
'*';
1706 if (iShape < 0 || iShape >= psDBF->nRecords)
1724 if (psDBF->pszCurrentRecord[0] != chNewFlag)
1726 psDBF->bCurrentRecordModified =
TRUE;
1727 psDBF->bUpdated =
TRUE;
1728 psDBF->pszCurrentRecord[0] = chNewFlag;
1743 return psDBF->pszCodePage;
1755 int nOldRecordLength, nOldHeaderLength;
1756 int nDeletedFieldOffset, nDeletedFieldSize;
1761 if (iField < 0 || iField >= psDBF->nFields)
1769 nOldRecordLength = psDBF->nRecordLength;
1770 nOldHeaderLength = psDBF->nHeaderLength;
1771 nDeletedFieldOffset = psDBF->panFieldOffset[iField];
1772 nDeletedFieldSize = psDBF->panFieldSize[iField];
1775 for (i = iField + 1; i < psDBF->nFields; i++)
1777 psDBF->panFieldOffset[i - 1] = psDBF->panFieldOffset[i] - nDeletedFieldSize;
1778 psDBF->panFieldSize[i - 1] = psDBF->panFieldSize[i];
1779 psDBF->panFieldDecimals[i - 1] = psDBF->panFieldDecimals[i];
1780 psDBF->pachFieldType[i - 1] = psDBF->pachFieldType[i];
1786 psDBF->panFieldOffset = (
int *)
SfRealloc(psDBF->panFieldOffset,
sizeof(
int) * psDBF->nFields);
1788 psDBF->panFieldSize = (
int *)
SfRealloc(psDBF->panFieldSize,
sizeof(
int) * psDBF->nFields);
1790 psDBF->panFieldDecimals = (
int *)
SfRealloc(psDBF->panFieldDecimals,
sizeof(
int) * psDBF->nFields);
1792 psDBF->pachFieldType = (
char *)
SfRealloc(psDBF->pachFieldType,
sizeof(
char) * psDBF->nFields);
1795 psDBF->nHeaderLength -= 32;
1796 psDBF->nRecordLength -= nDeletedFieldSize;
1799 memmove(psDBF->pszHeader + iField * 32,
1800 psDBF->pszHeader + (iField + 1) * 32,
1801 sizeof(
char) * (psDBF->nFields - iField) * 32);
1803 psDBF->pszHeader = (
char *)
SfRealloc(psDBF->pszHeader, psDBF->nFields * 32);
1806 psDBF->pszCurrentRecord = (
char *)
SfRealloc(psDBF->pszCurrentRecord, psDBF->nRecordLength);
1809 if (psDBF->bNoHeader && psDBF->nRecords == 0)
1813 psDBF->bNoHeader =
TRUE;
1817 pszRecord = (
char *)
malloc(
sizeof(
char) * nOldRecordLength);
1820 for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
1822 nRecordOffset = nOldRecordLength * (
SAOffset)iRecord + nOldHeaderLength;
1825 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
1826 psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp);
1828 nRecordOffset = psDBF->nRecordLength * (
SAOffset)iRecord + psDBF->nHeaderLength;
1831 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
1832 psDBF->sHooks.FWrite(pszRecord, nDeletedFieldOffset, 1, psDBF->fp);
1833 psDBF->sHooks.FWrite(pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
1834 nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize,
1844 psDBF->nCurrentRecord = -1;
1845 psDBF->bCurrentRecordModified =
FALSE;
1865 int *panFieldOffsetNew;
1866 int *panFieldSizeNew;
1867 int *panFieldDecimalsNew;
1868 char *pachFieldTypeNew;
1873 if (psDBF->nFields == 0)
1880 panFieldOffsetNew = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1881 panFieldSizeNew = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1882 panFieldDecimalsNew = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1883 pachFieldTypeNew = (
char *)
malloc(
sizeof(
char) * psDBF->nFields);
1884 pszHeaderNew = (
char *)
malloc(
sizeof(
char) * 32 * psDBF->nFields);
1887 for (i = 0; i < psDBF->nFields; i++)
1889 panFieldSizeNew[i] = psDBF->panFieldSize[panMap[i]];
1890 panFieldDecimalsNew[i] = psDBF->panFieldDecimals[panMap[i]];
1891 pachFieldTypeNew[i] = psDBF->pachFieldType[panMap[i]];
1892 memcpy(pszHeaderNew + i * 32, psDBF->pszHeader + panMap[i] * 32, 32);
1894 panFieldOffsetNew[0] = 1;
1895 for (i = 1; i < psDBF->nFields; i++)
1897 panFieldOffsetNew[i] = panFieldOffsetNew[i - 1] + panFieldSizeNew[i - 1];
1900 free(psDBF->pszHeader);
1901 psDBF->pszHeader = pszHeaderNew;
1904 if (!(psDBF->bNoHeader && psDBF->nRecords == 0))
1907 psDBF->bNoHeader =
TRUE;
1911 pszRecord = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
1912 pszRecordNew = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
1915 for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
1917 nRecordOffset = psDBF->nRecordLength * (
SAOffset)iRecord + psDBF->nHeaderLength;
1920 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
1921 psDBF->sHooks.FRead(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
1923 pszRecordNew[0] = pszRecord[0];
1925 for (i = 0; i < psDBF->nFields; i++)
1927 memcpy(pszRecordNew + panFieldOffsetNew[i],
1928 pszRecord + psDBF->panFieldOffset[panMap[i]],
1929 psDBF->panFieldSize[panMap[i]]);
1933 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
1934 psDBF->sHooks.FWrite(pszRecordNew, psDBF->nRecordLength, 1, psDBF->fp);
1942 free(psDBF->panFieldOffset);
1943 free(psDBF->panFieldSize);
1944 free(psDBF->panFieldDecimals);
1945 free(psDBF->pachFieldType);
1947 psDBF->panFieldOffset = panFieldOffsetNew;
1948 psDBF->panFieldSize = panFieldSizeNew;
1949 psDBF->panFieldDecimals = panFieldDecimalsNew;
1950 psDBF->pachFieldType = pachFieldTypeNew;
1952 psDBF->nCurrentRecord = -1;
1953 psDBF->bCurrentRecordModified =
FALSE;
1965 DBFAlterFieldDefn(DBFHandle psDBF,
int iField,
const char *pszFieldName,
char chType,
int nWidth,
int nDecimals)
1971 int nOldRecordLength;
1978 if (iField < 0 || iField >= psDBF->nFields)
1987 chOldType = psDBF->pachFieldType[iField];
1988 nOffset = psDBF->panFieldOffset[iField];
1989 nOldWidth = psDBF->panFieldSize[iField];
1990 nOldRecordLength = psDBF->nRecordLength;
2004 psDBF->panFieldSize[iField] = nWidth;
2005 psDBF->panFieldDecimals[iField] = nDecimals;
2006 psDBF->pachFieldType[iField] = chType;
2011 pszFInfo = psDBF->pszHeader + 32 * iField;
2013 for (i = 0; i < 32; i++)
2016 snprintf(pszFInfo, 10,
"%s", pszFieldName);
2018 pszFInfo[11] = psDBF->pachFieldType[iField];
2022 pszFInfo[16] = (
unsigned char)(nWidth % 256);
2023 pszFInfo[17] = (
unsigned char)(nWidth / 256);
2027 pszFInfo[16] = (
unsigned char)nWidth;
2028 pszFInfo[17] = (
unsigned char)nDecimals;
2034 if (nWidth != nOldWidth)
2036 for (i = iField + 1; i < psDBF->nFields; i++)
2037 psDBF->panFieldOffset[i] += nWidth - nOldWidth;
2038 psDBF->nRecordLength += nWidth - nOldWidth;
2040 psDBF->pszCurrentRecord = (
char *)
SfRealloc(psDBF->pszCurrentRecord, psDBF->nRecordLength);
2044 if (psDBF->bNoHeader && psDBF->nRecords == 0)
2048 psDBF->bNoHeader =
TRUE;
2051 if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType))
2053 char *pszRecord = (
char *)
malloc(
sizeof(
char) * nOldRecordLength);
2054 char *pszOldField = (
char *)
malloc(
sizeof(
char) * (nOldWidth + 1));
2056 pszOldField[nOldWidth] = 0;
2059 for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
2061 nRecordOffset = nOldRecordLength * (
SAOffset)iRecord + psDBF->nHeaderLength;
2064 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2065 psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp);
2067 memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
2070 if (nWidth != nOldWidth)
2072 if ((chOldType ==
'N' || chOldType ==
'F') && pszOldField[0] ==
' ')
2075 memmove(pszRecord + nOffset, pszRecord + nOffset + nOldWidth - nWidth, nWidth);
2077 if (nOffset + nOldWidth < nOldRecordLength)
2079 memmove(pszRecord + nOffset + nWidth,
2080 pszRecord + nOffset + nOldWidth,
2081 nOldRecordLength - (nOffset + nOldWidth));
2088 memset(pszRecord + nOffset, chFieldFill, nWidth);
2091 nRecordOffset = psDBF->nRecordLength * (
SAOffset)iRecord + psDBF->nHeaderLength;
2094 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2095 psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
2101 else if (nWidth > nOldWidth)
2103 char *pszRecord = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
2104 char *pszOldField = (
char *)
malloc(
sizeof(
char) * (nOldWidth + 1));
2106 pszOldField[nOldWidth] = 0;
2109 for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
2111 nRecordOffset = nOldRecordLength * (
SAOffset)iRecord + psDBF->nHeaderLength;
2114 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2115 psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp);
2117 memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
2120 if (nOffset + nOldWidth < nOldRecordLength)
2122 memmove(pszRecord + nOffset + nWidth,
2123 pszRecord + nOffset + nOldWidth,
2124 nOldRecordLength - (nOffset + nOldWidth));
2130 memset(pszRecord + nOffset, chFieldFill, nWidth);
2134 if ((chOldType ==
'N' || chOldType ==
'F'))
2138 pszRecord + nOffset + nWidth - nOldWidth, pszRecord + nOffset, nOldWidth);
2139 memset(pszRecord + nOffset,
' ', nWidth - nOldWidth);
2144 memset(pszRecord + nOffset + nOldWidth,
' ', nWidth - nOldWidth);
2148 nRecordOffset = psDBF->nRecordLength * (
SAOffset)iRecord + psDBF->nHeaderLength;
2151 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2152 psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
2159 psDBF->nCurrentRecord = -1;
2160 psDBF->bCurrentRecordModified =
FALSE;
static int DBFIsValueNULL(char chType, const char *pszValue)
const char SHPAPI_CALL1 * DBFGetCodePage(DBFHandle psDBF){ if(psDBF==NULL) return NULL;return psDBF->pszCodePage;}int SHPAPI_CALLDBFDeleteField(DBFHandle psDBF, int iField
const char SHPAPI_CALL1 * DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField){ return((const char *) DBFReadAttribute(psDBF, iRecord, iField, 'C')
int SHPAPI_CALL DBFMarkRecordDeleted(DBFHandle psDBF, int iShape, int bIsDeleted)
int SHPAPI_CALL DBFWriteDoubleAttribute(DBFHandle psDBF, int iRecord, int iField, double dValue)
int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF)
int SHPAPI_CALL DBFReadIntegerAttribute(DBFHandle psDBF, int iRecord, int iField)
const char SHPAPI_CALL1 * DBFReadTuple(DBFHandle psDBF, int hEntity){ if(hEntity< 0||hEntity >=psDBF->nRecords) return(NULL
int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, const char *pszFieldName, char chType, int nWidth, int nDecimals)
static int DBFLoadRecord(DBFHandle psDBF, int iRecord)
DBFHandle SHPAPI_CALL DBFOpen(const char *pszFilename, const char *pszAccess)
double SHPAPI_CALL DBFReadDoubleAttribute(DBFHandle psDBF, int iRecord, int iField)
if(!DBFLoadRecord(psDBF, hEntity)) return NULL
int SHPAPI_CALL DBFAddField(DBFHandle psDBF, const char *pszFieldName, DBFFieldType eType, int nWidth, int nDecimals)
DBFHandle SHPAPI_CALL DBFCreateLL(const char *pszFilename, const char *pszCodePage, SAHooks *psHooks)
static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, void *pValue)
const char SHPAPI_CALL1 * DBFReadLogicalAttribute(DBFHandle psDBF, int iRecord, int iField){ return((const char *) DBFReadAttribute(psDBF, iRecord, iField, 'L')
int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF)
int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle psDBF, int iRecord, int iField, int nValue)
int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle psDBF, int iRecord, int iField, const char *pszValue)
DBFHandle SHPAPI_CALL DBFCreateEx(const char *pszFilename, const char *pszCodePage)
static void str_to_upper(char *string)
void SHPAPI_CALL DBFClose(DBFHandle psDBF)
static void DBFWriteHeader(DBFHandle psDBF)
int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName, char chType, int nWidth, int nDecimals)
DBFHandle SHPAPI_CALL DBFCreate(const char *pszFilename)
DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, SAHooks *psHooks)
static void * SfRealloc(void *pMem, int nNewSize)
int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField)
static char DBFGetNullCharacter(char chType)
int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle psDBF, int iRecord, int iField)
int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity, void *pRawTuple)
int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, void *pValue)
static int DBFFlushRecord(DBFHandle psDBF)
int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, int *panMap)
int SHPAPI_CALL DBFIsRecordDeleted(DBFHandle psDBF, int iShape)
int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle psDBF, int iRecord, int iField, const char lValue)
char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle psDBF, int iField)
static void * DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, char chReqType)
void SHPAPI_CALL DBFUpdateHeader(DBFHandle psDBF)
DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField, char *pszFieldName, int *pnWidth, int *pnDecimals)
void SASetupDefaultHooks(SAHooks *psHooks)
int SHPAPI_CALL DBFDeleteField(DBFHandle hDBF, int iField)
#define SHP_CVSID(string)
DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char *pszFilename)
SAFile(* FOpen)(const char *filename, const char *access)
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
int(* Remove)(const char *filename)
int(* FClose)(SAFile file)