PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ DBFOpenLL()

DBFHandle SHPAPI_CALL DBFOpenLL ( const char *  pszDBFFile,
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  memcpy(pszFullname, pszFilename, nLenWithoutExtension);
420  memcpy(pszFullname + nLenWithoutExtension, ".dbf", 5);
421 
422  psDBF = STATIC_CAST(DBFHandle, calloc( 1, sizeof(DBFInfo) ));
423  psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
424  memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
425 
426  if( psDBF->fp == SHPLIB_NULLPTR )
427  {
428  memcpy(pszFullname + nLenWithoutExtension, ".DBF", 5);
429  psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
430  }
431 
432  memcpy(pszFullname + nLenWithoutExtension, ".cpg", 5);
433  pfCPG = psHooks->FOpen( pszFullname, "r" );
434  if( pfCPG == SHPLIB_NULLPTR )
435  {
436  memcpy(pszFullname + nLenWithoutExtension, ".CPG", 5);
437  pfCPG = psHooks->FOpen( pszFullname, "r" );
438  }
439 
440  free( pszFullname );
441 
442  if( psDBF->fp == SHPLIB_NULLPTR )
443  {
444  free( psDBF );
445  if( pfCPG ) psHooks->FClose( pfCPG );
446  return SHPLIB_NULLPTR;
447  }
448 
449  psDBF->bNoHeader = FALSE;
450  psDBF->nCurrentRecord = -1;
451  psDBF->bCurrentRecordModified = FALSE;
452 
453 /* -------------------------------------------------------------------- */
454 /* Read Table Header info */
455 /* -------------------------------------------------------------------- */
456  pabyBuf = STATIC_CAST(unsigned char *, malloc(nBufSize));
457  if( psDBF->sHooks.FRead( pabyBuf, XBASE_FILEHDR_SZ, 1, psDBF->fp ) != 1 )
458  {
459  psDBF->sHooks.FClose( psDBF->fp );
460  if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
461  free( pabyBuf );
462  free( psDBF );
463  return SHPLIB_NULLPTR;
464  }
465 
466  DBFSetLastModifiedDate(psDBF, pabyBuf[1], pabyBuf[2], pabyBuf[3]);
467 
468  psDBF->nRecords =
469  pabyBuf[4]|(pabyBuf[5]<<8)|(pabyBuf[6]<<16)|((pabyBuf[7]&0x7f)<<24);
470 
471  psDBF->nHeaderLength = nHeadLen = pabyBuf[8]|(pabyBuf[9]<<8);
472  psDBF->nRecordLength = pabyBuf[10]|(pabyBuf[11]<<8);
473  psDBF->iLanguageDriver = pabyBuf[29];
474 
475  if (psDBF->nRecordLength == 0 || nHeadLen < XBASE_FILEHDR_SZ)
476  {
477  psDBF->sHooks.FClose( psDBF->fp );
478  if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
479  free( pabyBuf );
480  free( psDBF );
481  return SHPLIB_NULLPTR;
482  }
483 
484  psDBF->nFields = nFields = (nHeadLen - XBASE_FILEHDR_SZ) / XBASE_FLDHDR_SZ;
485 
486  /* coverity[tainted_data] */
487  psDBF->pszCurrentRecord = STATIC_CAST(char *, malloc(psDBF->nRecordLength));
488 
489 /* -------------------------------------------------------------------- */
490 /* Figure out the code page from the LDID and CPG */
491 /* -------------------------------------------------------------------- */
492 
493  psDBF->pszCodePage = SHPLIB_NULLPTR;
494  if( pfCPG )
495  {
496  size_t n;
497  memset( pabyBuf, 0, nBufSize);
498  psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
499  n = strcspn( REINTERPRET_CAST(char *, pabyBuf), "\n\r" );
500  if( n > 0 )
501  {
502  pabyBuf[n] = '\0';
503  psDBF->pszCodePage = STATIC_CAST(char *, malloc(n + 1));
504  memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
505  }
506  psDBF->sHooks.FClose( pfCPG );
507  }
508  if( psDBF->pszCodePage == SHPLIB_NULLPTR && pabyBuf[29] != 0 )
509  {
510  snprintf( REINTERPRET_CAST(char *, pabyBuf), nBufSize, "LDID/%d", psDBF->iLanguageDriver );
511  psDBF->pszCodePage = STATIC_CAST(char *, malloc(strlen(REINTERPRET_CAST(char*, pabyBuf)) + 1));
512  strcpy( psDBF->pszCodePage, REINTERPRET_CAST(char *, pabyBuf) );
513  }
514 
515 /* -------------------------------------------------------------------- */
516 /* Read in Field Definitions */
517 /* -------------------------------------------------------------------- */
518 
519  pabyBuf = STATIC_CAST(unsigned char *, SfRealloc(pabyBuf,nHeadLen));
520  psDBF->pszHeader = REINTERPRET_CAST(char *, pabyBuf);
521 
522  psDBF->sHooks.FSeek( psDBF->fp, XBASE_FILEHDR_SZ, 0 );
523  if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-XBASE_FILEHDR_SZ, 1,
524  psDBF->fp ) != 1 )
525  {
526  psDBF->sHooks.FClose( psDBF->fp );
527  free( pabyBuf );
528  free( psDBF->pszCurrentRecord );
529  free( psDBF->pszCodePage );
530  free( psDBF );
531  return SHPLIB_NULLPTR;
532  }
533 
534  psDBF->panFieldOffset = STATIC_CAST(int *, malloc(sizeof(int) * nFields));
535  psDBF->panFieldSize = STATIC_CAST(int *, malloc(sizeof(int) * nFields));
536  psDBF->panFieldDecimals = STATIC_CAST(int *, malloc(sizeof(int) * nFields));
537  psDBF->pachFieldType = STATIC_CAST(char *, malloc(sizeof(char) * nFields));
538 
539  for( iField = 0; iField < nFields; iField++ )
540  {
541  unsigned char *pabyFInfo;
542 
543  pabyFInfo = pabyBuf+iField*XBASE_FLDHDR_SZ;
544  if( pabyFInfo[0] == HEADER_RECORD_TERMINATOR )
545  {
546  psDBF->nFields = iField;
547  break;
548  }
549 
550  if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
551  {
552  psDBF->panFieldSize[iField] = pabyFInfo[16];
553  psDBF->panFieldDecimals[iField] = pabyFInfo[17];
554  }
555  else
556  {
557  psDBF->panFieldSize[iField] = pabyFInfo[16];
558  psDBF->panFieldDecimals[iField] = 0;
559 
560 /*
561 ** The following seemed to be used sometimes to handle files with long
562 ** string fields, but in other cases (such as bug 1202) the decimals field
563 ** just seems to indicate some sort of preferred formatting, not very
564 ** wide fields. So I have disabled this code. FrankW.
565  psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
566  psDBF->panFieldDecimals[iField] = 0;
567 */
568  }
569 
570  psDBF->pachFieldType[iField] = STATIC_CAST(char, pabyFInfo[11]);
571  if( iField == 0 )
572  psDBF->panFieldOffset[iField] = 1;
573  else
574  psDBF->panFieldOffset[iField] =
575  psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
576  }
577 
578  /* Check that the total width of fields does not exceed the record width */
579  if( psDBF->nFields > 0 &&
580  psDBF->panFieldOffset[psDBF->nFields-1] +
581  psDBF->panFieldSize[psDBF->nFields-1] > psDBF->nRecordLength )
582  {
583  DBFClose( psDBF );
584  return SHPLIB_NULLPTR;
585  }
586 
587  DBFSetWriteEndOfFileChar( psDBF, TRUE );
588 
589  psDBF->bRequireNextWriteSeek = TRUE;
590 
591  return( psDBF );
592 }
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:599
#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:2297
static void * SfRealloc(void *pMem, int nNewSize)
Definition: dbfopen.c:109
#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: