698{
699 char *pszFullname;
701
702
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
719
720
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
732
733#if !defined(bBigEndian)
734 {
735 int i = 1;
736 if( *((
uchar *) &i) == 1 )
738 else
740 }
741#endif
742
743
744
745
746
749 memcpy(pszFullname, pszLayer, nLenWithoutExtension);
750 memcpy(pszFullname + nLenWithoutExtension, ".shp", 5);
751 fpSHP = psHooks->
FOpen(pszFullname, pszAccess );
753 {
754 memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5);
755 fpSHP = psHooks->
FOpen(pszFullname, pszAccess );
756 }
757
759 {
760 size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
762
763 pszFullname[nLenWithoutExtension] = 0;
764 snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.",
765 pszFullname, pszFullname );
766 psHooks->
Error( pszMessage );
768
770
771 return( 0 );
772 }
773
774
775
776
778 if( psHooks->
FRead( pabyBuf, 100, 1, fpSHP ) != 1 )
779 {
780 psHooks->
Error(
".shp file is unreadable, or corrupt." );
782
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 );
799 {
800 size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
802 pszFullname[nLenWithoutExtension] = 0;
803 snprintf( pszMessage, nMessageLen,
804 "Error opening file %s.shx for writing", pszFullname );
805 psHooks->
Error( pszMessage );
807
809
812
813 return( 0 );
814 }
815
816
817
818
819 psHooks->
FSeek( fpSHP, 100, 0 );
821 memcpy( pabySHXHeader, pabyBuf, 100 );
822 psHooks->
FWrite( pabySHXHeader, 100, 1, fpSHX );
824
825 while( nCurrentSHPOffset < nSHPFilesize )
826 {
827 if( psHooks->
FRead( &niRecord, 4, 1, fpSHP ) == 1 &&
828 psHooks->
FRead( &nRecordLength, 4, 1, fpSHP ) == 1)
829 {
831 memcpy( abyReadedRecord, &nRecordOffset, 4 );
832 memcpy( abyReadedRecord + 4, &nRecordLength, 4 );
833
834 psHooks->
FWrite( abyReadedRecord, 8, 1, fpSHX );
835
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
850
851 free( pabySHXHeader );
853
854 return( 0 );
855 }
856 }
857
858 nRealSHXContentSize /= 2;
860 psHooks->
FSeek( fpSHX, 24, 0 );
861 psHooks->
FWrite( &nRealSHXContentSize, 4, 1, fpSHX );
862
865
866 free ( pszFullname );
867 free ( pabySHXHeader );
868
869 return( 1 );
870}
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)