PostGIS  2.1.10dev-r@@SVN_REVISION@@
DBFHandle SHPAPI_CALL DBFOpenLL ( const char *  pszDBFFile,
const char *  pszAccess,
SAHooks psHooks 
)

Definition at line 383 of file dbfopen.c.

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

Referenced by DBFOpen().

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

Here is the call graph for this function:

Here is the caller graph for this function: