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

◆ 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 )
745 else
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: