PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ DBFOpenLL()

DBFHandle SHPAPI_CALL DBFOpenLL ( const char *  pszFilename,
const char *  pszAccess,
SAHooks psHooks 
)

Definition at line 388 of file dbfopen.c.

390{
391 DBFHandle psDBF;
392 SAFile pfCPG;
393 unsigned char *pabyBuf;
394 int nFields, nHeadLen, iField;
395 char *pszFullname;
396 int nBufSize = 500;
397 int nLenWithoutExtension;
398
399/* -------------------------------------------------------------------- */
400/* We only allow the access strings "rb" and "r+". */
401/* -------------------------------------------------------------------- */
402 if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0
403 && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0
404 && strcmp(pszAccess,"r+b") != 0 )
405 return SHPLIB_NULLPTR;
406
407 if( strcmp(pszAccess,"r") == 0 )
408 pszAccess = "rb";
409
410 if( strcmp(pszAccess,"r+") == 0 )
411 pszAccess = "rb+";
412
413/* -------------------------------------------------------------------- */
414/* Compute the base (layer) name. If there is any extension */
415/* on the passed in filename we will strip it off. */
416/* -------------------------------------------------------------------- */
417 nLenWithoutExtension = DBFGetLenWithoutExtension(pszFilename);
418 pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5));
419 if( pszFullname == SHPLIB_NULLPTR )
420 return SHPLIB_NULLPTR;
421 memcpy(pszFullname, pszFilename, nLenWithoutExtension);
422 memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5);
423
424 psDBF = STATIC_CAST(DBFHandle, calloc( 1, sizeof(DBFInfo) ));
425 if( psDBF == SHPLIB_NULLPTR )
426 {
427 free( pszFullname );
428 return SHPLIB_NULLPTR;
429 }
430 psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
431 memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
432
433 if( psDBF->fp == SHPLIB_NULLPTR )
434 {
435 memcpy(pszFullname + nLenWithoutExtension, ".DBF", 5);
436 psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
437 }
438
439 memcpy(pszFullname + nLenWithoutExtension, ".cpg", 5);
440 pfCPG = psHooks->FOpen( pszFullname, "r" );
441 if( pfCPG == SHPLIB_NULLPTR )
442 {
443 memcpy(pszFullname + nLenWithoutExtension, ".CPG", 5);
444 pfCPG = psHooks->FOpen( pszFullname, "r" );
445 }
446
447 free( pszFullname );
448
449 if( psDBF->fp == SHPLIB_NULLPTR )
450 {
451 free( psDBF );
452 if( pfCPG ) psHooks->FClose( pfCPG );
453 return SHPLIB_NULLPTR;
454 }
455
456 psDBF->bNoHeader = FALSE;
457 psDBF->nCurrentRecord = -1;
459
460/* -------------------------------------------------------------------- */
461/* Read Table Header info */
462/* -------------------------------------------------------------------- */
463 pabyBuf = STATIC_CAST(unsigned char *, malloc(nBufSize));
464 if( psDBF->sHooks.FRead( pabyBuf, XBASE_FILEHDR_SZ, 1, psDBF->fp ) != 1 )
465 {
466 psDBF->sHooks.FClose( psDBF->fp );
467 if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
468 free( pabyBuf );
469 free( psDBF );
470 return SHPLIB_NULLPTR;
471 }
472
473 DBFSetLastModifiedDate(psDBF, pabyBuf[1], pabyBuf[2], pabyBuf[3]);
474
475 psDBF->nRecords =
476 pabyBuf[4]|(pabyBuf[5]<<8)|(pabyBuf[6]<<16)|((pabyBuf[7]&0x7f)<<24);
477
478 psDBF->nHeaderLength = nHeadLen = pabyBuf[8]|(pabyBuf[9]<<8);
479 psDBF->nRecordLength = pabyBuf[10]|(pabyBuf[11]<<8);
480 psDBF->iLanguageDriver = pabyBuf[29];
481
482 if (psDBF->nRecordLength == 0 || nHeadLen < XBASE_FILEHDR_SZ)
483 {
484 psDBF->sHooks.FClose( psDBF->fp );
485 if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
486 free( pabyBuf );
487 free( psDBF );
488 return SHPLIB_NULLPTR;
489 }
490
491 psDBF->nFields = nFields = (nHeadLen - XBASE_FILEHDR_SZ) / XBASE_FLDHDR_SZ;
492
493 /* coverity[tainted_data] */
494 psDBF->pszCurrentRecord = STATIC_CAST(char *, malloc(psDBF->nRecordLength));
495
496/* -------------------------------------------------------------------- */
497/* Figure out the code page from the LDID and CPG */
498/* -------------------------------------------------------------------- */
499
501 if( pfCPG )
502 {
503 size_t n;
504 memset( pabyBuf, 0, nBufSize);
505 psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
506 n = strcspn( REINTERPRET_CAST(char *, pabyBuf), "\n\r" );
507 if( n > 0 )
508 {
509 pabyBuf[n] = '\0';
510 psDBF->pszCodePage = STATIC_CAST(char *, malloc(n + 1));
511 memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
512 }
513 psDBF->sHooks.FClose( pfCPG );
514 }
515 if( psDBF->pszCodePage == SHPLIB_NULLPTR && pabyBuf[29] != 0 )
516 {
517 snprintf( REINTERPRET_CAST(char *, pabyBuf), nBufSize, "LDID/%d", psDBF->iLanguageDriver );
518 psDBF->pszCodePage = STATIC_CAST(char *, malloc(strlen(REINTERPRET_CAST(char*, pabyBuf)) + 1));
519 strcpy( psDBF->pszCodePage, REINTERPRET_CAST(char *, pabyBuf) );
520 }
521
522/* -------------------------------------------------------------------- */
523/* Read in Field Definitions */
524/* -------------------------------------------------------------------- */
525
526 pabyBuf = STATIC_CAST(unsigned char *, SfRealloc(pabyBuf,nHeadLen));
527 psDBF->pszHeader = REINTERPRET_CAST(char *, pabyBuf);
528
529 psDBF->sHooks.FSeek( psDBF->fp, XBASE_FILEHDR_SZ, 0 );
530 if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-XBASE_FILEHDR_SZ, 1,
531 psDBF->fp ) != 1 )
532 {
533 psDBF->sHooks.FClose( psDBF->fp );
534 free( pabyBuf );
535 free( psDBF->pszCurrentRecord );
536 free( psDBF->pszCodePage );
537 free( psDBF );
538 return SHPLIB_NULLPTR;
539 }
540
541 psDBF->panFieldOffset = STATIC_CAST(int *, malloc(sizeof(int) * nFields));
542 psDBF->panFieldSize = STATIC_CAST(int *, malloc(sizeof(int) * nFields));
543 psDBF->panFieldDecimals = STATIC_CAST(int *, malloc(sizeof(int) * nFields));
544 psDBF->pachFieldType = STATIC_CAST(char *, malloc(sizeof(char) * nFields));
545
546 for( iField = 0; iField < nFields; iField++ )
547 {
548 unsigned char *pabyFInfo;
549
550 pabyFInfo = pabyBuf+iField*XBASE_FLDHDR_SZ;
551 if( pabyFInfo[0] == HEADER_RECORD_TERMINATOR )
552 {
553 psDBF->nFields = iField;
554 break;
555 }
556
557 if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
558 {
559 psDBF->panFieldSize[iField] = pabyFInfo[16];
560 psDBF->panFieldDecimals[iField] = pabyFInfo[17];
561 }
562 else
563 {
564 psDBF->panFieldSize[iField] = pabyFInfo[16];
565 psDBF->panFieldDecimals[iField] = 0;
566
567/*
568** The following seemed to be used sometimes to handle files with long
569** string fields, but in other cases (such as bug 1202) the decimals field
570** just seems to indicate some sort of preferred formatting, not very
571** wide fields. So I have disabled this code. FrankW.
572 psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
573 psDBF->panFieldDecimals[iField] = 0;
574*/
575 }
576
577 psDBF->pachFieldType[iField] = STATIC_CAST(char, pabyFInfo[11]);
578 if( iField == 0 )
579 psDBF->panFieldOffset[iField] = 1;
580 else
581 psDBF->panFieldOffset[iField] =
582 psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
583 }
584
585 /* Check that the total width of fields does not exceed the record width */
586 if( psDBF->nFields > 0 &&
587 psDBF->panFieldOffset[psDBF->nFields-1] +
588 psDBF->panFieldSize[psDBF->nFields-1] > psDBF->nRecordLength )
589 {
590 DBFClose( psDBF );
591 return SHPLIB_NULLPTR;
592 }
593
595
597
598 return( psDBF );
599}
static void * SfRealloc(void *pMem, int nNewSize)
Definition dbfopen.c:109
static int DBFGetLenWithoutExtension(const char *pszBasename)
Definition dbfopen.c:365
#define STATIC_CAST(type, x)
Definition dbfopen.c:96
#define HEADER_RECORD_TERMINATOR
Definition dbfopen.c:79
#define REINTERPRET_CAST(type, x)
Definition dbfopen.c:97
void SHPAPI_CALL DBFClose(DBFHandle psDBF)
Definition dbfopen.c:606
#define XBASE_FILEHDR_SZ
Definition dbfopen.c:77
#define TRUE
Definition dbfopen.c:73
#define FALSE
Definition dbfopen.c:72
void SHPAPI_CALL DBFSetLastModifiedDate(DBFHandle psDBF, int nYYSince1900, int nMM, int nDD)
Definition dbfopen.c:337
void SHPAPI_CALL DBFSetWriteEndOfFileChar(DBFHandle psDBF, int bWriteFlag)
Definition dbfopen.c:2317
#define SHPLIB_NULLPTR
Definition dbfopen.c:99
void * malloc(YYSIZE_T)
void free(void *)
#define XBASE_FLDHDR_SZ
Definition shapefil.h:648
int * SAFile
Definition shapefil.h:283
int nRecordLength
Definition shapefil.h:596
int * panFieldOffset
Definition shapefil.h:601
int * panFieldDecimals
Definition shapefil.h:603
char * pszCodePage
Definition shapefil.h:625
int nFields
Definition shapefil.h:600
int nHeaderLength
Definition shapefil.h:597
int * panFieldSize
Definition shapefil.h:602
char * pszCurrentRecord
Definition shapefil.h:610
int bCurrentRecordModified
Definition shapefil.h:609
char * pszHeader
Definition shapefil.h:606
SAFile fp
Definition shapefil.h:592
char * pachFieldType
Definition shapefil.h:604
int bRequireNextWriteSeek
Definition shapefil.h:633
SAHooks sHooks
Definition shapefil.h:590
int bNoHeader
Definition shapefil.h:615
int iLanguageDriver
Definition shapefil.h:624
int nRecords
Definition shapefil.h:594
int nCurrentRecord
Definition shapefil.h:608
SAFile(* FOpen)(const char *filename, const char *access)
Definition shapefil.h:290
int(* FClose)(SAFile file)
Definition shapefil.h:296
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition shapefil.h:291
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
Definition shapefil.h:293

References DBFInfo::bCurrentRecordModified, DBFInfo::bNoHeader, DBFInfo::bRequireNextWriteSeek, DBFClose(), DBFGetLenWithoutExtension(), DBFSetLastModifiedDate(), DBFSetWriteEndOfFileChar(), FALSE, SAHooks::FClose, SAHooks::FOpen, DBFInfo::fp, SAHooks::FRead, free(), SAHooks::FSeek, HEADER_RECORD_TERMINATOR, DBFInfo::iLanguageDriver, malloc(), DBFInfo::nCurrentRecord, DBFInfo::nFields, DBFInfo::nHeaderLength, DBFInfo::nRecordLength, DBFInfo::nRecords, DBFInfo::pachFieldType, DBFInfo::panFieldDecimals, DBFInfo::panFieldOffset, DBFInfo::panFieldSize, DBFInfo::pszCodePage, DBFInfo::pszCurrentRecord, DBFInfo::pszHeader, REINTERPRET_CAST, SfRealloc(), DBFInfo::sHooks, SHPLIB_NULLPTR, STATIC_CAST, TRUE, XBASE_FILEHDR_SZ, and XBASE_FLDHDR_SZ.

Referenced by DBFOpen().

Here is the call graph for this function:
Here is the caller graph for this function: