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];
static void * SfRealloc(void *pMem, int nNewSize)
SAFile(* FOpen)(const char *filename, const char *access)
int(* FClose)(SAFile file)