249
246
static void DBFWriteHeader(DBFHandle psDBF)
252
unsigned char abyHeader[XBASE_FLDHDR_SZ];
255
if( !psDBF->bNoHeader )
258
psDBF->bNoHeader = FALSE;
260
/* -------------------------------------------------------------------- */
261
/* Initialize the file header information. */
262
/* -------------------------------------------------------------------- */
263
for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
266
abyHeader[0] = 0x03; /* memo field? - just copying */
268
/* write out a dummy date */
269
abyHeader[1] = 95; /* YY */
270
abyHeader[2] = 7; /* MM */
271
abyHeader[3] = 26; /* DD */
273
/* record count preset at zero */
275
abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
276
abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
278
abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
279
abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
281
/* -------------------------------------------------------------------- */
282
/* Write the initial 32 byte file header, and all the field */
284
/* -------------------------------------------------------------------- */
285
fseek( psDBF->fp, 0, 0 );
286
fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
287
fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
289
/* -------------------------------------------------------------------- */
290
/* Write out the newline character if there is room for it. */
291
/* -------------------------------------------------------------------- */
292
if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
297
fwrite( &cNewline, 1, 1, psDBF->fp );
249
unsigned char abyHeader[XBASE_FLDHDR_SZ];
252
if ( !psDBF->bNoHeader )
255
psDBF->bNoHeader = FALSE;
257
/* -------------------------------------------------------------------- */
258
/* Initialize the file header information. */
259
/* -------------------------------------------------------------------- */
260
for ( i = 0; i < XBASE_FLDHDR_SZ; i++ )
263
abyHeader[0] = 0x03; /* memo field? - just copying */
265
/* write out a dummy date */
266
abyHeader[1] = 95; /* YY */
267
abyHeader[2] = 7; /* MM */
268
abyHeader[3] = 26; /* DD */
270
/* record count preset at zero */
272
abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
273
abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
275
abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
276
abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
278
/* -------------------------------------------------------------------- */
279
/* Write the initial 32 byte file header, and all the field */
281
/* -------------------------------------------------------------------- */
282
fseek( psDBF->fp, 0, 0 );
283
fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );
284
fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );
286
/* -------------------------------------------------------------------- */
287
/* Write out the newline character if there is room for it. */
288
/* -------------------------------------------------------------------- */
289
if ( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
294
fwrite( &cNewline, 1, 1, psDBF->fp );
301
298
/************************************************************************/
356
353
/* Open a .dbf file. */
357
354
/************************************************************************/
359
356
DBFHandle SHPAPI_CALL
360
357
DBFOpen( const char * pszFilename, const char * pszAccess )
364
unsigned char *pabyBuf;
365
int nFields, nHeadLen, nRecLen, iField, i;
366
char *pszBasename, *pszFullname;
368
/* -------------------------------------------------------------------- */
369
/* We only allow the access strings "rb" and "r+". */
370
/* -------------------------------------------------------------------- */
371
if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0
372
&& strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0
373
&& strcmp(pszAccess,"r+b") != 0 )
376
if( strcmp(pszAccess,"r") == 0 )
379
if( strcmp(pszAccess,"r+") == 0 )
382
/* -------------------------------------------------------------------- */
383
/* Compute the base (layer) name. If there is any extension */
384
/* on the passed in filename we will strip it off. */
385
/* -------------------------------------------------------------------- */
386
pszBasename = (char *) malloc(strlen(pszFilename)+5);
387
strcpy( pszBasename, pszFilename );
388
for( i = strlen(pszBasename)-1;
389
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
390
&& pszBasename[i] != '\\';
393
if( pszBasename[i] == '.' )
394
pszBasename[i] = '\0';
396
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
397
sprintf( pszFullname, "%s.dbf", pszBasename );
399
psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
400
psDBF->fp = fopen( pszFullname, pszAccess );
402
if( psDBF->fp == NULL )
404
sprintf( pszFullname, "%s.DBF", pszBasename );
405
psDBF->fp = fopen(pszFullname, pszAccess );
411
if( psDBF->fp == NULL )
417
psDBF->bNoHeader = FALSE;
418
psDBF->nCurrentRecord = -1;
419
psDBF->bCurrentRecordModified = FALSE;
421
/* -------------------------------------------------------------------- */
422
/* Read Table Header info */
423
/* -------------------------------------------------------------------- */
424
pabyBuf = (unsigned char *) malloc(500);
425
if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
434
pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
436
psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
437
psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
439
psDBF->nFields = nFields = (nHeadLen - 32) / 32;
441
psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
443
/* -------------------------------------------------------------------- */
444
/* Read in Field Definitions */
445
/* -------------------------------------------------------------------- */
447
pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
448
psDBF->pszHeader = (char *) pabyBuf;
450
fseek( psDBF->fp, 32, 0 );
451
if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
459
psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields);
460
psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields);
461
psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields);
462
psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields);
464
for( iField = 0; iField < nFields; iField++ )
466
unsigned char *pabyFInfo;
468
pabyFInfo = pabyBuf+iField*32;
470
if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
472
psDBF->panFieldSize[iField] = pabyFInfo[16];
473
psDBF->panFieldDecimals[iField] = pabyFInfo[17];
477
psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
478
psDBF->panFieldDecimals[iField] = 0;
481
psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
483
psDBF->panFieldOffset[iField] = 1;
485
psDBF->panFieldOffset[iField] =
486
psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
361
unsigned char *pabyBuf;
362
int nFields, nHeadLen, nRecLen, iField, i;
363
char *pszBasename, *pszFullname;
365
/* -------------------------------------------------------------------- */
366
/* We only allow the access strings "rb" and "r+". */
367
/* -------------------------------------------------------------------- */
368
if ( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0
369
&& strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0
370
&& strcmp(pszAccess,"r+b") != 0 )
373
if ( strcmp(pszAccess,"r") == 0 )
376
if ( strcmp(pszAccess,"r+") == 0 )
379
/* -------------------------------------------------------------------- */
380
/* Compute the base (layer) name. If there is any extension */
381
/* on the passed in filename we will strip it off. */
382
/* -------------------------------------------------------------------- */
383
pszBasename = (char *) malloc(strlen(pszFilename)+5);
384
strcpy( pszBasename, pszFilename );
385
for ( i = strlen(pszBasename)-1;
386
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
387
&& pszBasename[i] != '\\';
391
if ( pszBasename[i] == '.' )
392
pszBasename[i] = '\0';
394
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
395
sprintf( pszFullname, "%s.dbf", pszBasename );
397
psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
398
psDBF->fp = fopen( pszFullname, pszAccess );
400
if ( psDBF->fp == NULL )
402
sprintf( pszFullname, "%s.DBF", pszBasename );
403
psDBF->fp = fopen(pszFullname, pszAccess );
409
if ( psDBF->fp == NULL )
415
psDBF->bNoHeader = FALSE;
416
psDBF->nCurrentRecord = -1;
417
psDBF->bCurrentRecordModified = FALSE;
419
/* -------------------------------------------------------------------- */
420
/* Read Table Header info */
421
/* -------------------------------------------------------------------- */
422
pabyBuf = (unsigned char *) malloc(500);
423
if ( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
432
pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
434
psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
435
psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
437
psDBF->nFields = nFields = (nHeadLen - 32) / 32;
439
psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
441
/* -------------------------------------------------------------------- */
442
/* Read in Field Definitions */
443
/* -------------------------------------------------------------------- */
445
pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
446
psDBF->pszHeader = (char *) pabyBuf;
448
fseek( psDBF->fp, 32, 0 );
449
if ( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
457
psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields);
458
psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields);
459
psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields);
460
psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields);
462
for ( iField = 0; iField < nFields; iField++ )
464
unsigned char *pabyFInfo;
466
pabyFInfo = pabyBuf+iField*32;
468
if ( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
470
psDBF->panFieldSize[iField] = pabyFInfo[16];
471
psDBF->panFieldDecimals[iField] = pabyFInfo[17];
475
psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
476
psDBF->panFieldDecimals[iField] = 0;
479
psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
481
psDBF->panFieldOffset[iField] = 1;
483
psDBF->panFieldOffset[iField] =
484
psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
492
490
/************************************************************************/
497
495
DBFClose(DBFHandle psDBF)
499
static char eof = 0x1a;
502
/* -------------------------------------------------------------------- */
503
/* Write out header if not already written. */
504
/* -------------------------------------------------------------------- */
505
if( psDBF->bNoHeader )
506
DBFWriteHeader( psDBF );
508
DBFFlushRecord( psDBF );
510
/* -------------------------------------------------------------------- */
511
/* Update last access date, and number of records if we have */
513
/* -------------------------------------------------------------------- */
514
if( psDBF->bUpdated )
515
DBFUpdateHeader( psDBF );
517
/* -------------------------------------------------------------------- */
518
/* Add the DBF end-of-file marker after the last record. */
519
/* -------------------------------------------------------------------- */
521
fseek(psDBF->fp, -1, SEEK_END);
522
fread(&eof_test, 1, 1, psDBF->fp);
523
if( eof_test != 0x1a ) /* no EOF exists, so write one */
525
fseek(psDBF->fp, 0, SEEK_END);
526
fwrite(&eof, 1, 1, psDBF->fp);
529
/* -------------------------------------------------------------------- */
530
/* Close, and free resources. */
531
/* -------------------------------------------------------------------- */
534
if( psDBF->panFieldOffset != NULL )
536
free( psDBF->panFieldOffset );
537
free( psDBF->panFieldSize );
538
free( psDBF->panFieldDecimals );
539
free( psDBF->pachFieldType );
542
free( psDBF->pszHeader );
543
free( psDBF->pszCurrentRecord );
547
if( pszStringField != NULL )
549
free( pszStringField );
550
pszStringField = NULL;
497
static char eof = 0x1a;
500
/* -------------------------------------------------------------------- */
501
/* Write out header if not already written. */
502
/* -------------------------------------------------------------------- */
503
if ( psDBF->bNoHeader )
504
DBFWriteHeader( psDBF );
506
DBFFlushRecord( psDBF );
508
/* -------------------------------------------------------------------- */
509
/* Update last access date, and number of records if we have */
511
/* -------------------------------------------------------------------- */
512
if ( psDBF->bUpdated )
513
DBFUpdateHeader( psDBF );
515
/* -------------------------------------------------------------------- */
516
/* Add the DBF end-of-file marker after the last record. */
517
/* -------------------------------------------------------------------- */
519
fseek(psDBF->fp, -1, SEEK_END);
520
fread(&eof_test, 1, 1, psDBF->fp);
521
if ( eof_test != 0x1a ) /* no EOF exists, so write one */
523
fseek(psDBF->fp, 0, SEEK_END);
524
fwrite(&eof, 1, 1, psDBF->fp);
527
/* -------------------------------------------------------------------- */
528
/* Close, and free resources. */
529
/* -------------------------------------------------------------------- */
532
if ( psDBF->panFieldOffset != NULL )
534
free( psDBF->panFieldOffset );
535
free( psDBF->panFieldSize );
536
free( psDBF->panFieldDecimals );
537
free( psDBF->pachFieldType );
540
free( psDBF->pszHeader );
541
free( psDBF->pszCurrentRecord );
545
if ( pszStringField != NULL )
547
free( pszStringField );
548
pszStringField = NULL;
555
553
/************************************************************************/
562
560
DBFCreate( const char * pszFilename )
567
char *pszFullname, *pszBasename;
570
/* -------------------------------------------------------------------- */
571
/* Compute the base (layer) name. If there is any extension */
572
/* on the passed in filename we will strip it off. */
573
/* -------------------------------------------------------------------- */
574
pszBasename = (char *) malloc(strlen(pszFilename)+5);
575
strcpy( pszBasename, pszFilename );
576
for( i = strlen(pszBasename)-1;
577
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
578
&& pszBasename[i] != '\\';
581
if( pszBasename[i] == '.' )
582
pszBasename[i] = '\0';
584
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
585
sprintf( pszFullname, "%s.dbf", pszBasename );
588
/* -------------------------------------------------------------------- */
589
/* Create the file. */
590
/* -------------------------------------------------------------------- */
591
fp = fopen( pszFullname, "wb" );
598
fp = fopen( pszFullname, "rb+" );
604
/* -------------------------------------------------------------------- */
605
/* Create the info structure. */
606
/* -------------------------------------------------------------------- */
607
psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
612
psDBF->nRecordLength = 1;
613
psDBF->nHeaderLength = 33;
614
psDBF->bUpdated = FALSE;
616
psDBF->panFieldOffset = NULL;
617
psDBF->panFieldSize = NULL;
618
psDBF->panFieldDecimals = NULL;
619
psDBF->pachFieldType = NULL;
620
psDBF->pszHeader = NULL;
622
psDBF->nCurrentRecord = -1;
623
psDBF->bCurrentRecordModified = FALSE;
624
psDBF->pszCurrentRecord = NULL;
626
psDBF->bNoHeader = TRUE;
565
char *pszFullname, *pszBasename;
568
/* -------------------------------------------------------------------- */
569
/* Compute the base (layer) name. If there is any extension */
570
/* on the passed in filename we will strip it off. */
571
/* -------------------------------------------------------------------- */
572
pszBasename = (char *) malloc(strlen(pszFilename)+5);
573
strcpy( pszBasename, pszFilename );
574
for ( i = strlen(pszBasename)-1;
575
i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
576
&& pszBasename[i] != '\\';
580
if ( pszBasename[i] == '.' )
581
pszBasename[i] = '\0';
583
pszFullname = (char *) malloc(strlen(pszBasename) + 5);
584
sprintf( pszFullname, "%s.dbf", pszBasename );
587
/* -------------------------------------------------------------------- */
588
/* Create the file. */
589
/* -------------------------------------------------------------------- */
590
fp = fopen( pszFullname, "wb" );
597
fp = fopen( pszFullname, "rb+" );
603
/* -------------------------------------------------------------------- */
604
/* Create the info structure. */
605
/* -------------------------------------------------------------------- */
606
psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
611
psDBF->nRecordLength = 1;
612
psDBF->nHeaderLength = 33;
613
psDBF->bUpdated = FALSE;
615
psDBF->panFieldOffset = NULL;
616
psDBF->panFieldSize = NULL;
617
psDBF->panFieldDecimals = NULL;
618
psDBF->pachFieldType = NULL;
619
psDBF->pszHeader = NULL;
621
psDBF->nCurrentRecord = -1;
622
psDBF->bCurrentRecordModified = FALSE;
623
psDBF->pszCurrentRecord = NULL;
625
psDBF->bNoHeader = TRUE;
631
630
/************************************************************************/
636
635
/************************************************************************/
639
DBFAddField(DBFHandle psDBF, const char * pszFieldName,
638
DBFAddField(DBFHandle psDBF, const char * pszFieldName,
640
639
DBFFieldType eType, int nWidth, int nDecimals )
646
/* -------------------------------------------------------------------- */
647
/* Do some checking to ensure we can add records to this file. */
648
/* -------------------------------------------------------------------- */
649
if( psDBF->nRecords > 0 )
652
if( !psDBF->bNoHeader )
655
if( eType != FTDouble && nDecimals != 0 )
661
/* -------------------------------------------------------------------- */
662
/* SfRealloc all the arrays larger to hold the additional field */
664
/* -------------------------------------------------------------------- */
667
psDBF->panFieldOffset = (int *)
668
SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
670
psDBF->panFieldSize = (int *)
671
SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
673
psDBF->panFieldDecimals = (int *)
674
SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
676
psDBF->pachFieldType = (char *)
677
SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
679
/* -------------------------------------------------------------------- */
680
/* Assign the new field information fields. */
681
/* -------------------------------------------------------------------- */
682
psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
683
psDBF->nRecordLength += nWidth;
684
psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
685
psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
687
if( eType == FTLogical )
688
psDBF->pachFieldType[psDBF->nFields-1] = 'L';
689
else if( eType == FTString )
690
psDBF->pachFieldType[psDBF->nFields-1] = 'C';
691
else if( eType == FTDate )
692
psDBF->pachFieldType[psDBF->nFields-1] = 'D';
694
psDBF->pachFieldType[psDBF->nFields-1] = 'N';
696
/* -------------------------------------------------------------------- */
697
/* Extend the required header information. */
698
/* -------------------------------------------------------------------- */
699
psDBF->nHeaderLength += 32;
700
psDBF->bUpdated = FALSE;
702
psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
704
pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
706
for( i = 0; i < 32; i++ )
709
if( (int) strlen(pszFieldName) < 10 )
710
strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
712
strncpy( pszFInfo, pszFieldName, 10);
714
pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
716
if( eType == FTString )
718
pszFInfo[16] = (unsigned char) (nWidth % 256);
719
pszFInfo[17] = (unsigned char) (nWidth / 256);
723
pszFInfo[16] = (unsigned char) nWidth;
724
pszFInfo[17] = (unsigned char) nDecimals;
727
/* -------------------------------------------------------------------- */
728
/* Make the current record buffer appropriately larger. */
729
/* -------------------------------------------------------------------- */
730
psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
731
psDBF->nRecordLength);
733
return( psDBF->nFields-1 );
645
/* -------------------------------------------------------------------- */
646
/* Do some checking to ensure we can add records to this file. */
647
/* -------------------------------------------------------------------- */
648
if ( psDBF->nRecords > 0 )
651
if ( !psDBF->bNoHeader )
654
if ( eType != FTDouble && nDecimals != 0 )
660
/* -------------------------------------------------------------------- */
661
/* SfRealloc all the arrays larger to hold the additional field */
663
/* -------------------------------------------------------------------- */
666
psDBF->panFieldOffset = (int *)
667
SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
669
psDBF->panFieldSize = (int *)
670
SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
672
psDBF->panFieldDecimals = (int *)
673
SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
675
psDBF->pachFieldType = (char *)
676
SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
678
/* -------------------------------------------------------------------- */
679
/* Assign the new field information fields. */
680
/* -------------------------------------------------------------------- */
681
psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
682
psDBF->nRecordLength += nWidth;
683
psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
684
psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
686
if ( eType == FTLogical )
687
psDBF->pachFieldType[psDBF->nFields-1] = 'L';
688
else if ( eType == FTString )
689
psDBF->pachFieldType[psDBF->nFields-1] = 'C';
690
else if ( eType == FTDate )
691
psDBF->pachFieldType[psDBF->nFields-1] = 'D';
693
psDBF->pachFieldType[psDBF->nFields-1] = 'N';
695
/* -------------------------------------------------------------------- */
696
/* Extend the required header information. */
697
/* -------------------------------------------------------------------- */
698
psDBF->nHeaderLength += 32;
699
psDBF->bUpdated = FALSE;
701
psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
703
pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
705
for ( i = 0; i < 32; i++ )
708
if ( (int) strlen(pszFieldName) < 10 )
709
strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
711
strncpy( pszFInfo, pszFieldName, 10);
713
pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
715
if ( eType == FTString )
717
pszFInfo[16] = (unsigned char) (nWidth % 256);
718
pszFInfo[17] = (unsigned char) (nWidth / 256);
722
pszFInfo[16] = (unsigned char) nWidth;
723
pszFInfo[17] = (unsigned char) nDecimals;
726
/* -------------------------------------------------------------------- */
727
/* Make the current record buffer appropriately larger. */
728
/* -------------------------------------------------------------------- */
729
psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
730
psDBF->nRecordLength);
732
return( psDBF->nFields-1 );
740
739
/* Prep a record for reading. */
741
740
/************************************************************************/
743
int DBFReadSetup(DBFHandle psDBF, int hEntity)
742
int DBFReadSetup(DBFHandle psDBF, int hEntity)
747
/* -------------------------------------------------------------------- */
748
/* Verify selection. */
749
/* -------------------------------------------------------------------- */
750
if( hEntity < 0 || hEntity >= psDBF->nRecords )
753
/* -------------------------------------------------------------------- */
754
/* Have we read the record? */
755
/* -------------------------------------------------------------------- */
756
if( psDBF->nCurrentRecord != hEntity )
758
DBFFlushRecord( psDBF );
760
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
762
if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
764
fprintf( stderr, "fseek(%d) failed on DBF file.\n",
769
if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,
770
1, psDBF->fp ) != 1 )
772
fprintf( stderr, "fread(%d) failed on DBF file.\n",
773
psDBF->nRecordLength );
777
psDBF->nCurrentRecord = hEntity;
746
/* -------------------------------------------------------------------- */
747
/* Verify selection. */
748
/* -------------------------------------------------------------------- */
749
if ( hEntity < 0 || hEntity >= psDBF->nRecords )
752
/* -------------------------------------------------------------------- */
753
/* Have we read the record? */
754
/* -------------------------------------------------------------------- */
755
if ( psDBF->nCurrentRecord != hEntity )
757
DBFFlushRecord( psDBF );
759
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
761
if ( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
763
fprintf( stderr, "fseek(%d) failed on DBF file.\n",
768
if ( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,
769
1, psDBF->fp ) != 1 )
771
fprintf( stderr, "fread(%d) failed on DBF file.\n",
772
psDBF->nRecordLength );
776
psDBF->nCurrentRecord = hEntity;
815
unsigned char *pabyRec;
816
void *pReturnField = NULL;
818
static double dDoubleField;
820
/* -------------------------------------------------------------------- */
821
/* Verify selection. */
822
/* -------------------------------------------------------------------- */
823
if( iField < 0 || iField >= psDBF->nFields )
826
if( ! DBFReadSetup( psDBF, hEntity) )
829
/* get reference to current record */
830
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
832
/* -------------------------------------------------------------------- */
833
/* Ensure our field buffer is large enough to hold this buffer. */
834
/* -------------------------------------------------------------------- */
835
if( psDBF->panFieldSize[iField]+1 > nStringFieldLen )
837
nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10;
838
pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen);
841
/* -------------------------------------------------------------------- */
842
/* Extract the requested field. */
843
/* -------------------------------------------------------------------- */
844
strncpy( pszStringField,
845
((const char *) pabyRec) + psDBF->panFieldOffset[iField],
846
psDBF->panFieldSize[iField] );
847
pszStringField[psDBF->panFieldSize[iField]] = '\0';
849
pReturnField = pszStringField;
851
/* -------------------------------------------------------------------- */
852
/* Decode the field. */
853
/* -------------------------------------------------------------------- */
854
if( chReqType == 'N' )
856
dDoubleField = atof(pszStringField);
857
pReturnField = &dDoubleField;
860
/* -------------------------------------------------------------------- */
861
/* Should we trim white space off the string attribute value? */
862
/* -------------------------------------------------------------------- */
815
unsigned char *pabyRec;
816
void *pReturnField = NULL;
818
static double dDoubleField;
820
/* -------------------------------------------------------------------- */
821
/* Verify selection. */
822
/* -------------------------------------------------------------------- */
823
if ( iField < 0 || iField >= psDBF->nFields )
826
if ( ! DBFReadSetup( psDBF, hEntity) )
829
/* get reference to current record */
830
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
832
/* -------------------------------------------------------------------- */
833
/* Ensure our field buffer is large enough to hold this buffer. */
834
/* -------------------------------------------------------------------- */
835
if ( psDBF->panFieldSize[iField]+1 > nStringFieldLen )
837
nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10;
838
pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen);
841
/* -------------------------------------------------------------------- */
842
/* Extract the requested field. */
843
/* -------------------------------------------------------------------- */
844
strncpy( pszStringField,
845
((const char *) pabyRec) + psDBF->panFieldOffset[iField],
846
psDBF->panFieldSize[iField] );
847
pszStringField[psDBF->panFieldSize[iField]] = '\0';
849
pReturnField = pszStringField;
851
/* -------------------------------------------------------------------- */
852
/* Decode the field. */
853
/* -------------------------------------------------------------------- */
854
if ( chReqType == 'N' )
856
dDoubleField = atof(pszStringField);
857
pReturnField = &dDoubleField;
860
/* -------------------------------------------------------------------- */
861
/* Should we trim white space off the string attribute value? */
862
/* -------------------------------------------------------------------- */
863
863
#ifdef TRIM_DBF_WHITESPACE
866
char *pchSrc, *pchDst;
868
pchDst = pchSrc = pszStringField;
869
while( *pchSrc == ' ' )
872
while( *pchSrc != '\0' )
873
*(pchDst++) = *(pchSrc++);
876
while( pchDst != pszStringField && *(--pchDst) == ' ' )
866
char *pchSrc, *pchDst;
868
pchDst = pchSrc = pszStringField;
869
while ( *pchSrc == ' ' )
872
while ( *pchSrc != '\0' )
873
*(pchDst++) = *(pchSrc++);
876
while ( pchDst != pszStringField && *(--pchDst) == ' ' )
881
return( pReturnField );
881
return( pReturnField );
884
884
/************************************************************************/
1070
1070
/************************************************************************/
1072
1072
static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
1076
int nRecordOffset, i, j, nRetResult = TRUE;
1077
unsigned char *pabyRec;
1078
char szSField[400], szFormat[20];
1080
/* -------------------------------------------------------------------- */
1081
/* Is this a valid record? */
1082
/* -------------------------------------------------------------------- */
1083
if( hEntity < 0 || hEntity > psDBF->nRecords )
1086
if( psDBF->bNoHeader )
1087
DBFWriteHeader(psDBF);
1089
/* -------------------------------------------------------------------- */
1090
/* Is this a brand new record? */
1091
/* -------------------------------------------------------------------- */
1092
if( hEntity == psDBF->nRecords )
1094
DBFFlushRecord( psDBF );
1097
for( i = 0; i < psDBF->nRecordLength; i++ )
1098
psDBF->pszCurrentRecord[i] = ' ';
1100
psDBF->nCurrentRecord = hEntity;
1103
/* -------------------------------------------------------------------- */
1104
/* Is this an existing record, but different than the last one */
1106
/* -------------------------------------------------------------------- */
1107
if( psDBF->nCurrentRecord != hEntity )
1109
DBFFlushRecord( psDBF );
1111
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1113
fseek( psDBF->fp, nRecordOffset, 0 );
1114
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1116
psDBF->nCurrentRecord = hEntity;
1119
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1121
psDBF->bCurrentRecordModified = TRUE;
1122
psDBF->bUpdated = TRUE;
1124
/* -------------------------------------------------------------------- */
1125
/* Translate NULL value to valid DBF file representation. */
1127
/* Contributed by Jim Matthews. */
1128
/* -------------------------------------------------------------------- */
1129
if( pValue == NULL )
1131
switch(psDBF->pachFieldType[iField])
1135
/* NULL numeric fields have value "****************" */
1136
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*',
1137
psDBF->panFieldSize[iField] );
1141
/* NULL date fields have value "00000000" */
1142
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0',
1143
psDBF->panFieldSize[iField] );
1147
/* NULL boolean fields have value "?" */
1148
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?',
1149
psDBF->panFieldSize[iField] );
1153
/* empty string fields are considered NULL */
1154
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0',
1155
psDBF->panFieldSize[iField] );
1161
/* -------------------------------------------------------------------- */
1162
/* Assign all the record fields. */
1163
/* -------------------------------------------------------------------- */
1164
switch( psDBF->pachFieldType[iField] )
1169
if( psDBF->panFieldDecimals[iField] == 0 )
1171
int nWidth = psDBF->panFieldSize[iField];
1173
if( sizeof(szSField)-2 < nWidth )
1174
nWidth = sizeof(szSField)-2;
1176
sprintf( szFormat, "%%%dd", nWidth );
1177
sprintf(szSField, szFormat, (int) *((double *) pValue) );
1178
if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
1180
szSField[psDBF->panFieldSize[iField]] = '\0';
1184
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1185
szSField, strlen(szSField) );
1189
int nWidth = psDBF->panFieldSize[iField];
1191
if( sizeof(szSField)-2 < nWidth )
1192
nWidth = sizeof(szSField)-2;
1194
sprintf( szFormat, "%%%d.%df",
1195
nWidth, psDBF->panFieldDecimals[iField] );
1196
sprintf(szSField, szFormat, *((double *) pValue) );
1197
if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
1199
szSField[psDBF->panFieldSize[iField]] = '\0';
1202
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1203
szSField, strlen(szSField) );
1208
if (psDBF->panFieldSize[iField] >= 1 &&
1209
(*(char*)pValue == 'F' || *(char*)pValue == 'T'))
1210
*(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
1214
if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1216
j = psDBF->panFieldSize[iField];
1221
memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
1222
psDBF->panFieldSize[iField] );
1223
j = strlen((char *) pValue);
1226
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1227
(char *) pValue, j );
1231
return( nRetResult );
1076
int nRecordOffset, i, j, nRetResult = TRUE;
1077
unsigned char *pabyRec;
1078
char szSField[400], szFormat[20];
1080
/* -------------------------------------------------------------------- */
1081
/* Is this a valid record? */
1082
/* -------------------------------------------------------------------- */
1083
if ( hEntity < 0 || hEntity > psDBF->nRecords )
1086
if ( psDBF->bNoHeader )
1087
DBFWriteHeader(psDBF);
1089
/* -------------------------------------------------------------------- */
1090
/* Is this a brand new record? */
1091
/* -------------------------------------------------------------------- */
1092
if ( hEntity == psDBF->nRecords )
1094
DBFFlushRecord( psDBF );
1097
for ( i = 0; i < psDBF->nRecordLength; i++ )
1098
psDBF->pszCurrentRecord[i] = ' ';
1100
psDBF->nCurrentRecord = hEntity;
1103
/* -------------------------------------------------------------------- */
1104
/* Is this an existing record, but different than the last one */
1106
/* -------------------------------------------------------------------- */
1107
if ( psDBF->nCurrentRecord != hEntity )
1109
DBFFlushRecord( psDBF );
1111
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1113
fseek( psDBF->fp, nRecordOffset, 0 );
1114
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1116
psDBF->nCurrentRecord = hEntity;
1119
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1121
psDBF->bCurrentRecordModified = TRUE;
1122
psDBF->bUpdated = TRUE;
1124
/* -------------------------------------------------------------------- */
1125
/* Translate NULL value to valid DBF file representation. */
1127
/* Contributed by Jim Matthews. */
1128
/* -------------------------------------------------------------------- */
1129
if ( pValue == NULL )
1131
switch (psDBF->pachFieldType[iField])
1135
/* NULL numeric fields have value "****************" */
1136
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*',
1137
psDBF->panFieldSize[iField] );
1141
/* NULL date fields have value "00000000" */
1142
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0',
1143
psDBF->panFieldSize[iField] );
1147
/* NULL boolean fields have value "?" */
1148
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?',
1149
psDBF->panFieldSize[iField] );
1153
/* empty string fields are considered NULL */
1154
memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0',
1155
psDBF->panFieldSize[iField] );
1161
/* -------------------------------------------------------------------- */
1162
/* Assign all the record fields. */
1163
/* -------------------------------------------------------------------- */
1164
switch ( psDBF->pachFieldType[iField] )
1169
if ( psDBF->panFieldDecimals[iField] == 0 )
1171
int nWidth = psDBF->panFieldSize[iField];
1173
if ( sizeof(szSField)-2 < nWidth )
1174
nWidth = sizeof(szSField)-2;
1176
sprintf( szFormat, "%%%dd", nWidth );
1177
sprintf(szSField, szFormat, (int) *((double *) pValue) );
1178
if ( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
1180
szSField[psDBF->panFieldSize[iField]] = '\0';
1184
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1185
szSField, strlen(szSField) );
1189
int nWidth = psDBF->panFieldSize[iField];
1191
if ( sizeof(szSField)-2 < nWidth )
1192
nWidth = sizeof(szSField)-2;
1194
sprintf( szFormat, "%%%d.%df",
1195
nWidth, psDBF->panFieldDecimals[iField] );
1196
sprintf(szSField, szFormat, *((double *) pValue) );
1197
if ( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
1199
szSField[psDBF->panFieldSize[iField]] = '\0';
1202
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1203
szSField, strlen(szSField) );
1208
if (psDBF->panFieldSize[iField] >= 1 &&
1209
(*(char*)pValue == 'F' || *(char*)pValue == 'T'))
1210
*(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
1214
if ( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1216
j = psDBF->panFieldSize[iField];
1221
memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
1222
psDBF->panFieldSize[iField] );
1223
j = strlen((char *) pValue);
1226
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1227
(char *) pValue, j );
1231
return( nRetResult );
1234
1234
/************************************************************************/
1243
1243
const void * pValue )
1246
int nRecordOffset, i, j;
1247
unsigned char *pabyRec;
1249
/* -------------------------------------------------------------------- */
1250
/* Is this a valid record? */
1251
/* -------------------------------------------------------------------- */
1252
if( hEntity < 0 || hEntity > psDBF->nRecords )
1255
if( psDBF->bNoHeader )
1256
DBFWriteHeader(psDBF);
1258
/* -------------------------------------------------------------------- */
1259
/* Is this a brand new record? */
1260
/* -------------------------------------------------------------------- */
1261
if( hEntity == psDBF->nRecords )
1263
DBFFlushRecord( psDBF );
1266
for( i = 0; i < psDBF->nRecordLength; i++ )
1267
psDBF->pszCurrentRecord[i] = ' ';
1269
psDBF->nCurrentRecord = hEntity;
1272
/* -------------------------------------------------------------------- */
1273
/* Is this an existing record, but different than the last one */
1275
/* -------------------------------------------------------------------- */
1276
if( psDBF->nCurrentRecord != hEntity )
1278
DBFFlushRecord( psDBF );
1280
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1282
fseek( psDBF->fp, nRecordOffset, 0 );
1283
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1285
psDBF->nCurrentRecord = hEntity;
1288
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1290
/* -------------------------------------------------------------------- */
1291
/* Assign all the record fields. */
1292
/* -------------------------------------------------------------------- */
1293
if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1294
j = psDBF->panFieldSize[iField];
1297
memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
1298
psDBF->panFieldSize[iField] );
1299
j = strlen((char *) pValue);
1302
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1303
(char *) pValue, j );
1305
psDBF->bCurrentRecordModified = TRUE;
1306
psDBF->bUpdated = TRUE;
1246
int nRecordOffset, i, j;
1247
unsigned char *pabyRec;
1249
/* -------------------------------------------------------------------- */
1250
/* Is this a valid record? */
1251
/* -------------------------------------------------------------------- */
1252
if ( hEntity < 0 || hEntity > psDBF->nRecords )
1255
if ( psDBF->bNoHeader )
1256
DBFWriteHeader(psDBF);
1258
/* -------------------------------------------------------------------- */
1259
/* Is this a brand new record? */
1260
/* -------------------------------------------------------------------- */
1261
if ( hEntity == psDBF->nRecords )
1263
DBFFlushRecord( psDBF );
1266
for ( i = 0; i < psDBF->nRecordLength; i++ )
1267
psDBF->pszCurrentRecord[i] = ' ';
1269
psDBF->nCurrentRecord = hEntity;
1272
/* -------------------------------------------------------------------- */
1273
/* Is this an existing record, but different than the last one */
1275
/* -------------------------------------------------------------------- */
1276
if ( psDBF->nCurrentRecord != hEntity )
1278
DBFFlushRecord( psDBF );
1280
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1282
fseek( psDBF->fp, nRecordOffset, 0 );
1283
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1285
psDBF->nCurrentRecord = hEntity;
1288
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1290
/* -------------------------------------------------------------------- */
1291
/* Assign all the record fields. */
1292
/* -------------------------------------------------------------------- */
1293
if ( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1294
j = psDBF->panFieldSize[iField];
1297
memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
1298
psDBF->panFieldSize[iField] );
1299
j = strlen((char *) pValue);
1302
strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1303
(char *) pValue, j );
1305
psDBF->bCurrentRecordModified = TRUE;
1306
psDBF->bUpdated = TRUE;
1311
1311
/************************************************************************/
1389
1389
DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
1392
int nRecordOffset, i;
1393
unsigned char *pabyRec;
1395
/* -------------------------------------------------------------------- */
1396
/* Is this a valid record? */
1397
/* -------------------------------------------------------------------- */
1398
if( hEntity < 0 || hEntity > psDBF->nRecords )
1401
if( psDBF->bNoHeader )
1402
DBFWriteHeader(psDBF);
1404
/* -------------------------------------------------------------------- */
1405
/* Is this a brand new record? */
1406
/* -------------------------------------------------------------------- */
1407
if( hEntity == psDBF->nRecords )
1409
DBFFlushRecord( psDBF );
1412
for( i = 0; i < psDBF->nRecordLength; i++ )
1413
psDBF->pszCurrentRecord[i] = ' ';
1415
psDBF->nCurrentRecord = hEntity;
1418
/* -------------------------------------------------------------------- */
1419
/* Is this an existing record, but different than the last one */
1421
/* -------------------------------------------------------------------- */
1422
if( psDBF->nCurrentRecord != hEntity )
1424
DBFFlushRecord( psDBF );
1426
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1428
fseek( psDBF->fp, nRecordOffset, 0 );
1429
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1431
psDBF->nCurrentRecord = hEntity;
1434
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1436
memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength );
1438
psDBF->bCurrentRecordModified = TRUE;
1439
psDBF->bUpdated = TRUE;
1392
int nRecordOffset, i;
1393
unsigned char *pabyRec;
1395
/* -------------------------------------------------------------------- */
1396
/* Is this a valid record? */
1397
/* -------------------------------------------------------------------- */
1398
if ( hEntity < 0 || hEntity > psDBF->nRecords )
1401
if ( psDBF->bNoHeader )
1402
DBFWriteHeader(psDBF);
1404
/* -------------------------------------------------------------------- */
1405
/* Is this a brand new record? */
1406
/* -------------------------------------------------------------------- */
1407
if ( hEntity == psDBF->nRecords )
1409
DBFFlushRecord( psDBF );
1412
for ( i = 0; i < psDBF->nRecordLength; i++ )
1413
psDBF->pszCurrentRecord[i] = ' ';
1415
psDBF->nCurrentRecord = hEntity;
1418
/* -------------------------------------------------------------------- */
1419
/* Is this an existing record, but different than the last one */
1421
/* -------------------------------------------------------------------- */
1422
if ( psDBF->nCurrentRecord != hEntity )
1424
DBFFlushRecord( psDBF );
1426
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1428
fseek( psDBF->fp, nRecordOffset, 0 );
1429
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1431
psDBF->nCurrentRecord = hEntity;
1434
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1436
memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength );
1438
psDBF->bCurrentRecordModified = TRUE;
1439
psDBF->bUpdated = TRUE;
1444
1444
/************************************************************************/
1451
1451
DBFReadTuple(DBFHandle psDBF, int hEntity )
1455
unsigned char *pabyRec;
1456
static char *pReturnTuple = NULL;
1458
static int nTupleLen = 0;
1460
/* -------------------------------------------------------------------- */
1461
/* Have we read the record? */
1462
/* -------------------------------------------------------------------- */
1463
if( hEntity < 0 || hEntity >= psDBF->nRecords )
1466
if( psDBF->nCurrentRecord != hEntity )
1468
DBFFlushRecord( psDBF );
1470
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1472
fseek( psDBF->fp, nRecordOffset, 0 );
1473
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1475
psDBF->nCurrentRecord = hEntity;
1478
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1480
if ( nTupleLen < psDBF->nRecordLength) {
1481
nTupleLen = psDBF->nRecordLength;
1482
pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
1485
memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
1487
return( pReturnTuple );
1455
unsigned char *pabyRec;
1456
static char *pReturnTuple = NULL;
1458
static int nTupleLen = 0;
1460
/* -------------------------------------------------------------------- */
1461
/* Have we read the record? */
1462
/* -------------------------------------------------------------------- */
1463
if ( hEntity < 0 || hEntity >= psDBF->nRecords )
1466
if ( psDBF->nCurrentRecord != hEntity )
1468
DBFFlushRecord( psDBF );
1470
nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1472
fseek( psDBF->fp, nRecordOffset, 0 );
1473
fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1475
psDBF->nCurrentRecord = hEntity;
1478
pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1480
if ( nTupleLen < psDBF->nRecordLength)
1482
nTupleLen = psDBF->nRecordLength;
1483
pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
1486
memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
1488
return( pReturnTuple );
1490
1491
/************************************************************************/
1494
1495
/************************************************************************/
1496
1497
DBFHandle SHPAPI_CALL
1497
DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
1498
DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
1501
newDBF = DBFCreate ( pszFilename );
1502
if ( newDBF == NULL ) return ( NULL );
1504
newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
1505
memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
1507
newDBF->nFields = psDBF->nFields;
1508
newDBF->nRecordLength = psDBF->nRecordLength;
1509
newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
1511
newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields );
1512
memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
1513
newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
1514
memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
1515
newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
1516
memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
1517
newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields );
1518
memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );
1520
newDBF->bNoHeader = TRUE;
1521
newDBF->bUpdated = TRUE;
1523
DBFWriteHeader ( newDBF );
1524
DBFClose ( newDBF );
1526
newDBF = DBFOpen ( pszFilename, "rb+" );
1502
newDBF = DBFCreate ( pszFilename );
1503
if ( newDBF == NULL ) return ( NULL );
1505
newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
1506
memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
1508
newDBF->nFields = psDBF->nFields;
1509
newDBF->nRecordLength = psDBF->nRecordLength;
1510
newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
1512
newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields );
1513
memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
1514
newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
1515
memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
1516
newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
1517
memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
1518
newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields );
1519
memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );
1521
newDBF->bNoHeader = TRUE;
1522
newDBF->bUpdated = TRUE;
1524
DBFWriteHeader ( newDBF );
1525
DBFClose ( newDBF );
1527
newDBF = DBFOpen ( pszFilename, "rb+" );
1531
1532
/************************************************************************/