PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ SHPRestoreSHX()

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

Definition at line 703 of file shpopen.c.

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