PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ SHPRestoreSHX()

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