705{
706 char *pszFullname;
708
709
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
726
727
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
739
740#if !defined(bBigEndian)
741 {
742 int i = 1;
743 if( *((
uchar *) &i) == 1 )
745 else
747 }
748#endif
749
750
751
752
753
758 memcpy(pszFullname, pszLayer, nLenWithoutExtension);
759 memcpy(pszFullname + nLenWithoutExtension, ".shp", 5);
760 fpSHP = psHooks->
FOpen(pszFullname, pszAccess );
762 {
763 memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5);
764 fpSHP = psHooks->
FOpen(pszFullname, pszAccess );
765 }
766
768 {
769 size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
771
772 pszFullname[nLenWithoutExtension] = 0;
773 snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.",
774 pszFullname, pszFullname );
775 psHooks->
Error( pszMessage );
777
779
780 return( 0 );
781 }
782
783
784
785
787 if( psHooks->
FRead( pabyBuf, 100, 1, fpSHP ) != 1 )
788 {
789 psHooks->
Error(
".shp file is unreadable, or corrupt." );
791
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 );
808 {
809 size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
811 pszFullname[nLenWithoutExtension] = 0;
812 snprintf( pszMessage, nMessageLen,
813 "Error opening file %s.shx for writing", pszFullname );
814 psHooks->
Error( pszMessage );
816
818
821
822 return( 0 );
823 }
824
825
826
827
828 psHooks->
FSeek( fpSHP, 100, 0 );
830 memcpy( pabySHXHeader, pabyBuf, 100 );
831 psHooks->
FWrite( pabySHXHeader, 100, 1, fpSHX );
833
834 while( nCurrentSHPOffset < nSHPFilesize )
835 {
836 if( psHooks->
FRead( &niRecord, 4, 1, fpSHP ) == 1 &&
837 psHooks->
FRead( &nRecordLength, 4, 1, fpSHP ) == 1)
838 {
840 memcpy( abyReadedRecord, &nRecordOffset, 4 );
841 memcpy( abyReadedRecord + 4, &nRecordLength, 4 );
842
843 psHooks->
FWrite( abyReadedRecord, 8, 1, fpSHX );
844
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
859
860 free( pabySHXHeader );
862
863 return( 0 );
864 }
865 }
866
867 nRealSHXContentSize /= 2;
869 psHooks->
FSeek( fpSHX, 24, 0 );
870 psHooks->
FWrite( &nRealSHXContentSize, 4, 1, fpSHX );
871
874
875 free ( pszFullname );
876 free ( pabySHXHeader );
877
878 return( 1 );
879}
static void SwapWord(int length, void *wordP)
static int SHPGetLenWithoutExtension(const char *pszBasename)
#define STATIC_CAST(type, x)
void(* Error)(const char *message)
SAFile(* FOpen)(const char *filename, const char *access)
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
int(* FClose)(SAFile file)
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)