165 SHP_CVSID(
"$Id: dbfopen.c 15722 2017-09-14 13:52:25Z pramsey $")
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 );
236 psDBF->sHooks.FWrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
237 psDBF->sHooks.FWrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields,
243 if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
248 psDBF->sHooks.FWrite( &cNewline, 1, 1, psDBF->fp );
263 if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
265 psDBF->bCurrentRecordModified =
FALSE;
268 psDBF->nRecordLength * (
SAOffset) psDBF->nCurrentRecord
269 + psDBF->nHeaderLength;
271 if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 ) != 0
272 || psDBF->sHooks.FWrite( psDBF->pszCurrentRecord,
273 psDBF->nRecordLength,
274 1, psDBF->fp ) != 1 )
277 sprintf( szMessage,
"Failure writing DBF record %d.",
278 psDBF->nCurrentRecord );
279 psDBF->sHooks.Error( szMessage );
294 if( psDBF->nCurrentRecord != iRecord )
302 psDBF->nRecordLength * (
SAOffset) iRecord + psDBF->nHeaderLength;
304 if( psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, SEEK_SET ) != 0 )
307 sprintf( szMessage,
"fseek(%ld) failed on DBF file.\n",
308 (
long) nRecordOffset );
309 psDBF->sHooks.Error( szMessage );
313 if( psDBF->sHooks.FRead( psDBF->pszCurrentRecord,
314 psDBF->nRecordLength, 1, psDBF->fp ) != 1 )
317 sprintf( szMessage,
"fread(%d) failed on DBF file.\n",
318 psDBF->nRecordLength );
319 psDBF->sHooks.Error( szMessage );
323 psDBF->nCurrentRecord = iRecord;
337 unsigned char abyFileHeader[32];
339 if( psDBF->bNoHeader )
344 psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
345 psDBF->sHooks.FRead( abyFileHeader, 32, 1, psDBF->fp );
347 abyFileHeader[4] = (
unsigned char) (psDBF->nRecords % 256);
348 abyFileHeader[5] = (
unsigned char) ((psDBF->nRecords/256) % 256);
349 abyFileHeader[6] = (
unsigned char) ((psDBF->nRecords/(256*256)) % 256);
350 abyFileHeader[7] = (
unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
352 psDBF->sHooks.FSeek( psDBF->fp, 0, 0 );
353 psDBF->sHooks.FWrite( abyFileHeader, 32, 1, psDBF->fp );
355 psDBF->sHooks.FFlush( psDBF->fp );
365 DBFOpen(
const char * pszFilename,
const char * pszAccess )
372 return DBFOpenLL( pszFilename, pszAccess, &sHooks );
387 unsigned char *pabyBuf;
388 int nFields, nHeadLen, iField, i;
389 char *pszBasename, *pszFullname;
395 if( strcmp(pszAccess,
"r") != 0 && strcmp(pszAccess,
"r+") != 0
396 && strcmp(pszAccess,
"rb") != 0 && strcmp(pszAccess,
"rb+") != 0
397 && strcmp(pszAccess,
"r+b") != 0 )
400 if( strcmp(pszAccess,
"r") == 0 )
403 if( strcmp(pszAccess,
"r+") == 0 )
410 pszBasename = (
char *)
malloc(strlen(pszFilename)+5);
411 strcpy( pszBasename, pszFilename );
412 for( i = strlen(pszBasename)-1;
413 i > 0 && pszBasename[i] !=
'.' && pszBasename[i] !=
'/' 414 && pszBasename[i] !=
'\\';
417 if( pszBasename[i] ==
'.' )
418 pszBasename[i] =
'\0';
420 pszFullname = (
char *)
malloc(strlen(pszBasename) + 5);
421 sprintf( pszFullname,
"%s.dbf", pszBasename );
423 psDBF = (DBFHandle) calloc( 1,
sizeof(DBFInfo) );
424 psDBF->fp = psHooks->
FOpen( pszFullname, pszAccess );
425 memcpy( &(psDBF->sHooks), psHooks,
sizeof(
SAHooks) );
427 if( psDBF->fp == NULL )
429 sprintf( pszFullname,
"%s.DBF", pszBasename );
430 psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
433 sprintf( pszFullname,
"%s.cpg", pszBasename );
434 pfCPG = psHooks->
FOpen( pszFullname,
"r" );
437 sprintf( pszFullname,
"%s.CPG", pszBasename );
438 pfCPG = psHooks->
FOpen( pszFullname,
"r" );
444 if( psDBF->fp == NULL )
447 if( pfCPG ) psHooks->
FClose( pfCPG );
451 psDBF->bNoHeader =
FALSE;
452 psDBF->nCurrentRecord = -1;
453 psDBF->bCurrentRecordModified =
FALSE;
458 pabyBuf = (
unsigned char *)
malloc(nBufSize);
459 if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 )
461 psDBF->sHooks.FClose( psDBF->fp );
462 if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
469 pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
471 psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
472 psDBF->nRecordLength = pabyBuf[10] + pabyBuf[11]*256;
473 psDBF->iLanguageDriver = pabyBuf[29];
477 psDBF->sHooks.FClose( psDBF->fp );
478 if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
484 psDBF->nFields = nFields = (nHeadLen - 32) / 32;
486 psDBF->pszCurrentRecord = (
char *)
malloc(psDBF->nRecordLength);
492 psDBF->pszCodePage = NULL;
496 memset( pabyBuf, 0, nBufSize);
497 psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
498 n = strcspn( (
char *) pabyBuf,
"\n\r" );
502 psDBF->pszCodePage = (
char *)
malloc(n + 1);
503 memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
505 psDBF->sHooks.FClose( pfCPG );
507 if( (psDBF->pszCodePage == NULL) && (psDBF->iLanguageDriver != 0) )
509 sprintf( (
char *) pabyBuf,
"LDID/%d", psDBF->iLanguageDriver );
510 psDBF->pszCodePage = (
char *)
malloc(strlen((
char*)pabyBuf) + 1);
511 strcpy( psDBF->pszCodePage, (
char *) pabyBuf );
518 pabyBuf = (
unsigned char *)
SfRealloc(pabyBuf,nHeadLen);
519 psDBF->pszHeader = (
char *) pabyBuf;
521 psDBF->sHooks.FSeek( psDBF->fp, 32, 0 );
522 if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
524 psDBF->sHooks.FClose( psDBF->fp );
526 free( psDBF->pszCurrentRecord );
531 psDBF->panFieldOffset = (
int *)
malloc(
sizeof(
int) * nFields);
532 psDBF->panFieldSize = (
int *)
malloc(
sizeof(
int) * nFields);
533 psDBF->panFieldDecimals = (
int *)
malloc(
sizeof(
int) * nFields);
534 psDBF->pachFieldType = (
char *)
malloc(
sizeof(
char) * nFields);
536 for( iField = 0; iField < nFields; iField++ )
538 unsigned char *pabyFInfo;
540 pabyFInfo = pabyBuf+iField*32;
542 if( pabyFInfo[11] ==
'N' || pabyFInfo[11] ==
'F' )
544 psDBF->panFieldSize[iField] = pabyFInfo[16];
545 psDBF->panFieldDecimals[iField] = pabyFInfo[17];
549 psDBF->panFieldSize[iField] = pabyFInfo[16];
550 psDBF->panFieldDecimals[iField] = 0;
562 psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
564 psDBF->panFieldOffset[iField] = 1;
566 psDBF->panFieldOffset[iField] =
567 psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
586 if( psDBF->bNoHeader )
595 if( psDBF->bUpdated )
601 psDBF->sHooks.FClose( psDBF->fp );
603 if( psDBF->panFieldOffset != NULL )
605 free( psDBF->panFieldOffset );
606 free( psDBF->panFieldSize );
607 free( psDBF->panFieldDecimals );
608 free( psDBF->pachFieldType );
611 if( psDBF->pszWorkField != NULL )
612 free( psDBF->pszWorkField );
614 free( psDBF->pszHeader );
615 free( psDBF->pszCurrentRecord );
616 free( psDBF->pszCodePage );
648 return DBFCreateLL( pszFilename, pszCodePage , &sHooks );
663 char *pszFullname, *pszBasename;
671 pszBasename = (
char *)
malloc(strlen(pszFilename)+5);
672 strcpy( pszBasename, pszFilename );
673 for( i = strlen(pszBasename)-1;
674 i > 0 && pszBasename[i] !=
'.' && pszBasename[i] !=
'/' 675 && pszBasename[i] !=
'\\';
678 if( pszBasename[i] ==
'.' )
679 pszBasename[i] =
'\0';
681 pszFullname = (
char *)
malloc(strlen(pszBasename) + 5);
682 sprintf( pszFullname,
"%s.dbf", pszBasename );
687 fp = psHooks->
FOpen( pszFullname,
"wb" );
695 psHooks->
FWrite( &chZero, 1, 1, fp );
698 fp = psHooks->
FOpen( pszFullname,
"rb+" );
707 sprintf( pszFullname,
"%s.cpg", pszBasename );
708 if( pszCodePage != NULL )
710 if( strncmp( pszCodePage,
"LDID/", 5 ) == 0 )
712 ldid = atoi( pszCodePage + 5 );
719 psHooks->
FWrite( (
char*) pszCodePage, strlen(pszCodePage), 1, fpCPG );
723 if( pszCodePage == NULL || ldid >= 0 )
725 psHooks->
Remove( pszFullname );
734 psDBF = (DBFHandle) calloc(1,
sizeof(DBFInfo));
736 memcpy( &(psDBF->sHooks), psHooks,
sizeof(
SAHooks) );
740 psDBF->nRecordLength = 1;
741 psDBF->nHeaderLength = 33;
743 psDBF->panFieldOffset = NULL;
744 psDBF->panFieldSize = NULL;
745 psDBF->panFieldDecimals = NULL;
746 psDBF->pachFieldType = NULL;
747 psDBF->pszHeader = NULL;
749 psDBF->nCurrentRecord = -1;
750 psDBF->bCurrentRecordModified =
FALSE;
751 psDBF->pszCurrentRecord = NULL;
753 psDBF->bNoHeader =
TRUE;
755 psDBF->iLanguageDriver = ldid > 0 ? ldid : 0;
756 psDBF->pszCodePage = NULL;
759 psDBF->pszCodePage = (
char * )
malloc( strlen(pszCodePage) + 1 );
760 strcpy( psDBF->pszCodePage, pszCodePage );
774 DBFFieldType eType,
int nWidth,
int nDecimals )
777 char chNativeType =
'C';
779 if( eType == FTLogical )
781 else if( eType == FTString )
783 else if( eType == FTDate )
821 char chType,
int nWidth,
int nDecimals )
826 int nOldRecordLength, nOldHeaderLength;
844 nOldRecordLength = psDBF->nRecordLength;
845 nOldHeaderLength = psDBF->nHeaderLength;
853 psDBF->panFieldOffset = (
int *)
854 SfRealloc( psDBF->panFieldOffset,
sizeof(
int) * psDBF->nFields );
856 psDBF->panFieldSize = (
int *)
857 SfRealloc( psDBF->panFieldSize,
sizeof(
int) * psDBF->nFields );
859 psDBF->panFieldDecimals = (
int *)
860 SfRealloc( psDBF->panFieldDecimals,
sizeof(
int) * psDBF->nFields );
862 psDBF->pachFieldType = (
char *)
863 SfRealloc( psDBF->pachFieldType,
sizeof(
char) * psDBF->nFields );
868 psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
869 psDBF->nRecordLength += nWidth;
870 psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
871 psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
872 psDBF->pachFieldType[psDBF->nFields-1] = chType;
877 psDBF->nHeaderLength += 32;
878 psDBF->bUpdated =
FALSE;
880 psDBF->pszHeader = (
char *)
SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
882 pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
884 for( i = 0; i < 32; i++ )
887 if( (
int) strlen(pszFieldName) < 10 )
888 strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
890 strncpy( pszFInfo, pszFieldName, 10);
892 pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
896 pszFInfo[16] = (
unsigned char) (nWidth % 256);
897 pszFInfo[17] = (
unsigned char) (nWidth / 256);
901 pszFInfo[16] = (
unsigned char) nWidth;
902 pszFInfo[17] = (
unsigned char) nDecimals;
908 psDBF->pszCurrentRecord = (
char *)
SfRealloc(psDBF->pszCurrentRecord,
909 psDBF->nRecordLength);
912 if( psDBF->bNoHeader )
913 return( psDBF->nFields - 1 );
920 pszRecord = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
924 for (i = psDBF->nRecords-1; i >= 0; --i)
926 nRecordOffset = nOldRecordLength * (
SAOffset) i + nOldHeaderLength;
929 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
930 psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
933 memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
935 nRecordOffset = psDBF->nRecordLength * (
SAOffset) i + psDBF->nHeaderLength;
938 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
939 psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
946 psDBF->bNoHeader =
TRUE;
949 psDBF->nCurrentRecord = -1;
950 psDBF->bCurrentRecordModified =
FALSE;
952 return( psDBF->nFields-1 );
965 unsigned char *pabyRec;
966 void *pReturnField = NULL;
971 if( hEntity < 0 || hEntity >= psDBF->nRecords )
974 if( iField < 0 || iField >= psDBF->nFields )
983 pabyRec = (
unsigned char *) psDBF->pszCurrentRecord;
988 if( psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength )
990 psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100;
991 if( psDBF->pszWorkField == NULL )
992 psDBF->pszWorkField = (
char *)
malloc(psDBF->nWorkFieldLength);
994 psDBF->pszWorkField = (
char *) realloc(psDBF->pszWorkField,
995 psDBF->nWorkFieldLength);
1001 strncpy( psDBF->pszWorkField,
1002 ((
const char *) pabyRec) + psDBF->panFieldOffset[iField],
1003 psDBF->panFieldSize[iField] );
1004 psDBF->pszWorkField[psDBF->panFieldSize[iField]] =
'\0';
1006 pReturnField = psDBF->pszWorkField;
1011 if( chReqType ==
'N' )
1013 psDBF->dfDoubleField = psDBF->sHooks.Atof(psDBF->pszWorkField);
1015 pReturnField = &(psDBF->dfDoubleField);
1021 #ifdef TRIM_DBF_WHITESPACE 1024 char *pchSrc, *pchDst;
1026 pchDst = pchSrc = psDBF->pszWorkField;
1027 while( *pchSrc ==
' ' )
1030 while( *pchSrc !=
'\0' )
1031 *(pchDst++) = *(pchSrc++);
1034 while( pchDst != psDBF->pszWorkField && *(--pchDst) ==
' ' )
1039 return( pReturnField );
1056 if( pdValue == NULL )
1059 return( (
int) *pdValue );
1076 if( pdValue == NULL )
1119 if( pszValue == NULL )
1131 if( pszValue[0] ==
'*' )
1134 for( i = 0; pszValue[i] !=
'\0'; i++ )
1136 if( pszValue[i] !=
' ' )
1143 if (pszValue[0] ==
'\0' ||
1144 strncmp(pszValue,
"00000000",8) == 0 ||
1145 strncmp(pszValue,
" ",8) == 0) {
1154 if (pszValue[0] ==
'\0' || pszValue[0] ==
'?') {
1162 return strlen(pszValue) == 0;
1178 const char *pszValue;
1182 if( pszValue == NULL )
1198 return( psDBF->nFields );
1211 return( psDBF->nRecords );
1222 int * pnWidth,
int * pnDecimals )
1225 if( iField < 0 || iField >= psDBF->nFields )
1226 return( FTInvalid );
1228 if( pnWidth != NULL )
1229 *pnWidth = psDBF->panFieldSize[iField];
1231 if( pnDecimals != NULL )
1232 *pnDecimals = psDBF->panFieldDecimals[iField];
1234 if( pszFieldName != NULL )
1238 strncpy( pszFieldName, (
char *) psDBF->pszHeader+iField*32, 11 );
1239 pszFieldName[11] =
'\0';
1240 for( i = 10; i > 0 && pszFieldName[i] ==
' '; i-- )
1241 pszFieldName[i] =
'\0';
1244 if ( psDBF->pachFieldType[iField] ==
'L' )
1247 else if ( psDBF->pachFieldType[iField] ==
'D' )
1250 else if( psDBF->pachFieldType[iField] ==
'N' 1251 || psDBF->pachFieldType[iField] ==
'F' )
1253 if( psDBF->panFieldDecimals[iField] > 0
1254 || psDBF->panFieldSize[iField] > 10 )
1257 return( FTInteger );
1275 int i, j, nRetResult =
TRUE;
1276 unsigned char *pabyRec;
1277 char szSField[400], szFormat[20];
1282 if( hEntity < 0 || hEntity > psDBF->nRecords )
1285 if( psDBF->bNoHeader )
1291 if( hEntity == psDBF->nRecords )
1297 for( i = 0; i < psDBF->nRecordLength; i++ )
1298 psDBF->pszCurrentRecord[i] =
' ';
1300 psDBF->nCurrentRecord = hEntity;
1310 pabyRec = (
unsigned char *) psDBF->pszCurrentRecord;
1312 psDBF->bCurrentRecordModified =
TRUE;
1313 psDBF->bUpdated =
TRUE;
1320 if( pValue == NULL )
1322 memset( (
char *) (pabyRec+psDBF->panFieldOffset[iField]),
1324 psDBF->panFieldSize[iField] );
1331 switch( psDBF->pachFieldType[iField] )
1336 if( psDBF->panFieldDecimals[iField] == 0 )
1338 int nWidth = psDBF->panFieldSize[iField];
1340 if( (
int)
sizeof(szSField)-2 < nWidth )
1341 nWidth =
sizeof(szSField)-2;
1343 sprintf( szFormat,
"%%%dd", nWidth );
1344 sprintf(szSField, szFormat, (
int) *((
double *) pValue) );
1345 if( (
int)strlen(szSField) > psDBF->panFieldSize[iField] )
1347 szSField[psDBF->panFieldSize[iField]] =
'\0';
1351 strncpy((
char *) (pabyRec+psDBF->panFieldOffset[iField]),
1352 szSField, strlen(szSField) );
1356 int nWidth = psDBF->panFieldSize[iField];
1358 if( (
int)
sizeof(szSField)-2 < nWidth )
1359 nWidth =
sizeof(szSField)-2;
1361 sprintf( szFormat,
"%%%d.%df",
1362 nWidth, psDBF->panFieldDecimals[iField] );
1363 sprintf(szSField, szFormat, *((
double *) pValue) );
1364 if( (
int) strlen(szSField) > psDBF->panFieldSize[iField] )
1366 szSField[psDBF->panFieldSize[iField]] =
'\0';
1369 strncpy((
char *) (pabyRec+psDBF->panFieldOffset[iField]),
1370 szSField, strlen(szSField) );
1375 if (psDBF->panFieldSize[iField] >= 1 &&
1376 (*(
char*)pValue ==
'F' || *(
char*)pValue ==
'T'))
1377 *(pabyRec+psDBF->panFieldOffset[iField]) = *(
char*)pValue;
1381 if( (
int) strlen((
char *) pValue) > psDBF->panFieldSize[iField] )
1383 j = psDBF->panFieldSize[iField];
1388 memset( pabyRec+psDBF->panFieldOffset[iField],
' ',
1389 psDBF->panFieldSize[iField] );
1390 j = strlen((
char *) pValue);
1393 strncpy((
char *) (pabyRec+psDBF->panFieldOffset[iField]),
1394 (
char *) pValue, j );
1398 return( nRetResult );
1415 unsigned char *pabyRec;
1420 if( hEntity < 0 || hEntity > psDBF->nRecords )
1423 if( psDBF->bNoHeader )
1429 if( hEntity == psDBF->nRecords )
1435 for( i = 0; i < psDBF->nRecordLength; i++ )
1436 psDBF->pszCurrentRecord[i] =
' ';
1438 psDBF->nCurrentRecord = hEntity;
1448 pabyRec = (
unsigned char *) psDBF->pszCurrentRecord;
1453 if( (
int)strlen((
char *) pValue) > psDBF->panFieldSize[iField] )
1454 j = psDBF->panFieldSize[iField];
1457 memset( pabyRec+psDBF->panFieldOffset[iField],
' ',
1458 psDBF->panFieldSize[iField] );
1459 j = strlen((
char *) pValue);
1462 strncpy((
char *) (pabyRec+psDBF->panFieldOffset[iField]),
1463 (
char *) pValue, j );
1465 psDBF->bCurrentRecordModified =
TRUE;
1466 psDBF->bUpdated =
TRUE;
1496 double dValue = nValue;
1509 const char * pszValue )
1553 unsigned char *pabyRec;
1558 if( hEntity < 0 || hEntity > psDBF->nRecords )
1561 if( psDBF->bNoHeader )
1567 if( hEntity == psDBF->nRecords )
1573 for( i = 0; i < psDBF->nRecordLength; i++ )
1574 psDBF->pszCurrentRecord[i] =
' ';
1576 psDBF->nCurrentRecord = hEntity;
1586 pabyRec = (
unsigned char *) psDBF->pszCurrentRecord;
1588 memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength );
1590 psDBF->bCurrentRecordModified =
TRUE;
1591 psDBF->bUpdated =
TRUE;
1607 if( hEntity < 0 || hEntity >= psDBF->nRecords )
1613 return (
const char *) psDBF->pszCurrentRecord;
1627 newDBF =
DBFCreateEx ( pszFilename, psDBF->pszCodePage );
1628 if ( newDBF == NULL )
return ( NULL );
1630 newDBF->nFields = psDBF->nFields;
1631 newDBF->nRecordLength = psDBF->nRecordLength;
1632 newDBF->nHeaderLength = psDBF->nHeaderLength;
1634 newDBF->pszHeader = (
char *)
malloc ( newDBF->nHeaderLength );
1635 memcpy ( newDBF->pszHeader, psDBF->pszHeader, newDBF->nHeaderLength );
1637 newDBF->panFieldOffset = (
int *)
malloc (
sizeof(
int) * psDBF->nFields );
1638 memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset,
sizeof(
int) * psDBF->nFields );
1639 newDBF->panFieldSize = (
int *)
malloc (
sizeof(
int) * psDBF->nFields );
1640 memcpy ( newDBF->panFieldSize, psDBF->panFieldSize,
sizeof(
int) * psDBF->nFields );
1641 newDBF->panFieldDecimals = (
int *)
malloc (
sizeof(
int) * psDBF->nFields );
1642 memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals,
sizeof(
int) * psDBF->nFields );
1643 newDBF->pachFieldType = (
char *)
malloc (
sizeof(
char) * psDBF->nFields );
1644 memcpy ( newDBF->pachFieldType, psDBF->pachFieldType,
sizeof(
char)*psDBF->nFields );
1646 newDBF->bNoHeader =
TRUE;
1647 newDBF->bUpdated =
TRUE;
1652 newDBF =
DBFOpen ( pszFilename,
"rb+" );
1672 if( iField >=0 && iField < psDBF->nFields )
1673 return psDBF->pachFieldType[iField];
1687 len = strlen (
string);
1690 if (isalpha(
string[i]) && islower(
string[i]))
1691 string[i] = (char) toupper ((
int)
string[i]);
1706 char name[12], name1[12], name2[12];
1709 strncpy(name1, pszFieldName,11);
1716 strncpy(name2,name,11);
1719 if(!strncmp(name1,name2,10))
1738 if( iShape < 0 || (psDBF->nRecords > 0 && iShape >= psDBF->nRecords) )
1744 if( psDBF->nRecords > 0 && !
DBFLoadRecord( psDBF, iShape ) )
1750 return psDBF->pszCurrentRecord[0] ==
'*';
1766 if( iShape < 0 || iShape >= psDBF->nRecords )
1784 if( psDBF->pszCurrentRecord[0] != chNewFlag )
1786 psDBF->bCurrentRecordModified =
TRUE;
1787 psDBF->bUpdated =
TRUE;
1788 psDBF->pszCurrentRecord[0] = chNewFlag;
1803 return psDBF->pszCodePage;
1815 int nOldRecordLength, nOldHeaderLength;
1816 int nDeletedFieldOffset, nDeletedFieldSize;
1821 if (iField < 0 || iField >= psDBF->nFields)
1829 nOldRecordLength = psDBF->nRecordLength;
1830 nOldHeaderLength = psDBF->nHeaderLength;
1831 nDeletedFieldOffset = psDBF->panFieldOffset[iField];
1832 nDeletedFieldSize = psDBF->panFieldSize[iField];
1835 for (i = iField + 1; i < psDBF->nFields; i++)
1837 psDBF->panFieldOffset[i-1] = psDBF->panFieldOffset[i] - nDeletedFieldSize;
1838 psDBF->panFieldSize[i-1] = psDBF->panFieldSize[i];
1839 psDBF->panFieldDecimals[i-1] = psDBF->panFieldDecimals[i];
1840 psDBF->pachFieldType[i-1] = psDBF->pachFieldType[i];
1846 psDBF->panFieldOffset = (
int *)
1847 SfRealloc( psDBF->panFieldOffset,
sizeof(
int) * psDBF->nFields );
1849 psDBF->panFieldSize = (
int *)
1850 SfRealloc( psDBF->panFieldSize,
sizeof(
int) * psDBF->nFields );
1852 psDBF->panFieldDecimals = (
int *)
1853 SfRealloc( psDBF->panFieldDecimals,
sizeof(
int) * psDBF->nFields );
1855 psDBF->pachFieldType = (
char *)
1856 SfRealloc( psDBF->pachFieldType,
sizeof(
char) * psDBF->nFields );
1859 psDBF->nHeaderLength -= 32;
1860 psDBF->nRecordLength -= nDeletedFieldSize;
1863 memmove(psDBF->pszHeader + iField*32,
1864 psDBF->pszHeader + (iField+1)*32,
1865 sizeof(
char) * (psDBF->nFields - iField)*32);
1867 psDBF->pszHeader = (
char *)
SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
1870 psDBF->pszCurrentRecord = (
char *)
SfRealloc(psDBF->pszCurrentRecord,
1871 psDBF->nRecordLength);
1874 if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
1878 psDBF->bNoHeader =
TRUE;
1882 pszRecord = (
char *)
malloc(
sizeof(
char) * nOldRecordLength);
1885 for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
1888 nOldRecordLength * (
SAOffset) iRecord + nOldHeaderLength;
1891 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
1892 psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
1895 psDBF->nRecordLength * (
SAOffset) iRecord + psDBF->nHeaderLength;
1898 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
1899 psDBF->sHooks.FWrite( pszRecord, nDeletedFieldOffset, 1, psDBF->fp );
1900 psDBF->sHooks.FWrite( pszRecord + nDeletedFieldOffset + nDeletedFieldSize,
1901 nOldRecordLength - nDeletedFieldOffset - nDeletedFieldSize,
1911 psDBF->nCurrentRecord = -1;
1912 psDBF->bCurrentRecordModified =
FALSE;
1932 int *panFieldOffsetNew;
1933 int *panFieldSizeNew;
1934 int *panFieldDecimalsNew;
1935 char *pachFieldTypeNew;
1940 if ( psDBF->nFields == 0 )
1947 panFieldOffsetNew = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1948 panFieldSizeNew = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1949 panFieldDecimalsNew = (
int *)
malloc(
sizeof(
int) * psDBF->nFields);
1950 pachFieldTypeNew = (
char *)
malloc(
sizeof(
char) * psDBF->nFields);
1951 pszHeaderNew = (
char*)
malloc(
sizeof(
char) * 32 * psDBF->nFields);
1954 for(i=0; i < psDBF->nFields; i++)
1956 panFieldSizeNew[i] = psDBF->panFieldSize[panMap[i]];
1957 panFieldDecimalsNew[i] = psDBF->panFieldDecimals[panMap[i]];
1958 pachFieldTypeNew[i] = psDBF->pachFieldType[panMap[i]];
1959 memcpy(pszHeaderNew + i * 32,
1960 psDBF->pszHeader + panMap[i] * 32, 32);
1962 panFieldOffsetNew[0] = 1;
1963 for(i=1; i < psDBF->nFields; i++)
1965 panFieldOffsetNew[i] = panFieldOffsetNew[i - 1] + panFieldSizeNew[i - 1];
1968 free(psDBF->pszHeader);
1969 psDBF->pszHeader = pszHeaderNew;
1972 if ( !(psDBF->bNoHeader && psDBF->nRecords == 0) )
1975 psDBF->bNoHeader =
TRUE;
1979 pszRecord = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
1980 pszRecordNew = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
1983 for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
1986 psDBF->nRecordLength * (
SAOffset) iRecord + psDBF->nHeaderLength;
1989 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
1990 psDBF->sHooks.FRead( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
1992 pszRecordNew[0] = pszRecord[0];
1994 for(i=0; i < psDBF->nFields; i++)
1996 memcpy(pszRecordNew + panFieldOffsetNew[i],
1997 pszRecord + psDBF->panFieldOffset[panMap[i]],
1998 psDBF->panFieldSize[panMap[i]]);
2002 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
2003 psDBF->sHooks.FWrite( pszRecordNew, psDBF->nRecordLength, 1, psDBF->fp );
2011 free(psDBF->panFieldOffset);
2012 free(psDBF->panFieldSize);
2013 free(psDBF->panFieldDecimals);
2014 free(psDBF->pachFieldType);
2016 psDBF->panFieldOffset = panFieldOffsetNew;
2017 psDBF->panFieldSize = panFieldSizeNew;
2018 psDBF->panFieldDecimals =panFieldDecimalsNew;
2019 psDBF->pachFieldType = pachFieldTypeNew;
2021 psDBF->nCurrentRecord = -1;
2022 psDBF->bCurrentRecordModified =
FALSE;
2036 char chType,
int nWidth,
int nDecimals )
2042 int nOldRecordLength;
2049 if (iField < 0 || iField >= psDBF->nFields)
2058 chOldType = psDBF->pachFieldType[iField];
2059 nOffset = psDBF->panFieldOffset[iField];
2060 nOldWidth = psDBF->panFieldSize[iField];
2061 nOldRecordLength = psDBF->nRecordLength;
2075 psDBF->panFieldSize[iField] = nWidth;
2076 psDBF->panFieldDecimals[iField] = nDecimals;
2077 psDBF->pachFieldType[iField] = chType;
2082 pszFInfo = psDBF->pszHeader + 32 * iField;
2084 for( i = 0; i < 32; i++ )
2087 if( (
int) strlen(pszFieldName) < 10 )
2088 strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
2090 strncpy( pszFInfo, pszFieldName, 10);
2092 pszFInfo[11] = psDBF->pachFieldType[iField];
2096 pszFInfo[16] = (
unsigned char) (nWidth % 256);
2097 pszFInfo[17] = (
unsigned char) (nWidth / 256);
2101 pszFInfo[16] = (
unsigned char) nWidth;
2102 pszFInfo[17] = (
unsigned char) nDecimals;
2108 if (nWidth != nOldWidth)
2110 for (i = iField + 1; i < psDBF->nFields; i++)
2111 psDBF->panFieldOffset[i] += nWidth - nOldWidth;
2112 psDBF->nRecordLength += nWidth - nOldWidth;
2114 psDBF->pszCurrentRecord = (
char *)
SfRealloc(psDBF->pszCurrentRecord,
2115 psDBF->nRecordLength);
2119 if ( psDBF->bNoHeader && psDBF->nRecords == 0 )
2123 psDBF->bNoHeader =
TRUE;
2126 if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType))
2128 char* pszRecord = (
char *)
malloc(
sizeof(
char) * nOldRecordLength);
2129 char* pszOldField = (
char *)
malloc(
sizeof(
char) * (nOldWidth + 1));
2131 pszOldField[nOldWidth] = 0;
2134 for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
2137 nOldRecordLength * (
SAOffset) iRecord + psDBF->nHeaderLength;
2140 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
2141 psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
2143 memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
2146 if (nWidth != nOldWidth)
2148 if ((chOldType ==
'N' || chOldType ==
'F') && pszOldField[0] ==
' ')
2151 memmove( pszRecord + nOffset,
2152 pszRecord + nOffset + nOldWidth - nWidth,
2155 if (nOffset + nOldWidth < nOldRecordLength)
2157 memmove( pszRecord + nOffset + nWidth,
2158 pszRecord + nOffset + nOldWidth,
2159 nOldRecordLength - (nOffset + nOldWidth));
2166 memset( pszRecord + nOffset, chFieldFill, nWidth);
2170 psDBF->nRecordLength * (
SAOffset) iRecord + psDBF->nHeaderLength;
2173 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
2174 psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
2180 else if (nWidth > nOldWidth)
2182 char* pszRecord = (
char *)
malloc(
sizeof(
char) * psDBF->nRecordLength);
2183 char* pszOldField = (
char *)
malloc(
sizeof(
char) * (nOldWidth + 1));
2185 pszOldField[nOldWidth] = 0;
2188 for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
2191 nOldRecordLength * (
SAOffset) iRecord + psDBF->nHeaderLength;
2194 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
2195 psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
2197 memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
2200 if (nOffset + nOldWidth < nOldRecordLength)
2202 memmove( pszRecord + nOffset + nWidth,
2203 pszRecord + nOffset + nOldWidth,
2204 nOldRecordLength - (nOffset + nOldWidth));
2210 memset( pszRecord + nOffset, chFieldFill, nWidth);
2214 if ((chOldType ==
'N' || chOldType ==
'F'))
2217 memmove( pszRecord + nOffset + nWidth - nOldWidth,
2218 pszRecord + nOffset, nOldWidth );
2219 memset( pszRecord + nOffset,
' ', nWidth - nOldWidth );
2224 memset(pszRecord + nOffset + nOldWidth,
' ', nWidth - nOldWidth);
2229 psDBF->nRecordLength * (
SAOffset) iRecord + psDBF->nHeaderLength;
2232 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
2233 psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
2240 psDBF->nCurrentRecord = -1;
2241 psDBF->bCurrentRecordModified =
FALSE;
DBFHandle SHPAPI_CALL DBFCreate(const char *pszFilename)
int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
int SHPAPI_CALL DBFReorderFields(DBFHandle psDBF, int *panMap)
int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity, void *pRawTuple)
const char SHPAPI_CALL1 * DBFReadLogicalAttribute(DBFHandle psDBF, int iRecord, int iField){ return((const char *) DBFReadAttribute(psDBF, iRecord, iField, 'L')
int SHPAPI_CALL DBFReadIntegerAttribute(DBFHandle psDBF, int iRecord, int iField)
int SHPAPI_CALL DBFWriteStringAttribute(DBFHandle psDBF, int iRecord, int iField, const char *pszValue)
const char SHPAPI_CALL1 * DBFReadStringAttribute(DBFHandle psDBF, int iRecord, int iField){ return((const char *) DBFReadAttribute(psDBF, iRecord, iField, 'C')
static void * SfRealloc(void *pMem, int nNewSize)
int SHPAPI_CALL DBFWriteDoubleAttribute(DBFHandle psDBF, int iRecord, int iField, double dValue)
int SHPAPI_CALL DBFAddNativeFieldType(DBFHandle psDBF, const char *pszFieldName, char chType, int nWidth, int nDecimals)
const char SHPAPI_CALL1 * DBFReadTuple(DBFHandle psDBF, int hEntity){ if(hEntity< 0||hEntity >=psDBF->nRecords) return(NULL
int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, void *pValue)
DBFHandle SHPAPI_CALL DBFCreateEx(const char *pszFilename, const char *pszCodePage)
static int DBFLoadRecord(DBFHandle psDBF, int iRecord)
int(* FClose)(SAFile file)
#define SHP_CVSID(string)
int SHPAPI_CALL DBFAlterFieldDefn(DBFHandle psDBF, int iField, const char *pszFieldName, char chType, int nWidth, int nDecimals)
int SHPAPI_CALL DBFGetRecordCount(DBFHandle psDBF)
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
static int DBFIsValueNULL(char chType, const char *pszValue)
static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, void *pValue)
int SHPAPI_CALL DBFMarkRecordDeleted(DBFHandle psDBF, int iShape, int bIsDeleted)
int SHPAPI_CALL DBFWriteNULLAttribute(DBFHandle psDBF, int iRecord, int iField)
DBFFieldType SHPAPI_CALL DBFGetFieldInfo(DBFHandle psDBF, int iField, char *pszFieldName, int *pnWidth, int *pnDecimals)
int SHPAPI_CALL DBFGetFieldCount(DBFHandle psDBF)
DBFHandle SHPAPI_CALL DBFOpen(const char *pszFilename, const char *pszAccess)
static void str_to_upper(char *string)
const char SHPAPI_CALL1 * DBFGetCodePage(DBFHandle psDBF){ if(psDBF==NULL) return NULL;return psDBF->pszCodePage;}int SHPAPI_CALLDBFDeleteField(DBFHandle psDBF, int iField
static void DBFWriteHeader(DBFHandle psDBF)
DBFHandle SHPAPI_CALL DBFOpenLL(const char *pszFilename, const char *pszAccess, SAHooks *psHooks)
int SHPAPI_CALL DBFWriteLogicalAttribute(DBFHandle psDBF, int iRecord, int iField, const char lValue)
static int DBFFlushRecord(DBFHandle psDBF)
double SHPAPI_CALL DBFReadDoubleAttribute(DBFHandle psDBF, int iRecord, int iField)
int(* Remove)(const char *filename)
int SHPAPI_CALL DBFAddField(DBFHandle psDBF, const char *pszFieldName, DBFFieldType eType, int nWidth, int nDecimals)
DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char *pszFilename)
static void * DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, char chReqType)
DBFHandle SHPAPI_CALL DBFCreateLL(const char *pszFilename, const char *pszCodePage, SAHooks *psHooks)
int SHPAPI_CALL DBFWriteIntegerAttribute(DBFHandle psDBF, int iRecord, int iField, int nValue)
void SHPAPI_CALL DBFClose(DBFHandle psDBF)
static char DBFGetNullCharacter(char chType)
int SHPAPI_CALL DBFIsAttributeNULL(DBFHandle psDBF, int iRecord, int iField)
char SHPAPI_CALL DBFGetNativeFieldType(DBFHandle psDBF, int iField)
SAFile(* FOpen)(const char *filename, const char *access)
int SHPAPI_CALL DBFDeleteField(DBFHandle hDBF, int iField)
void SHPAPI_CALL DBFUpdateHeader(DBFHandle psDBF)
void SASetupDefaultHooks(SAHooks *psHooks)
int SHPAPI_CALL DBFIsRecordDeleted(DBFHandle psDBF, int iShape)