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

◆ SHPOpenLL()

SHPHandle SHPAPI_CALL SHPOpenLL ( const char *  pszShapeFile,
const char *  pszAccess,
SAHooks psHooks 
)

Definition at line 482 of file shpopen.c.

484{
485 char *pszFullname, *pszBasename;
486 SHPHandle psSHP;
487
488 uchar *pabyBuf;
489 int i;
490 double dValue;
491
492/* -------------------------------------------------------------------- */
493/* Ensure the access string is one of the legal ones. We */
494/* ensure the result string indicates binary to avoid common */
495/* problems on Windows. */
496/* -------------------------------------------------------------------- */
497 if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0
498 || strcmp(pszAccess,"r+") == 0 )
499 pszAccess = "r+b";
500 else
501 pszAccess = "rb";
502
503/* -------------------------------------------------------------------- */
504/* Establish the byte order on this machine. */
505/* -------------------------------------------------------------------- */
506 i = 1;
507 if( *((uchar *) &i) == 1 )
509 else
511
512/* -------------------------------------------------------------------- */
513/* Initialize the info structure. */
514/* -------------------------------------------------------------------- */
515 psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1);
516
517 psSHP->bUpdated = FALSE;
518 memcpy( &(psSHP->sHooks), psHooks, sizeof(SAHooks) );
519
520/* -------------------------------------------------------------------- */
521/* Compute the base (layer) name. If there is any extension */
522/* on the passed in filename we will strip it off. */
523/* -------------------------------------------------------------------- */
524 pszBasename = (char *) malloc(strlen(pszLayer)+5);
525 strcpy( pszBasename, pszLayer );
526 for( i = strlen(pszBasename)-1;
527 i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
528 && pszBasename[i] != '\\';
529 i-- ) {}
530
531 if( pszBasename[i] == '.' )
532 pszBasename[i] = '\0';
533
534/* -------------------------------------------------------------------- */
535/* Open the .shp and .shx files. Note that files pulled from */
536/* a PC to Unix with upper case filenames won't work! */
537/* -------------------------------------------------------------------- */
538 pszFullname = (char *) malloc(strlen(pszBasename) + 5);
539 sprintf( pszFullname, "%s.shp", pszBasename ) ;
540 psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
541 if( psSHP->fpSHP == NULL )
542 {
543 sprintf( pszFullname, "%s.SHP", pszBasename );
544 psSHP->fpSHP = psSHP->sHooks.FOpen(pszFullname, pszAccess );
545 }
546
547 if( psSHP->fpSHP == NULL )
548 {
549 char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
550 sprintf( pszMessage, "Unable to open %s.shp or %s.SHP.",
551 pszBasename, pszBasename );
552 psHooks->Error( pszMessage );
553 free( pszMessage );
554 free( psSHP );
555 free( pszBasename );
556 free( pszFullname );
557 return( NULL );
558 }
559
560 sprintf( pszFullname, "%s.shx", pszBasename );
561 psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
562 if( psSHP->fpSHX == NULL )
563 {
564 sprintf( pszFullname, "%s.SHX", pszBasename );
565 psSHP->fpSHX = psSHP->sHooks.FOpen(pszFullname, pszAccess );
566 }
567
568 if( psSHP->fpSHX == NULL )
569 {
570 char *pszMessage = (char *) malloc(strlen(pszBasename)*2+256);
571 sprintf( pszMessage, "Unable to open %s.shx or %s.SHX.",
572 pszBasename, pszBasename );
573 psHooks->Error( pszMessage );
574 free( pszMessage );
575
576 psSHP->sHooks.FClose( psSHP->fpSHP );
577 free( psSHP );
578 free( pszBasename );
579 free( pszFullname );
580 return( NULL );
581 }
582
583 free( pszFullname );
584 free( pszBasename );
585
586/* -------------------------------------------------------------------- */
587/* Read the file size from the SHP file. */
588/* -------------------------------------------------------------------- */
589 pabyBuf = (uchar *) malloc(100);
590 psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHP );
591
592 psSHP->nFileSize = ((unsigned int)pabyBuf[24] * 256 * 256 * 256
593 + (unsigned int)pabyBuf[25] * 256 * 256
594 + (unsigned int)pabyBuf[26] * 256
595 + (unsigned int)pabyBuf[27]) * 2;
596
597/* -------------------------------------------------------------------- */
598/* Read SHX file Header info */
599/* -------------------------------------------------------------------- */
600 if( psSHP->sHooks.FRead( pabyBuf, 100, 1, psSHP->fpSHX ) != 1
601 || pabyBuf[0] != 0
602 || pabyBuf[1] != 0
603 || pabyBuf[2] != 0x27
604 || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
605 {
606 psSHP->sHooks.Error( ".shx file is unreadable, or corrupt." );
607 psSHP->sHooks.FClose( psSHP->fpSHP );
608 psSHP->sHooks.FClose( psSHP->fpSHX );
609 free( psSHP );
610
611 return( NULL );
612 }
613
614 psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256
615 + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256;
616 psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8;
617
618 psSHP->nShapeType = pabyBuf[32];
619
620 if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 )
621 {
622 char szError[200];
623
624 sprintf( szError,
625 "Record count in .shp header is %d, which seems\n"
626 "unreasonable. Assuming header is corrupt.",
627 psSHP->nRecords );
628 psSHP->sHooks.Error( szError );
629 psSHP->sHooks.FClose( psSHP->fpSHP );
630 psSHP->sHooks.FClose( psSHP->fpSHX );
631 free( psSHP );
632 free(pabyBuf);
633
634 return( NULL );
635 }
636
637/* -------------------------------------------------------------------- */
638/* Read the bounds. */
639/* -------------------------------------------------------------------- */
640 if( bBigEndian ) SwapWord( 8, pabyBuf+36 );
641 memcpy( &dValue, pabyBuf+36, 8 );
642 psSHP->adBoundsMin[0] = dValue;
643
644 if( bBigEndian ) SwapWord( 8, pabyBuf+44 );
645 memcpy( &dValue, pabyBuf+44, 8 );
646 psSHP->adBoundsMin[1] = dValue;
647
648 if( bBigEndian ) SwapWord( 8, pabyBuf+52 );
649 memcpy( &dValue, pabyBuf+52, 8 );
650 psSHP->adBoundsMax[0] = dValue;
651
652 if( bBigEndian ) SwapWord( 8, pabyBuf+60 );
653 memcpy( &dValue, pabyBuf+60, 8 );
654 psSHP->adBoundsMax[1] = dValue;
655
656 if( bBigEndian ) SwapWord( 8, pabyBuf+68 ); /* z */
657 memcpy( &dValue, pabyBuf+68, 8 );
658 psSHP->adBoundsMin[2] = dValue;
659
660 if( bBigEndian ) SwapWord( 8, pabyBuf+76 );
661 memcpy( &dValue, pabyBuf+76, 8 );
662 psSHP->adBoundsMax[2] = dValue;
663
664 if( bBigEndian ) SwapWord( 8, pabyBuf+84 ); /* z */
665 memcpy( &dValue, pabyBuf+84, 8 );
666 psSHP->adBoundsMin[3] = dValue;
667
668 if( bBigEndian ) SwapWord( 8, pabyBuf+92 );
669 memcpy( &dValue, pabyBuf+92, 8 );
670 psSHP->adBoundsMax[3] = dValue;
671
672 free( pabyBuf );
673
674/* -------------------------------------------------------------------- */
675/* Read the .shx file to get the offsets to each record in */
676/* the .shp file. */
677/* -------------------------------------------------------------------- */
678 psSHP->nMaxRecords = psSHP->nRecords;
679
680 psSHP->panRecOffset = (unsigned int *)
681 malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
682 psSHP->panRecSize = (unsigned int *)
683 malloc(sizeof(unsigned int) * MAX(1,psSHP->nMaxRecords) );
684 pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) );
685
686 if (psSHP->panRecOffset == NULL ||
687 psSHP->panRecSize == NULL ||
688 pabyBuf == NULL)
689 {
690 char szError[200];
691
692 sprintf(szError,
693 "Not enough memory to allocate requested memory (nRecords=%d).\n"
694 "Probably broken SHP file",
695 psSHP->nRecords );
696 psSHP->sHooks.Error( szError );
697 psSHP->sHooks.FClose( psSHP->fpSHP );
698 psSHP->sHooks.FClose( psSHP->fpSHX );
699 if (psSHP->panRecOffset) free( psSHP->panRecOffset );
700 if (psSHP->panRecSize) free( psSHP->panRecSize );
701 if (pabyBuf) free( pabyBuf );
702 free( psSHP );
703 return( NULL );
704 }
705
706 if( (int) psSHP->sHooks.FRead( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX )
707 != psSHP->nRecords )
708 {
709 char szError[200];
710
711 sprintf( szError,
712 "Failed to read all values for %d records in .shx file.",
713 psSHP->nRecords );
714 psSHP->sHooks.Error( szError );
715
716 /* SHX is short or unreadable for some reason. */
717 psSHP->sHooks.FClose( psSHP->fpSHP );
718 psSHP->sHooks.FClose( psSHP->fpSHX );
719 free( psSHP->panRecOffset );
720 free( psSHP->panRecSize );
721 free( pabyBuf );
722 free( psSHP );
723
724 return( NULL );
725 }
726
727 /* In read-only mode, we can close the SHX now */
728 if (strcmp(pszAccess, "rb") == 0)
729 {
730 psSHP->sHooks.FClose( psSHP->fpSHX );
731 psSHP->fpSHX = NULL;
732 }
733
734 for( i = 0; i < psSHP->nRecords; i++ )
735 {
736 int32 nOffset, nLength;
737
738 memcpy( &nOffset, pabyBuf + i * 8, 4 );
739 if( !bBigEndian ) SwapWord( 4, &nOffset );
740
741 memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
742 if( !bBigEndian ) SwapWord( 4, &nLength );
743
744 psSHP->panRecOffset[i] = nOffset*2;
745 psSHP->panRecSize[i] = nLength*2;
746 }
747 free( pabyBuf );
748
749 return( psSHP );
750}
void * malloc(YYSIZE_T)
void free(void *)
SHPInfo * SHPHandle
Definition shapefil.h:301
static int bBigEndian
Definition shpopen.c:293
unsigned int int32
Definition shpopen.c:273
unsigned char uchar
Definition shpopen.c:268
static void SwapWord(int length, void *wordP)
Definition shpopen.c:302
#define TRUE
Definition shpopen.c:278
#define FALSE
Definition shpopen.c:277
#define MAX(a, b)
Definition shpopen.c:284
void(* Error)(const char *message)
Definition shapefil.h:264
SAFile(* FOpen)(const char *filename, const char *access)
Definition shapefil.h:255
int(* FClose)(SAFile file)
Definition shapefil.h:261
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition shapefil.h:256
SAFile fpSHX
Definition shapefil.h:281
int nShapeType
Definition shapefil.h:283
SAFile fpSHP
Definition shapefil.h:280
int nMaxRecords
Definition shapefil.h:288
unsigned int * panRecSize
Definition shapefil.h:290
SAHooks sHooks
Definition shapefil.h:278
double adBoundsMin[4]
Definition shapefil.h:292
int nRecords
Definition shapefil.h:287
int bUpdated
Definition shapefil.h:295
unsigned int nFileSize
Definition shapefil.h:285
unsigned int * panRecOffset
Definition shapefil.h:289
double adBoundsMax[4]
Definition shapefil.h:293

References SHPInfo::adBoundsMax, SHPInfo::adBoundsMin, bBigEndian, SHPInfo::bUpdated, SAHooks::Error, FALSE, SAHooks::FClose, SAHooks::FOpen, SHPInfo::fpSHP, SHPInfo::fpSHX, SAHooks::FRead, free(), malloc(), MAX, SHPInfo::nFileSize, SHPInfo::nMaxRecords, SHPInfo::nRecords, SHPInfo::nShapeType, SHPInfo::panRecOffset, SHPInfo::panRecSize, SHPInfo::sHooks, SwapWord(), and TRUE.

Referenced by SHPCreateLL(), and SHPOpen().

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