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

◆ SHPRestoreSHX()

int SHPAPI_CALL SHPRestoreSHX ( const char *  pszLayer,
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 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/* Ensure the access string is one of the legal ones. We */
719/* ensure the result string indicates binary to avoid common */
720/* problems on Windows. */
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/* Establish the byte order on this machine. */
732/* -------------------------------------------------------------------- */
733#if !defined(bBigEndian)
734 {
735 int i = 1;
736 if( *((uchar *) &i) == 1 )
738 else
740 }
741#endif
742
743/* -------------------------------------------------------------------- */
744/* Open the .shp file. Note that files pulled from */
745/* a PC to Unix with upper case filenames won't work! */
746/* -------------------------------------------------------------------- */
747 nLenWithoutExtension = SHPGetLenWithoutExtension(pszLayer);
748 pszFullname = STATIC_CAST(char *, malloc(nLenWithoutExtension + 5));
749 memcpy(pszFullname, pszLayer, nLenWithoutExtension);
750 memcpy(pszFullname + nLenWithoutExtension, ".shp", 5);
751 fpSHP = psHooks->FOpen(pszFullname, pszAccess );
752 if( fpSHP == SHPLIB_NULLPTR )
753 {
754 memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5);
755 fpSHP = psHooks->FOpen(pszFullname, pszAccess );
756 }
757
758 if( fpSHP == SHPLIB_NULLPTR )
759 {
760 size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
761 char* pszMessage = STATIC_CAST(char *, malloc( nMessageLen ));
762
763 pszFullname[nLenWithoutExtension] = 0;
764 snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.",
765 pszFullname, pszFullname );
766 psHooks->Error( pszMessage );
767 free( pszMessage );
768
769 free( pszFullname );
770
771 return( 0 );
772 }
773
774/* -------------------------------------------------------------------- */
775/* Read the file size from the SHP file. */
776/* -------------------------------------------------------------------- */
777 pabyBuf = STATIC_CAST(uchar *, malloc(100));
778 if( psHooks->FRead( pabyBuf, 100, 1, fpSHP ) != 1 )
779 {
780 psHooks->Error( ".shp file is unreadable, or corrupt." );
781 psHooks->FClose( fpSHP );
782
783 free( pabyBuf );
784 free( pszFullname );
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 );
798 if( fpSHX == SHPLIB_NULLPTR )
799 {
800 size_t nMessageLen = strlen( pszFullname ) * 2 + 256;
801 char* pszMessage = STATIC_CAST(char *, malloc( nMessageLen ));
802 pszFullname[nLenWithoutExtension] = 0;
803 snprintf( pszMessage, nMessageLen,
804 "Error opening file %s.shx for writing", pszFullname );
805 psHooks->Error( pszMessage );
806 free( pszMessage );
807
808 psHooks->FClose( fpSHP );
809
810 free( pabyBuf );
811 free( pszFullname );
812
813 return( 0 );
814 }
815
816/* -------------------------------------------------------------------- */
817/* Open SHX and create it using SHP file content. */
818/* -------------------------------------------------------------------- */
819 psHooks->FSeek( fpSHP, 100, 0 );
820 pabySHXHeader = STATIC_CAST(char *, malloc ( 100 ));
821 memcpy( pabySHXHeader, pabyBuf, 100 );
822 psHooks->FWrite( pabySHXHeader, 100, 1, fpSHX );
823 free ( pabyBuf );
824
825 while( nCurrentSHPOffset < nSHPFilesize )
826 {
827 if( psHooks->FRead( &niRecord, 4, 1, fpSHP ) == 1 &&
828 psHooks->FRead( &nRecordLength, 4, 1, fpSHP ) == 1)
829 {
830 if( !bBigEndian ) SwapWord( 4, &nRecordOffset );
831 memcpy( abyReadedRecord, &nRecordOffset, 4 );
832 memcpy( abyReadedRecord + 4, &nRecordLength, 4 );
833
834 psHooks->FWrite( abyReadedRecord, 8, 1, fpSHX );
835
836 if ( !bBigEndian ) SwapWord( 4, &nRecordOffset );
837 if ( !bBigEndian ) SwapWord( 4, &nRecordLength );
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
848 psHooks->FClose( fpSHX );
849 psHooks->FClose( fpSHP );
850
851 free( pabySHXHeader );
852 free( pszFullname );
853
854 return( 0 );
855 }
856 }
857
858 nRealSHXContentSize /= 2; // Bytes counted -> WORDs
859 if( !bBigEndian ) SwapWord( 4, &nRealSHXContentSize );
860 psHooks->FSeek( fpSHX, 24, 0 );
861 psHooks->FWrite( &nRealSHXContentSize, 4, 1, fpSHX );
862
863 psHooks->FClose( fpSHP );
864 psHooks->FClose( fpSHX );
865
866 free ( pszFullname );
867 free ( pabySHXHeader );
868
869 return( 1 );
870}
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: