PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ DBFOpenLL()

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

Definition at line 370 of file dbfopen.c.

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

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

Referenced by DBFOpen().

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