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
370
373
374
375
376
377
380 memcpy(pszFullname, pszLayer, nLenWithoutExtension);
381 memcpy(pszFullname + nLenWithoutExtension, ".shp", 5);
384 {
385 memcpy(pszFullname + nLenWithoutExtension, ".SHP", 5);
387 }
388
390 {
391 size_t nMessageLen = strlen(pszFullname)*2+256;
393 pszFullname[nLenWithoutExtension] = 0;
394 snprintf( pszMessage, nMessageLen, "Unable to open %s.shp or %s.SHP.",
395 pszFullname, pszFullname );
396 psHooks->
Error( pszMessage );
398
401
403 }
404
405 memcpy(pszFullname + nLenWithoutExtension, ".shx", 5);
408 {
409 memcpy(pszFullname + nLenWithoutExtension, ".SHX", 5);
411 }
412
414 {
415 size_t nMessageLen = strlen(pszFullname)*2+256;
417 pszFullname[nLenWithoutExtension] = 0;
418 snprintf( pszMessage, nMessageLen, "Unable to open %s.shx or %s.SHX. "
419 "Set SHAPE_RESTORE_SHX config option to YES to restore or "
420 "create it.", pszFullname, pszFullname );
421 psHooks->
Error( pszMessage );
423
428 }
429
431
432
433
434
437 {
438 psSHP->
sHooks.
Error(
".shp file is unreadable, or corrupt." );
443
445 }
446
448 (pabyBuf[26]<<8)|pabyBuf[27];
451 else
453
454
455
456
458 || pabyBuf[0] != 0
459 || pabyBuf[1] != 0
460 || pabyBuf[2] != 0x27
461 || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) )
462 {
463 psSHP->
sHooks.
Error(
".shx file is unreadable, or corrupt." );
468
470 }
471
472 psSHP->
nRecords = pabyBuf[27]|(pabyBuf[26]<<8)|(pabyBuf[25]<<16)|
473 ((pabyBuf[24] & 0x7F)<<24);
475
477
479 {
480 char szErrorMsg[200];
481
482 snprintf( szErrorMsg, sizeof(szErrorMsg),
483 "Record count in .shp header is %d, which seems\n"
484 "unreasonable. Assuming header is corrupt.",
486 szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
492
494 }
495
496
497
498 if( psSHP->
nRecords >= 1024 * 1024 )
499 {
503 if( nFileSize > 100 &&
505 {
507 }
509 }
510
511
512
513
515 memcpy( &dValue, pabyBuf+36, 8 );
517
519 memcpy( &dValue, pabyBuf+44, 8 );
521
523 memcpy( &dValue, pabyBuf+52, 8 );
525
527 memcpy( &dValue, pabyBuf+60, 8 );
529
531 memcpy( &dValue, pabyBuf+68, 8 );
533
535 memcpy( &dValue, pabyBuf+76, 8 );
537
539 memcpy( &dValue, pabyBuf+84, 8 );
541
543 memcpy( &dValue, pabyBuf+92, 8 );
545
547
548
549
550
551
553
558 if( bLazySHXLoading )
560 else
562
566 {
567 char szErrorMsg[200];
568
569 snprintf( szErrorMsg, sizeof(szErrorMsg),
570 "Not enough memory to allocate requested memory (nRecords=%d).\n"
571 "Probably broken SHP file",
573 szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
579 if (pabyBuf)
free( pabyBuf );
582 }
583
584 if( bLazySHXLoading )
585 {
589 return( psSHP );
590 }
591
594 {
595 char szErrorMsg[200];
596
597 snprintf( szErrorMsg, sizeof(szErrorMsg),
598 "Failed to read all values for %d records in .shx file: %s.",
600 szErrorMsg[sizeof(szErrorMsg)-1] = '\0';
602
603
610
612 }
613
614
615 if (strcmp(pszAccess, "rb") == 0)
616 {
619 }
620
621 for( i = 0; i < psSHP->
nRecords; i++ )
622 {
623 unsigned int nOffset, nLength;
624
625 memcpy( &nOffset, pabyBuf + i * 8, 4 );
627
628 memcpy( &nLength, pabyBuf + i * 8 + 4, 4 );
630
632 {
634 snprintf(
str,
sizeof(
str),
635 "Invalid offset for entity %d", i);
636 str[
sizeof(
str)-1] =
'\0';
637
642 }
643 if( nLength >
STATIC_CAST(
unsigned int, INT_MAX / 2 - 4) )
644 {
646 snprintf(
str,
sizeof(
str),
647 "Invalid length for entity %d", i);
648 str[
sizeof(
str)-1] =
'\0';
649
654 }
657 }
659
660 return( psSHP );
661}
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