PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ DBFOpenLL()

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

Definition at line 382 of file dbfopen.c.

References FALSE, SAHooks::FClose, SAHooks::FOpen, free(), malloc(), SfRealloc(), and SHPAPI_CALL.

Referenced by DBFOpen().

384 {
385  DBFHandle psDBF;
386  SAFile pfCPG;
387  unsigned char *pabyBuf;
388  int nFields, nHeadLen, iField, i;
389  char *pszBasename, *pszFullname;
390  int nBufSize = 500;
391 
392 /* -------------------------------------------------------------------- */
393 /* We only allow the access strings "rb" and "r+". */
394 /* -------------------------------------------------------------------- */
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 )
398  return( NULL );
399 
400  if( strcmp(pszAccess,"r") == 0 )
401  pszAccess = "rb";
402 
403  if( strcmp(pszAccess,"r+") == 0 )
404  pszAccess = "rb+";
405 
406 /* -------------------------------------------------------------------- */
407 /* Compute the base (layer) name. If there is any extension */
408 /* on the passed in filename we will strip it off. */
409 /* -------------------------------------------------------------------- */
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] != '\\';
415  i-- ) {}
416 
417  if( pszBasename[i] == '.' )
418  pszBasename[i] = '\0';
419 
420  pszFullname = (char *) malloc(strlen(pszBasename) + 5);
421  sprintf( pszFullname, "%s.dbf", pszBasename );
422 
423  psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
424  psDBF->fp = psHooks->FOpen( pszFullname, pszAccess );
425  memcpy( &(psDBF->sHooks), psHooks, sizeof(SAHooks) );
426 
427  if( psDBF->fp == NULL )
428  {
429  sprintf( pszFullname, "%s.DBF", pszBasename );
430  psDBF->fp = psDBF->sHooks.FOpen(pszFullname, pszAccess );
431  }
432 
433  sprintf( pszFullname, "%s.cpg", pszBasename );
434  pfCPG = psHooks->FOpen( pszFullname, "r" );
435  if( pfCPG == NULL )
436  {
437  sprintf( pszFullname, "%s.CPG", pszBasename );
438  pfCPG = psHooks->FOpen( pszFullname, "r" );
439  }
440 
441  free( pszBasename );
442  free( pszFullname );
443 
444  if( psDBF->fp == NULL )
445  {
446  free( psDBF );
447  if( pfCPG ) psHooks->FClose( pfCPG );
448  return( NULL );
449  }
450 
451  psDBF->bNoHeader = FALSE;
452  psDBF->nCurrentRecord = -1;
453  psDBF->bCurrentRecordModified = FALSE;
454 
455 /* -------------------------------------------------------------------- */
456 /* Read Table Header info */
457 /* -------------------------------------------------------------------- */
458  pabyBuf = (unsigned char *) malloc(nBufSize);
459  if( psDBF->sHooks.FRead( pabyBuf, 32, 1, psDBF->fp ) != 1 )
460  {
461  psDBF->sHooks.FClose( psDBF->fp );
462  if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
463  free( pabyBuf );
464  free( psDBF );
465  return NULL;
466  }
467 
468  psDBF->nRecords =
469  pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
470 
471  psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
472  psDBF->nRecordLength = pabyBuf[10] + pabyBuf[11]*256;
473  psDBF->iLanguageDriver = pabyBuf[29];
474 
475  if (nHeadLen < 32)
476  {
477  psDBF->sHooks.FClose( psDBF->fp );
478  if( pfCPG ) psDBF->sHooks.FClose( pfCPG );
479  free( pabyBuf );
480  free( psDBF );
481  return NULL;
482  }
483 
484  psDBF->nFields = nFields = (nHeadLen - 32) / 32;
485 
486  psDBF->pszCurrentRecord = (char *) malloc(psDBF->nRecordLength);
487 
488 /* -------------------------------------------------------------------- */
489 /* Figure out the code page from the LDID and CPG */
490 /* -------------------------------------------------------------------- */
491 
492  psDBF->pszCodePage = NULL;
493  if( pfCPG )
494  {
495  size_t n;
496  memset( pabyBuf, 0, nBufSize);
497  psDBF->sHooks.FRead( pabyBuf, nBufSize - 1, 1, pfCPG );
498  n = strcspn( (char *) pabyBuf, "\n\r" );
499  if( n > 0 )
500  {
501  pabyBuf[n] = '\0';
502  psDBF->pszCodePage = (char *) malloc(n + 1);
503  memcpy( psDBF->pszCodePage, pabyBuf, n + 1 );
504  }
505  psDBF->sHooks.FClose( pfCPG );
506  }
507  if( (psDBF->pszCodePage == NULL) && (psDBF->iLanguageDriver != 0) )
508  {
509  sprintf( (char *) pabyBuf, "LDID/%d", psDBF->iLanguageDriver );
510  psDBF->pszCodePage = (char *) malloc(strlen((char*)pabyBuf) + 1);
511  strcpy( psDBF->pszCodePage, (char *) pabyBuf );
512  }
513 
514 /* -------------------------------------------------------------------- */
515 /* Read in Field Definitions */
516 /* -------------------------------------------------------------------- */
517 
518  pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
519  psDBF->pszHeader = (char *) pabyBuf;
520 
521  psDBF->sHooks.FSeek( psDBF->fp, 32, 0 );
522  if( psDBF->sHooks.FRead( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
523  {
524  psDBF->sHooks.FClose( psDBF->fp );
525  free( pabyBuf );
526  free( psDBF->pszCurrentRecord );
527  free( psDBF );
528  return NULL;
529  }
530 
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);
535 
536  for( iField = 0; iField < nFields; iField++ )
537  {
538  unsigned char *pabyFInfo;
539 
540  pabyFInfo = pabyBuf+iField*32;
541 
542  if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
543  {
544  psDBF->panFieldSize[iField] = pabyFInfo[16];
545  psDBF->panFieldDecimals[iField] = pabyFInfo[17];
546  }
547  else
548  {
549  psDBF->panFieldSize[iField] = pabyFInfo[16];
550  psDBF->panFieldDecimals[iField] = 0;
551 
552 /*
553 ** The following seemed to be used sometimes to handle files with long
554 ** string fields, but in other cases (such as bug 1202) the decimals field
555 ** just seems to indicate some sort of preferred formatting, not very
556 ** wide fields. So I have disabled this code. FrankW.
557  psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
558  psDBF->panFieldDecimals[iField] = 0;
559 */
560  }
561 
562  psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
563  if( iField == 0 )
564  psDBF->panFieldOffset[iField] = 1;
565  else
566  psDBF->panFieldOffset[iField] =
567  psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
568  }
569 
570  return( psDBF );
571 }
static void * SfRealloc(void *pMem, int nNewSize)
Definition: dbfopen.c:179
int(* FClose)(SAFile file)
Definition: shapefil.h:261
#define FALSE
Definition: dbfopen.c:168
void free(void *)
void * malloc(YYSIZE_T)
int * SAFile
Definition: shapefil.h:242
SAFile(* FOpen)(const char *filename, const char *access)
Definition: shapefil.h:255
Here is the call graph for this function:
Here is the caller graph for this function: