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

◆ DBFOpenLL()

DBFHandle SHPAPI_CALL DBFOpenLL ( const char *  pszFilename,
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}
static void * SfRealloc(void *pMem, int nNewSize)
Definition dbfopen.c:180
#define FALSE
Definition dbfopen.c:168
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: