PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ SHPRestoreSHX()

int SHPAPI_CALL SHPRestoreSHX ( const char *  pszLayer,
const char *  pszAccess,
SAHooks psHooks 
)

Definition at line 696 of file shpopen.c.

698 {
699  char *pszFullname;
700  SAFile fpSHP, fpSHX;
701 
702 
703  uchar *pabyBuf;
704  int nLenWithoutExtension;
705  unsigned int nSHPFilesize;
706 
707  unsigned int nCurrentSHPOffset = 100;
708  size_t nRealSHXContentSize = 100;
709 
710  const char pszSHXAccess[] = "w+b";
711  char *pabySHXHeader;
712  char abyReadedRecord[8];
713  unsigned int niRecord = 0;
714  unsigned int nRecordLength = 0;
715  unsigned int nRecordOffset = 50;
716 
717 /* -------------------------------------------------------------------- */
718 /* Ensure the access string is one of the legal ones. We */
719 /* ensure the result string indicates binary to avoid common */
720 /* problems on Windows. */
721 /* -------------------------------------------------------------------- */
722  if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0
723  || strcmp(pszAccess,"r+") == 0 )
724  pszAccess = "r+b";
725  else
726  {
727  pszAccess = "rb";
728  }
729 
730 /* -------------------------------------------------------------------- */
731 /* Establish the byte order on this machine. */
732 /* -------------------------------------------------------------------- */
733 #if !defined(bBigEndian)
734  {
735  int i = 1;
736  if( *((uchar *) &i) == 1 )
737  bBigEndian = FALSE;
738  else
739  bBigEndian = TRUE;
740  }
741 #endif
742 
743 /* -------------------------------------------------------------------- */
744 /* Open the .shp file. Note that files pulled from */
745 /* a PC to Unix with upper case filenames won't work! */
746 /* -------------------------------------------------------------------- */
747  nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer);
748  pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5));
749  memcpy(pszFullname, pszLayer, nLenWithoutExtension);
750  memcpy(pszFullname + nLenWithoutExtension, ".shp", 5);
751  fpSHP = psHooks->FOpen(pszFullname, pszAccess );
752  if( fpSHP == SHPLIB_NULLPTR )
753  {
754  memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5);
755  fpSHP = psHooks->FOpen(pszFullname, pszAccess );
756  }
757 
758  if( fpSHP == SHPLIB_NULLPTR )
759  {
760  size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
761  char* pszMessage = STATIC_CAST(char *, malloc( nMessageLen ));
762 
763  pszFullname[nLenWithoutExtension] = 0;
764  snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.",
765  pszFullname, pszFullname );
766  psHooks->Error( pszMessage );
767  free( pszMessage );
768 
769  free( pszFullname );
770 
771  return( 0 );
772  }
773 
774 /* -------------------------------------------------------------------- */
775 /* Read the file size from the SHP file. */
776 /* -------------------------------------------------------------------- */
777  pabyBuf = STATIC_CAST(uchar *, malloc(100));
778  if( psHooks->FRead( pabyBuf, 100, 1, fpSHP ) != 1 )
779  {
780  psHooks->Error( ".shp file is unreadable, or corrupt." );
781  psHooks->FClose( fpSHP );
782 
783  free( pabyBuf );
784  free( pszFullname );
785 
786  return( 0 );
787  }
788 
789  nSHPFilesize = (STATIC_CAST(unsigned int, pabyBuf[24])<<24)|(pabyBuf[25]<<16)|
790  (pabyBuf[26]<<8)|pabyBuf[27];
791  if( nSHPFilesize < UINT_MAX / 2 )
792  nSHPFilesize *= 2;
793  else
794  nSHPFilesize = (UINT_MAX / 2) * 2;
795 
796  memcpy(pszFullname + nLenWithoutExtension, ".shx", 5);
797  fpSHX = psHooks->FOpen( pszFullname, pszSHXAccess );
798  if( fpSHX == SHPLIB_NULLPTR )
799  {
800  size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
801  char* pszMessage = STATIC_CAST(char *, malloc( nMessageLen ));
802  pszFullname[nLenWithoutExtension] = 0;
803  snprintf( pszMessage, nMessageLen,
804  "Error opening file %s.shx for writing", pszFullname );
805  psHooks->Error( pszMessage );
806  free( pszMessage );
807 
808  psHooks->FClose( fpSHP );
809 
810  free( pabyBuf );
811  free( pszFullname );
812 
813  return( 0 );
814  }
815 
816 /* -------------------------------------------------------------------- */
817 /* Open SHX and create it using SHP file content. */
818 /* -------------------------------------------------------------------- */
819  psHooks->FSeek( fpSHP, 100, 0 );
820  pabySHXHeader = STATIC_CAST(char *, malloc ( 100 ));
821  memcpy( pabySHXHeader, pabyBuf, 100 );
822  psHooks->FWrite( pabySHXHeader, 100, 1, fpSHX );
823  free ( pabyBuf );
824 
825  while( nCurrentSHPOffset < nSHPFilesize )
826  {
827  if( psHooks->FRead( &niRecord, 4, 1, fpSHP ) == 1 &&
828  psHooks->FRead( &nRecordLength, 4, 1, fpSHP ) == 1)
829  {
830  if( !bBigEndian ) SwapWord( 4, &nRecordOffset );
831  memcpy( abyReadedRecord, &nRecordOffset, 4 );
832  memcpy( abyReadedRecord + 4, &nRecordLength, 4 );
833 
834  psHooks->FWrite( abyReadedRecord, 8, 1, fpSHX );
835 
836  if ( !bBigEndian ) SwapWord( 4, &nRecordOffset );
837  if ( !bBigEndian ) SwapWord( 4, &nRecordLength );
838  nRecordOffset += nRecordLength + 4;
839  nCurrentSHPOffset += 8 + nRecordLength * 2;
840 
841  psHooks->FSeek( fpSHP, nCurrentSHPOffset, 0 );
842  nRealSHXContentSize += 8;
843  }
844  else
845  {
846  psHooks->Error( "Error parsing .shp to restore .shx" );
847 
848  psHooks->FClose( fpSHX );
849  psHooks->FClose( fpSHP );
850 
851  free( pabySHXHeader );
852  free( pszFullname );
853 
854  return( 0 );
855  }
856  }
857 
858  nRealSHXContentSize /= 2; // Bytes counted -> WORDs
859  if( !bBigEndian ) SwapWord( 4, &nRealSHXContentSize );
860  psHooks->FSeek( fpSHX, 24, 0 );
861  psHooks->FWrite( &nRealSHXContentSize, 4, 1, fpSHX );
862 
863  psHooks->FClose( fpSHP );
864  psHooks->FClose( fpSHX );
865 
866  free ( pszFullname );
867  free ( pabySHXHeader );
868 
869  return( 1 );
870 }
void * malloc(YYSIZE_T)
void free(void *)
int * SAFile
Definition: shapefil.h:283
static int bBigEndian
Definition: shpopen.c:93
unsigned char uchar
Definition: shpopen.c:49
static void SwapWord(int length, void *wordP)
Definition: shpopen.c:110
static int SHPGetLenWithoutExtension(const char *pszBasename)
Definition: shpopen.c:305
#define STATIC_CAST(type, x)
Definition: shpopen.c:100
#define TRUE
Definition: shpopen.c:59
#define FALSE
Definition: shpopen.c:58
#define SHPLIB_NULLPTR
Definition: shpopen.c:101
void(* Error)(const char *message)
Definition: shapefil.h:299
SAFile(* FOpen)(const char *filename, const char *access)
Definition: shapefil.h:290
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition: shapefil.h:292
int(* FClose)(SAFile file)
Definition: shapefil.h:296
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition: shapefil.h:291
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
Definition: shapefil.h:293

References bBigEndian, SAHooks::Error, FALSE, SAHooks::FClose, SAHooks::FOpen, SAHooks::FRead, free(), SAHooks::FSeek, SAHooks::FWrite, malloc(), SHPGetLenWithoutExtension(), SHPLIB_NULLPTR, STATIC_CAST, SwapWord(), and TRUE.

Referenced by SHPOpenLLEx().

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