331{
332 char *pszFullname;
334
336 int i;
337 double dValue;
338 int bLazySHXLoading =
FALSE;
339 int nLenWithoutExtension;
340
341
342
343
344
345
346 if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0
347 || strcmp(pszAccess,"r+") == 0 )
348 pszAccess = "r+b";
349 else
350 {
352 pszAccess = "rb";
353 }
354
355
356
357
358#if !defined(bBigEndian)
359 i = 1;
360 if( *((
uchar *) &i) == 1 )
362 else
364#endif
365
366
367
368
372
375
376
377
378
379
383 {
386 }
387 memcpy(pszFullname, pszLayer, nLenWithoutExtension);
388 memcpy(pszFullname + nLenWithoutExtension, ".shp", 5);
391 {
392 memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5);
394 }
395
397 {
398 size_t nMessageLen = strlen(pszFullname)*2+256;
400 pszFullname[nLenWithoutExtension] = 0;
401 snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.",
402 pszFullname, pszFullname );
403 psHooks->
Error( pszMessage );
405
408
410 }
411
412 memcpy(pszFullname + nLenWithoutExtension, ".shx", 5);
415 {
416 memcpy(pszFullname + nLenWithoutExtension, ".SHX", 5);
418 }
419
421 {
422 size_t nMessageLen = strlen(pszFullname)*2+256;
424 pszFullname[nLenWithoutExtension] = 0;
425 snprintf( pszMessage, nMessageLen, "Unable to open %s.shx or %s.SHX. "
426 "Set SHAPE_RESTORE_SHX config option to YES to restore or "
427 "create it.", pszFullname, pszFullname );
428 psHooks->
Error( pszMessage );
430
435 }
436
438
439
440
441
444 {
445 psSHP->
sHooks.
Error(
".shp file is unreadable, or corrupt." );
450
452 }
453
455 (pabyBuf[26]<<8)|pabyBuf[27];
458 else
460
461
462
463
465 || pabyBuf[0] != 0
466 || pabyBuf[1] != 0
467 || pabyBuf[2] != 0x27
468 || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
469 {
470 psSHP->
sHooks.
Error(
".shx file is unreadable, or corrupt." );
475
477 }
478
479 psSHP->
nRecords = pabyBuf[27]|(pabyBuf[26]<<8)|(pabyBuf[25]<<16)|
480 ((pabyBuf[24] & 0x7F)<<24);
482
484
486 {
487 char szErrorMsg[200];
488
489 snprintf( szErrorMsg, sizeof(szErrorMsg),
490 "Record count in .shp header is %d, which seems\n"
491 "unreasonable. Assuming header is corrupt.",
493 szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
499
501 }
502
503
504
505 if( psSHP->
nRecords >= 1024 * 1024 )
506 {
510 if( nFileSize > 100 &&
512 {
514 }
516 }
517
518
519
520
522 memcpy( &dValue, pabyBuf+36, 8 );
524
526 memcpy( &dValue, pabyBuf+44, 8 );
528
530 memcpy( &dValue, pabyBuf+52, 8 );
532
534 memcpy( &dValue, pabyBuf+60, 8 );
536
538 memcpy( &dValue, pabyBuf+68, 8 );
540
542 memcpy( &dValue, pabyBuf+76, 8 );
544
546 memcpy( &dValue, pabyBuf+84, 8 );
548
550 memcpy( &dValue, pabyBuf+92, 8 );
552
554
555
556
557
558
560
565 if( bLazySHXLoading )
567 else
569
573 {
574 char szErrorMsg[200];
575
576 snprintf( szErrorMsg, sizeof(szErrorMsg),
577 "Not enough memory to allocate requested memory (nRecords=%d).\n"
578 "Probably broken SHP file",
580 szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
586 if (pabyBuf)
free( pabyBuf );
589 }
590
591 if( bLazySHXLoading )
592 {
596 return( psSHP );
597 }
598
601 {
602 char szErrorMsg[200];
603
604 snprintf( szErrorMsg, sizeof(szErrorMsg),
605 "Failed to read all values for %d records in .shx file: %s.",
607 szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
609
610
617
619 }
620
621
622 if (strcmp(pszAccess, "rb") == 0)
623 {
626 }
627
628 for( i = 0; i < psSHP->
nRecords; i++ )
629 {
630 unsigned int nOffset, nLength;
631
632 memcpy( &nOffset, pabyBuf + i * 8, 4 );
634
635 memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
637
639 {
641 snprintf(
str,
sizeof(
str),
642 "Invalid offset for entity %d", i);
643 str[
sizeof(
str)-1] =
'\0';
644
649 }
650 if( nLength >
STATIC_CAST(
unsigned int, INT_MAX / 2 - 4) )
651 {
653 snprintf(
str,
sizeof(
str),
654 "Invalid length for entity %d", i);
655 str[
sizeof(
str)-1] =
'\0';
656
661 }
664 }
666
667 return( psSHP );
668}
static void SwapWord(int length, void *wordP)
static int SHPGetLenWithoutExtension(const char *pszBasename)
void SHPAPI_CALL SHPClose(SHPHandle psSHP)
#define STATIC_CAST(type, x)
void(* Error)(const char *message)
SAFile(* FOpen)(const char *filename, const char *access)
SAOffset(* FTell)(SAFile file)
int(* FClose)(SAFile file)
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
unsigned int * panRecSize
unsigned int * panRecOffset