~ubuntu-branches/ubuntu/trusty/postgis/trusty-security

« back to all changes in this revision

Viewing changes to loader/dbfopen.c

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Paolo Lovergine
  • Date: 2009-12-11 13:10:34 UTC
  • mfrom: (1.1.9 upstream) (5.2.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20091211131034-wmsz69wxvt95pe5r
Tags: 1.4.0-2
* Upload to unstable.
* Better parameterized debian/rules against postgis $(VERSION).
* Added dblatex and libcunit1-dev among build-deps.
* Added postgis_comments.sql to contrib/ SQL templates.
* Dropping 8.3 support, no more supported for squeeze.
  (closes: #559587)
* Do not stop on error in postrm if the target dir does not exist.
  (closes: #560409)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/******************************************************************************
2
 
 * $Id: dbfopen.c 3748 2009-02-19 20:58:15Z pramsey $
 
2
 * $Id: dbfopen.c 4168 2009-06-11 16:44:03Z pramsey $
3
3
 *
4
4
 * Project:  Shapelib
5
5
 * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
13
13
 * option is discussed in more detail in shapelib.html.
14
14
 *
15
15
 * --
16
 
 * 
 
16
 *
17
17
 * Permission is hereby granted, free of charge, to any person obtaining a
18
18
 * copy of this software and associated documentation files (the "Software"),
19
19
 * to deal in the Software without restriction, including without limitation
203
203
 * Added header.
204
204
 */
205
205
 
206
 
static char rcsid[] = 
207
 
  "$Id: dbfopen.c 3748 2009-02-19 20:58:15Z pramsey $";
208
 
 
209
206
#include "shapefil.h"
210
207
 
211
208
#include <math.h>
231
228
static void * SfRealloc( void * pMem, int nNewSize )
232
229
 
233
230
{
234
 
    if( pMem == NULL )
235
 
        return( (void *) malloc(nNewSize) );
236
 
    else
237
 
        return( (void *) realloc(pMem,nNewSize) );
 
231
        if ( pMem == NULL )
 
232
                return( (void *) malloc(nNewSize) );
 
233
        else
 
234
                return( (void *) realloc(pMem,nNewSize) );
238
235
}
239
236
 
240
237
/************************************************************************/
249
246
static void DBFWriteHeader(DBFHandle psDBF)
250
247
 
251
248
{
252
 
    unsigned char       abyHeader[XBASE_FLDHDR_SZ];
253
 
    int         i;
254
 
 
255
 
    if( !psDBF->bNoHeader )
256
 
        return;
257
 
 
258
 
    psDBF->bNoHeader = FALSE;
259
 
 
260
 
/* -------------------------------------------------------------------- */
261
 
/*      Initialize the file header information.                         */
262
 
/* -------------------------------------------------------------------- */
263
 
    for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
264
 
        abyHeader[i] = 0;
265
 
 
266
 
    abyHeader[0] = 0x03;                /* memo field? - just copying   */
267
 
 
268
 
    /* write out a dummy date */
269
 
    abyHeader[1] = 95;                  /* YY */
270
 
    abyHeader[2] = 7;                   /* MM */
271
 
    abyHeader[3] = 26;                  /* DD */
272
 
 
273
 
    /* record count preset at zero */
274
 
 
275
 
    abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
276
 
    abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
277
 
    
278
 
    abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
279
 
    abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
280
 
 
281
 
/* -------------------------------------------------------------------- */
282
 
/*      Write the initial 32 byte file header, and all the field        */
283
 
/*      descriptions.                                                   */
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 );
288
 
 
289
 
/* -------------------------------------------------------------------- */
290
 
/*      Write out the newline character if there is room for it.        */
291
 
/* -------------------------------------------------------------------- */
292
 
    if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
293
 
    {
294
 
        char    cNewline;
295
 
 
296
 
        cNewline = 0x0d;
297
 
        fwrite( &cNewline, 1, 1, psDBF->fp );
298
 
    }
 
249
        unsigned char   abyHeader[XBASE_FLDHDR_SZ];
 
250
        int             i;
 
251
 
 
252
        if ( !psDBF->bNoHeader )
 
253
                return;
 
254
 
 
255
        psDBF->bNoHeader = FALSE;
 
256
 
 
257
        /* -------------------------------------------------------------------- */
 
258
        /*      Initialize the file header information.                         */
 
259
        /* -------------------------------------------------------------------- */
 
260
        for ( i = 0; i < XBASE_FLDHDR_SZ; i++ )
 
261
                abyHeader[i] = 0;
 
262
 
 
263
        abyHeader[0] = 0x03;            /* memo field? - just copying   */
 
264
 
 
265
        /* write out a dummy date */
 
266
        abyHeader[1] = 95;                      /* YY */
 
267
        abyHeader[2] = 7;                       /* MM */
 
268
        abyHeader[3] = 26;                      /* DD */
 
269
 
 
270
        /* record count preset at zero */
 
271
 
 
272
        abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
 
273
        abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
 
274
 
 
275
        abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
 
276
        abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
 
277
 
 
278
        /* -------------------------------------------------------------------- */
 
279
        /*      Write the initial 32 byte file header, and all the field        */
 
280
        /*      descriptions.                                                   */
 
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 );
 
285
 
 
286
        /* -------------------------------------------------------------------- */
 
287
        /*      Write out the newline character if there is room for it.        */
 
288
        /* -------------------------------------------------------------------- */
 
289
        if ( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )
 
290
        {
 
291
                char    cNewline;
 
292
 
 
293
                cNewline = 0x0d;
 
294
                fwrite( &cNewline, 1, 1, psDBF->fp );
 
295
        }
299
296
}
300
297
 
301
298
/************************************************************************/
307
304
static void DBFFlushRecord( DBFHandle psDBF )
308
305
 
309
306
{
310
 
    int         nRecordOffset;
311
 
 
312
 
    if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
313
 
    {
314
 
        psDBF->bCurrentRecordModified = FALSE;
315
 
 
316
 
        nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord 
317
 
                                                     + psDBF->nHeaderLength;
318
 
 
319
 
        fseek( psDBF->fp, nRecordOffset, 0 );
320
 
        fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
321
 
    }
 
307
        int             nRecordOffset;
 
308
 
 
309
        if ( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )
 
310
        {
 
311
                psDBF->bCurrentRecordModified = FALSE;
 
312
 
 
313
                nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord
 
314
                                + psDBF->nHeaderLength;
 
315
 
 
316
                fseek( psDBF->fp, nRecordOffset, 0 );
 
317
                fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
 
318
        }
322
319
}
323
320
 
324
321
/************************************************************************/
329
326
DBFUpdateHeader( DBFHandle psDBF )
330
327
 
331
328
{
332
 
    unsigned char               abyFileHeader[32];
333
 
 
334
 
    if( psDBF->bNoHeader )
335
 
        DBFWriteHeader( psDBF );
336
 
 
337
 
    DBFFlushRecord( psDBF );
338
 
 
339
 
    fseek( psDBF->fp, 0, 0 );
340
 
    fread( abyFileHeader, 32, 1, psDBF->fp );
341
 
    
342
 
    abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
343
 
    abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
344
 
    abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
345
 
    abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
346
 
    
347
 
    fseek( psDBF->fp, 0, 0 );
348
 
    fwrite( abyFileHeader, 32, 1, psDBF->fp );
349
 
 
350
 
    fflush( psDBF->fp );
 
329
        unsigned char           abyFileHeader[32];
 
330
 
 
331
        if ( psDBF->bNoHeader )
 
332
                DBFWriteHeader( psDBF );
 
333
 
 
334
        DBFFlushRecord( psDBF );
 
335
 
 
336
        fseek( psDBF->fp, 0, 0 );
 
337
        fread( abyFileHeader, 32, 1, psDBF->fp );
 
338
 
 
339
        abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
 
340
        abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
 
341
        abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
 
342
        abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
 
343
 
 
344
        fseek( psDBF->fp, 0, 0 );
 
345
        fwrite( abyFileHeader, 32, 1, psDBF->fp );
 
346
 
 
347
        fflush( psDBF->fp );
351
348
}
352
349
 
353
350
/************************************************************************/
355
352
/*                                                                      */
356
353
/*      Open a .dbf file.                                               */
357
354
/************************************************************************/
358
 
   
 
355
 
359
356
DBFHandle SHPAPI_CALL
360
357
DBFOpen( const char * pszFilename, const char * pszAccess )
361
358
 
362
359
{
363
 
    DBFHandle           psDBF;
364
 
    unsigned char               *pabyBuf;
365
 
    int                 nFields, nHeadLen, nRecLen, iField, i;
366
 
    char                *pszBasename, *pszFullname;
367
 
 
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 )
374
 
        return( NULL );
375
 
 
376
 
    if( strcmp(pszAccess,"r") == 0 )
377
 
        pszAccess = "rb";
378
 
 
379
 
    if( strcmp(pszAccess,"r+") == 0 )
380
 
        pszAccess = "rb+";
381
 
 
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] != '\\';
391
 
         i-- ) {}
392
 
 
393
 
    if( pszBasename[i] == '.' )
394
 
        pszBasename[i] = '\0';
395
 
 
396
 
    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
397
 
    sprintf( pszFullname, "%s.dbf", pszBasename );
398
 
        
399
 
    psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
400
 
    psDBF->fp = fopen( pszFullname, pszAccess );
401
 
 
402
 
    if( psDBF->fp == NULL )
403
 
    {
404
 
        sprintf( pszFullname, "%s.DBF", pszBasename );
405
 
        psDBF->fp = fopen(pszFullname, pszAccess );
406
 
    }
407
 
    
408
 
    free( pszBasename );
409
 
    free( pszFullname );
410
 
    
411
 
    if( psDBF->fp == NULL )
412
 
    {
413
 
        free( psDBF );
414
 
        return( NULL );
415
 
    }
416
 
 
417
 
    psDBF->bNoHeader = FALSE;
418
 
    psDBF->nCurrentRecord = -1;
419
 
    psDBF->bCurrentRecordModified = FALSE;
420
 
 
421
 
/* -------------------------------------------------------------------- */
422
 
/*  Read Table Header info                                              */
423
 
/* -------------------------------------------------------------------- */
424
 
    pabyBuf = (unsigned char *) malloc(500);
425
 
    if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
426
 
    {
427
 
        fclose( psDBF->fp );
428
 
        free( pabyBuf );
429
 
        free( psDBF );
430
 
        return NULL;
431
 
    }
432
 
 
433
 
    psDBF->nRecords = 
434
 
     pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
435
 
 
436
 
    psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
437
 
    psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
438
 
    
439
 
    psDBF->nFields = nFields = (nHeadLen - 32) / 32;
440
 
 
441
 
    psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
442
 
 
443
 
/* -------------------------------------------------------------------- */
444
 
/*  Read in Field Definitions                                           */
445
 
/* -------------------------------------------------------------------- */
446
 
    
447
 
    pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
448
 
    psDBF->pszHeader = (char *) pabyBuf;
449
 
 
450
 
    fseek( psDBF->fp, 32, 0 );
451
 
    if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
452
 
    {
453
 
        fclose( psDBF->fp );
454
 
        free( pabyBuf );
455
 
        free( psDBF );
456
 
        return NULL;
457
 
    }
458
 
 
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);
463
 
 
464
 
    for( iField = 0; iField < nFields; iField++ )
465
 
    {
466
 
        unsigned char           *pabyFInfo;
467
 
 
468
 
        pabyFInfo = pabyBuf+iField*32;
469
 
 
470
 
        if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
471
 
        {
472
 
            psDBF->panFieldSize[iField] = pabyFInfo[16];
473
 
            psDBF->panFieldDecimals[iField] = pabyFInfo[17];
474
 
        }
475
 
        else
476
 
        {
477
 
            psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
478
 
            psDBF->panFieldDecimals[iField] = 0;
479
 
        }
480
 
 
481
 
        psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
482
 
        if( iField == 0 )
483
 
            psDBF->panFieldOffset[iField] = 1;
484
 
        else
485
 
            psDBF->panFieldOffset[iField] = 
486
 
              psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
487
 
    }
488
 
 
489
 
    return( psDBF );
 
360
        DBFHandle               psDBF;
 
361
        unsigned char           *pabyBuf;
 
362
        int                     nFields, nHeadLen, nRecLen, iField, i;
 
363
        char            *pszBasename, *pszFullname;
 
364
 
 
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 )
 
371
                return( NULL );
 
372
 
 
373
        if ( strcmp(pszAccess,"r") == 0 )
 
374
                pszAccess = "rb";
 
375
 
 
376
        if ( strcmp(pszAccess,"r+") == 0 )
 
377
                pszAccess = "rb+";
 
378
 
 
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] != '\\';
 
388
                i-- )
 
389
        {}
 
390
 
 
391
        if ( pszBasename[i] == '.' )
 
392
                pszBasename[i] = '\0';
 
393
 
 
394
        pszFullname = (char *) malloc(strlen(pszBasename) + 5);
 
395
        sprintf( pszFullname, "%s.dbf", pszBasename );
 
396
 
 
397
        psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
 
398
        psDBF->fp = fopen( pszFullname, pszAccess );
 
399
 
 
400
        if ( psDBF->fp == NULL )
 
401
        {
 
402
                sprintf( pszFullname, "%s.DBF", pszBasename );
 
403
                psDBF->fp = fopen(pszFullname, pszAccess );
 
404
        }
 
405
 
 
406
        free( pszBasename );
 
407
        free( pszFullname );
 
408
 
 
409
        if ( psDBF->fp == NULL )
 
410
        {
 
411
                free( psDBF );
 
412
                return( NULL );
 
413
        }
 
414
 
 
415
        psDBF->bNoHeader = FALSE;
 
416
        psDBF->nCurrentRecord = -1;
 
417
        psDBF->bCurrentRecordModified = FALSE;
 
418
 
 
419
        /* -------------------------------------------------------------------- */
 
420
        /*  Read Table Header info                                              */
 
421
        /* -------------------------------------------------------------------- */
 
422
        pabyBuf = (unsigned char *) malloc(500);
 
423
        if ( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
 
424
        {
 
425
                fclose( psDBF->fp );
 
426
                free( pabyBuf );
 
427
                free( psDBF );
 
428
                return NULL;
 
429
        }
 
430
 
 
431
        psDBF->nRecords =
 
432
            pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
 
433
 
 
434
        psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
 
435
        psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
 
436
 
 
437
        psDBF->nFields = nFields = (nHeadLen - 32) / 32;
 
438
 
 
439
        psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
 
440
 
 
441
        /* -------------------------------------------------------------------- */
 
442
        /*  Read in Field Definitions                                           */
 
443
        /* -------------------------------------------------------------------- */
 
444
 
 
445
        pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen);
 
446
        psDBF->pszHeader = (char *) pabyBuf;
 
447
 
 
448
        fseek( psDBF->fp, 32, 0 );
 
449
        if ( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
 
450
        {
 
451
                fclose( psDBF->fp );
 
452
                free( pabyBuf );
 
453
                free( psDBF );
 
454
                return NULL;
 
455
        }
 
456
 
 
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);
 
461
 
 
462
        for ( iField = 0; iField < nFields; iField++ )
 
463
        {
 
464
                unsigned char           *pabyFInfo;
 
465
 
 
466
                pabyFInfo = pabyBuf+iField*32;
 
467
 
 
468
                if ( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' )
 
469
                {
 
470
                        psDBF->panFieldSize[iField] = pabyFInfo[16];
 
471
                        psDBF->panFieldDecimals[iField] = pabyFInfo[17];
 
472
                }
 
473
                else
 
474
                {
 
475
                        psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256;
 
476
                        psDBF->panFieldDecimals[iField] = 0;
 
477
                }
 
478
 
 
479
                psDBF->pachFieldType[iField] = (char) pabyFInfo[11];
 
480
                if ( iField == 0 )
 
481
                        psDBF->panFieldOffset[iField] = 1;
 
482
                else
 
483
                        psDBF->panFieldOffset[iField] =
 
484
                            psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1];
 
485
        }
 
486
 
 
487
        return( psDBF );
490
488
}
491
489
 
492
490
/************************************************************************/
496
494
void SHPAPI_CALL
497
495
DBFClose(DBFHandle psDBF)
498
496
{
499
 
    static char eof = 0x1a;
500
 
    char eof_test;
501
 
    
502
 
/* -------------------------------------------------------------------- */
503
 
/*      Write out header if not already written.                        */
504
 
/* -------------------------------------------------------------------- */
505
 
    if( psDBF->bNoHeader )
506
 
        DBFWriteHeader( psDBF );
507
 
 
508
 
    DBFFlushRecord( psDBF );
509
 
 
510
 
/* -------------------------------------------------------------------- */
511
 
/*      Update last access date, and number of records if we have       */
512
 
/*      write access.                                                   */
513
 
/* -------------------------------------------------------------------- */
514
 
    if( psDBF->bUpdated )
515
 
        DBFUpdateHeader( psDBF );
516
 
 
517
 
/* -------------------------------------------------------------------- */
518
 
/*  Add the DBF end-of-file marker after the last record.               */
519
 
/* -------------------------------------------------------------------- */
520
 
 
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 */
524
 
    {
525
 
        fseek(psDBF->fp, 0, SEEK_END);
526
 
        fwrite(&eof, 1, 1, psDBF->fp);
527
 
    }
528
 
 
529
 
/* -------------------------------------------------------------------- */
530
 
/*      Close, and free resources.                                      */
531
 
/* -------------------------------------------------------------------- */
532
 
    fclose( psDBF->fp );
533
 
 
534
 
    if( psDBF->panFieldOffset != NULL )
535
 
    {
536
 
        free( psDBF->panFieldOffset );
537
 
        free( psDBF->panFieldSize );
538
 
        free( psDBF->panFieldDecimals );
539
 
        free( psDBF->pachFieldType );
540
 
    }
541
 
 
542
 
    free( psDBF->pszHeader );
543
 
    free( psDBF->pszCurrentRecord );
544
 
 
545
 
    free( psDBF );
546
 
 
547
 
    if( pszStringField != NULL )
548
 
    {
549
 
        free( pszStringField );
550
 
        pszStringField = NULL;
551
 
        nStringFieldLen = 0;
552
 
    }
 
497
        static char eof = 0x1a;
 
498
        char eof_test;
 
499
 
 
500
        /* -------------------------------------------------------------------- */
 
501
        /*      Write out header if not already written.                        */
 
502
        /* -------------------------------------------------------------------- */
 
503
        if ( psDBF->bNoHeader )
 
504
                DBFWriteHeader( psDBF );
 
505
 
 
506
        DBFFlushRecord( psDBF );
 
507
 
 
508
        /* -------------------------------------------------------------------- */
 
509
        /*      Update last access date, and number of records if we have       */
 
510
        /*      write access.                                                   */
 
511
        /* -------------------------------------------------------------------- */
 
512
        if ( psDBF->bUpdated )
 
513
                DBFUpdateHeader( psDBF );
 
514
 
 
515
        /* -------------------------------------------------------------------- */
 
516
        /*  Add the DBF end-of-file marker after the last record.               */
 
517
        /* -------------------------------------------------------------------- */
 
518
 
 
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 */
 
522
        {
 
523
                fseek(psDBF->fp, 0, SEEK_END);
 
524
                fwrite(&eof, 1, 1, psDBF->fp);
 
525
        }
 
526
 
 
527
        /* -------------------------------------------------------------------- */
 
528
        /*      Close, and free resources.                                      */
 
529
        /* -------------------------------------------------------------------- */
 
530
        fclose( psDBF->fp );
 
531
 
 
532
        if ( psDBF->panFieldOffset != NULL )
 
533
        {
 
534
                free( psDBF->panFieldOffset );
 
535
                free( psDBF->panFieldSize );
 
536
                free( psDBF->panFieldDecimals );
 
537
                free( psDBF->pachFieldType );
 
538
        }
 
539
 
 
540
        free( psDBF->pszHeader );
 
541
        free( psDBF->pszCurrentRecord );
 
542
 
 
543
        free( psDBF );
 
544
 
 
545
        if ( pszStringField != NULL )
 
546
        {
 
547
                free( pszStringField );
 
548
                pszStringField = NULL;
 
549
                nStringFieldLen = 0;
 
550
        }
553
551
}
554
552
 
555
553
/************************************************************************/
562
560
DBFCreate( const char * pszFilename )
563
561
 
564
562
{
565
 
    DBFHandle   psDBF;
566
 
    FILE        *fp;
567
 
    char        *pszFullname, *pszBasename;
568
 
    int         i;
569
 
 
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] != '\\';
579
 
         i-- ) {}
580
 
 
581
 
    if( pszBasename[i] == '.' )
582
 
        pszBasename[i] = '\0';
583
 
 
584
 
    pszFullname = (char *) malloc(strlen(pszBasename) + 5);
585
 
    sprintf( pszFullname, "%s.dbf", pszBasename );
586
 
    free( pszBasename );
587
 
 
588
 
/* -------------------------------------------------------------------- */
589
 
/*      Create the file.                                                */
590
 
/* -------------------------------------------------------------------- */
591
 
    fp = fopen( pszFullname, "wb" );
592
 
    if( fp == NULL )
593
 
        return( NULL );
594
 
 
595
 
    fputc( 0, fp );
596
 
    fclose( fp );
597
 
 
598
 
    fp = fopen( pszFullname, "rb+" );
599
 
    if( fp == NULL )
600
 
        return( NULL );
601
 
 
602
 
    free( pszFullname );
603
 
 
604
 
/* -------------------------------------------------------------------- */
605
 
/*      Create the info structure.                                      */
606
 
/* -------------------------------------------------------------------- */
607
 
    psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
608
 
 
609
 
    psDBF->fp = fp;
610
 
    psDBF->nRecords = 0;
611
 
    psDBF->nFields = 0;
612
 
    psDBF->nRecordLength = 1;
613
 
    psDBF->nHeaderLength = 33;
614
 
    psDBF->bUpdated = FALSE;
615
 
    
616
 
    psDBF->panFieldOffset = NULL;
617
 
    psDBF->panFieldSize = NULL;
618
 
    psDBF->panFieldDecimals = NULL;
619
 
    psDBF->pachFieldType = NULL;
620
 
    psDBF->pszHeader = NULL;
621
 
 
622
 
    psDBF->nCurrentRecord = -1;
623
 
    psDBF->bCurrentRecordModified = FALSE;
624
 
    psDBF->pszCurrentRecord = NULL;
625
 
 
626
 
    psDBF->bNoHeader = TRUE;
627
 
 
628
 
    return( psDBF );
 
563
        DBFHandle       psDBF;
 
564
        FILE    *fp;
 
565
        char    *pszFullname, *pszBasename;
 
566
        int             i;
 
567
 
 
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] != '\\';
 
577
                i-- )
 
578
        {}
 
579
 
 
580
        if ( pszBasename[i] == '.' )
 
581
                pszBasename[i] = '\0';
 
582
 
 
583
        pszFullname = (char *) malloc(strlen(pszBasename) + 5);
 
584
        sprintf( pszFullname, "%s.dbf", pszBasename );
 
585
        free( pszBasename );
 
586
 
 
587
        /* -------------------------------------------------------------------- */
 
588
        /*      Create the file.                                                */
 
589
        /* -------------------------------------------------------------------- */
 
590
        fp = fopen( pszFullname, "wb" );
 
591
        if ( fp == NULL )
 
592
                return( NULL );
 
593
 
 
594
        fputc( 0, fp );
 
595
        fclose( fp );
 
596
 
 
597
        fp = fopen( pszFullname, "rb+" );
 
598
        if ( fp == NULL )
 
599
                return( NULL );
 
600
 
 
601
        free( pszFullname );
 
602
 
 
603
        /* -------------------------------------------------------------------- */
 
604
        /*      Create the info structure.                                      */
 
605
        /* -------------------------------------------------------------------- */
 
606
        psDBF = (DBFHandle) malloc(sizeof(DBFInfo));
 
607
 
 
608
        psDBF->fp = fp;
 
609
        psDBF->nRecords = 0;
 
610
        psDBF->nFields = 0;
 
611
        psDBF->nRecordLength = 1;
 
612
        psDBF->nHeaderLength = 33;
 
613
        psDBF->bUpdated = FALSE;
 
614
 
 
615
        psDBF->panFieldOffset = NULL;
 
616
        psDBF->panFieldSize = NULL;
 
617
        psDBF->panFieldDecimals = NULL;
 
618
        psDBF->pachFieldType = NULL;
 
619
        psDBF->pszHeader = NULL;
 
620
 
 
621
        psDBF->nCurrentRecord = -1;
 
622
        psDBF->bCurrentRecordModified = FALSE;
 
623
        psDBF->pszCurrentRecord = NULL;
 
624
 
 
625
        psDBF->bNoHeader = TRUE;
 
626
 
 
627
        return( psDBF );
629
628
}
630
629
 
631
630
/************************************************************************/
636
635
/************************************************************************/
637
636
 
638
637
int SHPAPI_CALL
639
 
DBFAddField(DBFHandle psDBF, const char * pszFieldName, 
 
638
DBFAddField(DBFHandle psDBF, const char * pszFieldName,
640
639
            DBFFieldType eType, int nWidth, int nDecimals )
641
640
 
642
641
{
643
 
    char        *pszFInfo;
644
 
    int         i;
645
 
 
646
 
/* -------------------------------------------------------------------- */
647
 
/*      Do some checking to ensure we can add records to this file.     */
648
 
/* -------------------------------------------------------------------- */
649
 
    if( psDBF->nRecords > 0 )
650
 
        return( -1 );
651
 
 
652
 
    if( !psDBF->bNoHeader )
653
 
        return( -1 );
654
 
 
655
 
    if( eType != FTDouble && nDecimals != 0 )
656
 
        return( -1 );
657
 
 
658
 
    if( nWidth < 1 )
659
 
        return -1;
660
 
 
661
 
/* -------------------------------------------------------------------- */
662
 
/*      SfRealloc all the arrays larger to hold the additional field      */
663
 
/*      information.                                                    */
664
 
/* -------------------------------------------------------------------- */
665
 
    psDBF->nFields++;
666
 
 
667
 
    psDBF->panFieldOffset = (int *) 
668
 
      SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
669
 
 
670
 
    psDBF->panFieldSize = (int *) 
671
 
      SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
672
 
 
673
 
    psDBF->panFieldDecimals = (int *) 
674
 
      SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
675
 
 
676
 
    psDBF->pachFieldType = (char *) 
677
 
      SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
678
 
 
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;
686
 
 
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';
693
 
    else
694
 
        psDBF->pachFieldType[psDBF->nFields-1] = 'N';
695
 
 
696
 
/* -------------------------------------------------------------------- */
697
 
/*      Extend the required header information.                         */
698
 
/* -------------------------------------------------------------------- */
699
 
    psDBF->nHeaderLength += 32;
700
 
    psDBF->bUpdated = FALSE;
701
 
 
702
 
    psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
703
 
 
704
 
    pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
705
 
 
706
 
    for( i = 0; i < 32; i++ )
707
 
        pszFInfo[i] = '\0';
708
 
 
709
 
    if( (int) strlen(pszFieldName) < 10 )
710
 
        strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
711
 
    else
712
 
        strncpy( pszFInfo, pszFieldName, 10);
713
 
 
714
 
    pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
715
 
 
716
 
    if( eType == FTString )
717
 
    {
718
 
        pszFInfo[16] = (unsigned char) (nWidth % 256);
719
 
        pszFInfo[17] = (unsigned char) (nWidth / 256);
720
 
    }
721
 
    else
722
 
    {
723
 
        pszFInfo[16] = (unsigned char) nWidth;
724
 
        pszFInfo[17] = (unsigned char) nDecimals;
725
 
    }
726
 
    
727
 
/* -------------------------------------------------------------------- */
728
 
/*      Make the current record buffer appropriately larger.            */
729
 
/* -------------------------------------------------------------------- */
730
 
    psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
731
 
                                               psDBF->nRecordLength);
732
 
 
733
 
    return( psDBF->nFields-1 );
 
642
        char    *pszFInfo;
 
643
        int             i;
 
644
 
 
645
        /* -------------------------------------------------------------------- */
 
646
        /*      Do some checking to ensure we can add records to this file.     */
 
647
        /* -------------------------------------------------------------------- */
 
648
        if ( psDBF->nRecords > 0 )
 
649
                return( -1 );
 
650
 
 
651
        if ( !psDBF->bNoHeader )
 
652
                return( -1 );
 
653
 
 
654
        if ( eType != FTDouble && nDecimals != 0 )
 
655
                return( -1 );
 
656
 
 
657
        if ( nWidth < 1 )
 
658
                return -1;
 
659
 
 
660
        /* -------------------------------------------------------------------- */
 
661
        /*      SfRealloc all the arrays larger to hold the additional field      */
 
662
        /*      information.                                                    */
 
663
        /* -------------------------------------------------------------------- */
 
664
        psDBF->nFields++;
 
665
 
 
666
        psDBF->panFieldOffset = (int *)
 
667
                                SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
 
668
 
 
669
        psDBF->panFieldSize = (int *)
 
670
                              SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
 
671
 
 
672
        psDBF->panFieldDecimals = (int *)
 
673
                                  SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
 
674
 
 
675
        psDBF->pachFieldType = (char *)
 
676
                               SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
 
677
 
 
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;
 
685
 
 
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';
 
692
        else
 
693
                psDBF->pachFieldType[psDBF->nFields-1] = 'N';
 
694
 
 
695
        /* -------------------------------------------------------------------- */
 
696
        /*      Extend the required header information.                         */
 
697
        /* -------------------------------------------------------------------- */
 
698
        psDBF->nHeaderLength += 32;
 
699
        psDBF->bUpdated = FALSE;
 
700
 
 
701
        psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
 
702
 
 
703
        pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
 
704
 
 
705
        for ( i = 0; i < 32; i++ )
 
706
                pszFInfo[i] = '\0';
 
707
 
 
708
        if ( (int) strlen(pszFieldName) < 10 )
 
709
                strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
 
710
        else
 
711
                strncpy( pszFInfo, pszFieldName, 10);
 
712
 
 
713
        pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
 
714
 
 
715
        if ( eType == FTString )
 
716
        {
 
717
                pszFInfo[16] = (unsigned char) (nWidth % 256);
 
718
                pszFInfo[17] = (unsigned char) (nWidth / 256);
 
719
        }
 
720
        else
 
721
        {
 
722
                pszFInfo[16] = (unsigned char) nWidth;
 
723
                pszFInfo[17] = (unsigned char) nDecimals;
 
724
        }
 
725
 
 
726
        /* -------------------------------------------------------------------- */
 
727
        /*      Make the current record buffer appropriately larger.            */
 
728
        /* -------------------------------------------------------------------- */
 
729
        psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
 
730
                                  psDBF->nRecordLength);
 
731
 
 
732
        return( psDBF->nFields-1 );
734
733
}
735
734
 
736
735
 
740
739
/*      Prep a record for reading.                                      */
741
740
/************************************************************************/
742
741
 
743
 
int DBFReadSetup(DBFHandle psDBF, int hEntity) 
 
742
int DBFReadSetup(DBFHandle psDBF, int hEntity)
744
743
{
745
 
    int         nRecordOffset;
746
 
 
747
 
/* -------------------------------------------------------------------- */
748
 
/*      Verify selection.                                               */
749
 
/* -------------------------------------------------------------------- */
750
 
    if( hEntity < 0 || hEntity >= psDBF->nRecords )
751
 
        return( 0 );
752
 
 
753
 
/* -------------------------------------------------------------------- */
754
 
/*      Have we read the record?                                        */
755
 
/* -------------------------------------------------------------------- */
756
 
    if( psDBF->nCurrentRecord != hEntity )
757
 
    {
758
 
        DBFFlushRecord( psDBF );
759
 
 
760
 
        nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
761
 
 
762
 
        if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
763
 
        {
764
 
            fprintf( stderr, "fseek(%d) failed on DBF file.\n",
765
 
                     nRecordOffset );
766
 
            return 0;
767
 
        }
768
 
 
769
 
        if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 
770
 
                   1, psDBF->fp ) != 1 )
771
 
        {
772
 
            fprintf( stderr, "fread(%d) failed on DBF file.\n",
773
 
                     psDBF->nRecordLength );
774
 
            return 0;
775
 
        }
776
 
 
777
 
        psDBF->nCurrentRecord = hEntity;
778
 
    }
779
 
    
780
 
    return 1;
 
744
        int             nRecordOffset;
 
745
 
 
746
        /* -------------------------------------------------------------------- */
 
747
        /*      Verify selection.                                               */
 
748
        /* -------------------------------------------------------------------- */
 
749
        if ( hEntity < 0 || hEntity >= psDBF->nRecords )
 
750
                return( 0 );
 
751
 
 
752
        /* -------------------------------------------------------------------- */
 
753
        /*      Have we read the record?                                        */
 
754
        /* -------------------------------------------------------------------- */
 
755
        if ( psDBF->nCurrentRecord != hEntity )
 
756
        {
 
757
                DBFFlushRecord( psDBF );
 
758
 
 
759
                nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
 
760
 
 
761
                if ( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )
 
762
                {
 
763
                        fprintf( stderr, "fseek(%d) failed on DBF file.\n",
 
764
                                 nRecordOffset );
 
765
                        return 0;
 
766
                }
 
767
 
 
768
                if ( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,
 
769
                            1, psDBF->fp ) != 1 )
 
770
                {
 
771
                        fprintf( stderr, "fread(%d) failed on DBF file.\n",
 
772
                                 psDBF->nRecordLength );
 
773
                        return 0;
 
774
                }
 
775
 
 
776
                psDBF->nCurrentRecord = hEntity;
 
777
        }
 
778
 
 
779
        return 1;
781
780
 
782
781
}
783
782
 
790
789
 
791
790
int DBFReadDeleted(DBFHandle psDBF, int hEntity)
792
791
{
793
 
  unsigned char *pabyRec;
794
 
  
795
 
  if( ! DBFReadSetup( psDBF, hEntity) )
796
 
    return 0;
797
 
 
798
 
  /* get reference to current record */
799
 
  pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
800
 
 
801
 
  /* 0x20 => not deleted, 0x24 => deleted */
802
 
  return *pabyRec == 0x20 ? 0 : 1;
 
792
        unsigned char   *pabyRec;
 
793
 
 
794
        if ( ! DBFReadSetup( psDBF, hEntity) )
 
795
                return 0;
 
796
 
 
797
        /* get reference to current record */
 
798
        pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
799
 
 
800
        /* 0x20 => not deleted, 0x24 => deleted */
 
801
        return *pabyRec == 0x20 ? 0 : 1;
 
802
 
803
803
}
804
804
 
805
805
/************************************************************************/
812
812
                              char chReqType )
813
813
 
814
814
{
815
 
    unsigned char       *pabyRec;
816
 
    void        *pReturnField = NULL;
817
 
 
818
 
    static double dDoubleField;
819
 
 
820
 
/* -------------------------------------------------------------------- */
821
 
/*      Verify selection.                                               */
822
 
/* -------------------------------------------------------------------- */
823
 
    if( iField < 0 || iField >= psDBF->nFields )
824
 
        return( NULL );
825
 
 
826
 
    if( ! DBFReadSetup( psDBF, hEntity) )
827
 
      return( NULL );
828
 
 
829
 
    /* get reference to current record */
830
 
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
831
 
 
832
 
/* -------------------------------------------------------------------- */
833
 
/*      Ensure our field buffer is large enough to hold this buffer.          */
834
 
/* -------------------------------------------------------------------- */
835
 
    if( psDBF->panFieldSize[iField]+1 > nStringFieldLen )
836
 
    {
837
 
            nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10;
838
 
            pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen);
839
 
    }
840
 
 
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';
848
 
 
849
 
    pReturnField = pszStringField;
850
 
 
851
 
/* -------------------------------------------------------------------- */
852
 
/*      Decode the field.                                               */
853
 
/* -------------------------------------------------------------------- */
854
 
    if( chReqType == 'N' )
855
 
    {
856
 
      dDoubleField = atof(pszStringField);
857
 
      pReturnField = &dDoubleField;
858
 
    }
859
 
 
860
 
/* -------------------------------------------------------------------- */
861
 
/*      Should we trim white space off the string attribute value?      */
862
 
/* -------------------------------------------------------------------- */
 
815
        unsigned char   *pabyRec;
 
816
        void    *pReturnField = NULL;
 
817
 
 
818
        static double dDoubleField;
 
819
 
 
820
        /* -------------------------------------------------------------------- */
 
821
        /*      Verify selection.                                               */
 
822
        /* -------------------------------------------------------------------- */
 
823
        if ( iField < 0 || iField >= psDBF->nFields )
 
824
                return( NULL );
 
825
 
 
826
        if ( ! DBFReadSetup( psDBF, hEntity) )
 
827
                return( NULL );
 
828
 
 
829
        /* get reference to current record */
 
830
        pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
831
 
 
832
        /* -------------------------------------------------------------------- */
 
833
        /*      Ensure our field buffer is large enough to hold this buffer.          */
 
834
        /* -------------------------------------------------------------------- */
 
835
        if ( psDBF->panFieldSize[iField]+1 > nStringFieldLen )
 
836
        {
 
837
                nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10;
 
838
                pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen);
 
839
        }
 
840
 
 
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';
 
848
 
 
849
        pReturnField = pszStringField;
 
850
 
 
851
        /* -------------------------------------------------------------------- */
 
852
        /*      Decode the field.                                               */
 
853
        /* -------------------------------------------------------------------- */
 
854
        if ( chReqType == 'N' )
 
855
        {
 
856
                dDoubleField = atof(pszStringField);
 
857
                pReturnField = &dDoubleField;
 
858
        }
 
859
 
 
860
        /* -------------------------------------------------------------------- */
 
861
        /*      Should we trim white space off the string attribute value?      */
 
862
        /* -------------------------------------------------------------------- */
863
863
#ifdef TRIM_DBF_WHITESPACE
864
 
    else
865
 
    {
866
 
        char    *pchSrc, *pchDst;
867
 
 
868
 
        pchDst = pchSrc = pszStringField;
869
 
        while( *pchSrc == ' ' )
870
 
            pchSrc++;
871
 
 
872
 
        while( *pchSrc != '\0' )
873
 
            *(pchDst++) = *(pchSrc++);
874
 
        *pchDst = '\0';
875
 
 
876
 
        while( pchDst != pszStringField && *(--pchDst) == ' ' )
877
 
            *pchDst = '\0';
878
 
    }
 
864
        else
 
865
        {
 
866
                char    *pchSrc, *pchDst;
 
867
 
 
868
                pchDst = pchSrc = pszStringField;
 
869
                while ( *pchSrc == ' ' )
 
870
                        pchSrc++;
 
871
 
 
872
                while ( *pchSrc != '\0' )
 
873
                        *(pchDst++) = *(pchSrc++);
 
874
                *pchDst = '\0';
 
875
 
 
876
                while ( pchDst != pszStringField && *(--pchDst) == ' ' )
 
877
                        *pchDst = '\0';
 
878
        }
879
879
#endif
880
 
    
881
 
    return( pReturnField );
 
880
 
 
881
        return( pReturnField );
882
882
}
883
883
 
884
884
/************************************************************************/
891
891
DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField )
892
892
 
893
893
{
894
 
    double      *pdValue;
895
 
 
896
 
    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
897
 
 
898
 
    if( pdValue == NULL )
899
 
        return 0;
900
 
    else
901
 
        return( (int) *pdValue );
 
894
        double  *pdValue;
 
895
 
 
896
        pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
 
897
 
 
898
        if ( pdValue == NULL )
 
899
                return 0;
 
900
        else
 
901
                return( (int) *pdValue );
902
902
}
903
903
 
904
904
/************************************************************************/
911
911
DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField )
912
912
 
913
913
{
914
 
    double      *pdValue;
915
 
 
916
 
    pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
917
 
 
918
 
    if( pdValue == NULL )
919
 
        return 0.0;
920
 
    else
921
 
        return( *pdValue );
 
914
        double  *pdValue;
 
915
 
 
916
        pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' );
 
917
 
 
918
        if ( pdValue == NULL )
 
919
                return 0.0;
 
920
        else
 
921
                return( *pdValue );
922
922
}
923
923
 
924
924
/************************************************************************/
931
931
DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField )
932
932
 
933
933
{
934
 
    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );
 
934
        return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );
935
935
}
936
936
 
937
937
/************************************************************************/
944
944
DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
945
945
 
946
946
{
947
 
    return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
 
947
        return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
948
948
}
949
949
 
950
950
/************************************************************************/
959
959
DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField )
960
960
 
961
961
{
962
 
    const char  *pszValue;
963
 
 
964
 
    pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
965
 
 
966
 
    if( pszValue == NULL )
967
 
        return TRUE;
968
 
 
969
 
    switch(psDBF->pachFieldType[iField])
970
 
    {
971
 
      case 'N':
972
 
      case 'F':
973
 
        /* NULL numeric fields have value "****************" */
974
 
        return pszValue[0] == '*';
975
 
 
976
 
      case 'D':
977
 
        /* NULL date fields have value "00000000" */
978
 
        return (strncmp(pszValue,"00000000",8) == 0 || strlen(pszValue) == 0);
979
 
 
980
 
      case 'L':
981
 
        /* NULL boolean fields have value "?" */ 
982
 
        return pszValue[0] == '?';
983
 
 
984
 
      default:
985
 
        /* empty string fields are considered NULL */
986
 
        return strlen(pszValue) == 0;
987
 
    }
 
962
        const char      *pszValue;
 
963
 
 
964
        pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
 
965
 
 
966
        if ( pszValue == NULL )
 
967
                return TRUE;
 
968
 
 
969
        switch (psDBF->pachFieldType[iField])
 
970
        {
 
971
        case 'N':
 
972
        case 'F':
 
973
                /* NULL numeric fields have value "****************" */
 
974
                return pszValue[0] == '*';
 
975
 
 
976
        case 'D':
 
977
                /* NULL date fields have value "00000000" */
 
978
                return (strncmp(pszValue,"00000000",8) == 0 || strlen(pszValue) == 0);
 
979
 
 
980
        case 'L':
 
981
                /* NULL boolean fields have value "?" */
 
982
                return pszValue[0] == '?';
 
983
 
 
984
        default:
 
985
                /* empty string fields are considered NULL */
 
986
                return strlen(pszValue) == 0;
 
987
        }
988
988
}
989
989
 
990
990
/************************************************************************/
997
997
DBFGetFieldCount( DBFHandle psDBF )
998
998
 
999
999
{
1000
 
    return( psDBF->nFields );
 
1000
        return( psDBF->nFields );
1001
1001
}
1002
1002
 
1003
1003
/************************************************************************/
1010
1010
DBFGetRecordCount( DBFHandle psDBF )
1011
1011
 
1012
1012
{
1013
 
    return( psDBF->nRecords );
 
1013
        return( psDBF->nRecords );
1014
1014
}
1015
1015
 
1016
1016
/************************************************************************/
1024
1024
                 int * pnWidth, int * pnDecimals )
1025
1025
 
1026
1026
{
1027
 
    if( iField < 0 || iField >= psDBF->nFields )
1028
 
        return( FTInvalid );
1029
 
 
1030
 
    if( pnWidth != NULL )
1031
 
        *pnWidth = psDBF->panFieldSize[iField];
1032
 
 
1033
 
    if( pnDecimals != NULL )
1034
 
        *pnDecimals = psDBF->panFieldDecimals[iField];
1035
 
 
1036
 
    if( pszFieldName != NULL )
1037
 
    {
1038
 
        int     i;
1039
 
 
1040
 
        strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 );
1041
 
        pszFieldName[11] = '\0';
1042
 
        for( i = 10; i > 0 && pszFieldName[i] == ' '; i-- )
1043
 
            pszFieldName[i] = '\0';
1044
 
    }
1045
 
 
1046
 
    if ( psDBF->pachFieldType[iField] == 'L' )
1047
 
        return( FTLogical);
1048
 
 
1049
 
    else if( psDBF->pachFieldType[iField] == 'D'  )
1050
 
        return ( FTDate );
1051
 
 
1052
 
    else if( psDBF->pachFieldType[iField] == 'N' 
1053
 
             || psDBF->pachFieldType[iField] == 'F' )
1054
 
    {
1055
 
        if( psDBF->panFieldDecimals[iField] > 0 )
1056
 
            return( FTDouble );
 
1027
        if ( iField < 0 || iField >= psDBF->nFields )
 
1028
                return( FTInvalid );
 
1029
 
 
1030
        if ( pnWidth != NULL )
 
1031
                *pnWidth = psDBF->panFieldSize[iField];
 
1032
 
 
1033
        if ( pnDecimals != NULL )
 
1034
                *pnDecimals = psDBF->panFieldDecimals[iField];
 
1035
 
 
1036
        if ( pszFieldName != NULL )
 
1037
        {
 
1038
                int     i;
 
1039
 
 
1040
                strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 );
 
1041
                pszFieldName[11] = '\0';
 
1042
                for ( i = 10; i > 0 && pszFieldName[i] == ' '; i-- )
 
1043
                        pszFieldName[i] = '\0';
 
1044
        }
 
1045
 
 
1046
        if ( psDBF->pachFieldType[iField] == 'L' )
 
1047
                return( FTLogical);
 
1048
 
 
1049
        else if ( psDBF->pachFieldType[iField] == 'D'  )
 
1050
                return ( FTDate );
 
1051
 
 
1052
        else if ( psDBF->pachFieldType[iField] == 'N'
 
1053
                  || psDBF->pachFieldType[iField] == 'F' )
 
1054
        {
 
1055
                if ( psDBF->panFieldDecimals[iField] > 0 )
 
1056
                        return( FTDouble );
 
1057
                else
 
1058
                        return( FTInteger );
 
1059
        }
1057
1060
        else
1058
 
            return( FTInteger );
1059
 
    }
1060
 
    else
1061
 
    {
1062
 
        return( FTString );
1063
 
    }
 
1061
        {
 
1062
                return( FTString );
 
1063
        }
1064
1064
}
1065
1065
 
1066
1066
/************************************************************************/
1070
1070
/************************************************************************/
1071
1071
 
1072
1072
static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField,
1073
 
                             void * pValue )
 
1073
                             void * pValue )
1074
1074
 
1075
1075
{
1076
 
    int         nRecordOffset, i, j, nRetResult = TRUE;
1077
 
    unsigned char       *pabyRec;
1078
 
    char        szSField[400], szFormat[20];
1079
 
 
1080
 
/* -------------------------------------------------------------------- */
1081
 
/*      Is this a valid record?                                         */
1082
 
/* -------------------------------------------------------------------- */
1083
 
    if( hEntity < 0 || hEntity > psDBF->nRecords )
1084
 
        return( FALSE );
1085
 
 
1086
 
    if( psDBF->bNoHeader )
1087
 
        DBFWriteHeader(psDBF);
1088
 
 
1089
 
/* -------------------------------------------------------------------- */
1090
 
/*      Is this a brand new record?                                     */
1091
 
/* -------------------------------------------------------------------- */
1092
 
    if( hEntity == psDBF->nRecords )
1093
 
    {
1094
 
        DBFFlushRecord( psDBF );
1095
 
 
1096
 
        psDBF->nRecords++;
1097
 
        for( i = 0; i < psDBF->nRecordLength; i++ )
1098
 
            psDBF->pszCurrentRecord[i] = ' ';
1099
 
 
1100
 
        psDBF->nCurrentRecord = hEntity;
1101
 
    }
1102
 
 
1103
 
/* -------------------------------------------------------------------- */
1104
 
/*      Is this an existing record, but different than the last one     */
1105
 
/*      we accessed?                                                    */
1106
 
/* -------------------------------------------------------------------- */
1107
 
    if( psDBF->nCurrentRecord != hEntity )
1108
 
    {
1109
 
        DBFFlushRecord( psDBF );
1110
 
 
1111
 
        nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1112
 
 
1113
 
        fseek( psDBF->fp, nRecordOffset, 0 );
1114
 
        fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1115
 
 
1116
 
        psDBF->nCurrentRecord = hEntity;
1117
 
    }
1118
 
 
1119
 
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1120
 
 
1121
 
    psDBF->bCurrentRecordModified = TRUE;
1122
 
    psDBF->bUpdated = TRUE;
1123
 
 
1124
 
/* -------------------------------------------------------------------- */
1125
 
/*      Translate NULL value to valid DBF file representation.          */
1126
 
/*                                                                      */
1127
 
/*      Contributed by Jim Matthews.                                    */
1128
 
/* -------------------------------------------------------------------- */
1129
 
    if( pValue == NULL )
1130
 
    {
1131
 
        switch(psDBF->pachFieldType[iField])
1132
 
        {
1133
 
          case 'N':
1134
 
          case 'F':
1135
 
            /* NULL numeric fields have value "****************" */
1136
 
            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*', 
1137
 
                    psDBF->panFieldSize[iField] );
1138
 
            break;
1139
 
 
1140
 
          case 'D':
1141
 
            /* NULL date fields have value "00000000" */
1142
 
            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0', 
1143
 
                    psDBF->panFieldSize[iField] );
1144
 
            break;
1145
 
 
1146
 
          case 'L':
1147
 
            /* NULL boolean fields have value "?" */ 
1148
 
            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?', 
1149
 
                    psDBF->panFieldSize[iField] );
1150
 
            break;
1151
 
 
1152
 
          default:
1153
 
            /* empty string fields are considered NULL */
1154
 
            memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0', 
1155
 
                    psDBF->panFieldSize[iField] );
1156
 
            break;
1157
 
        }
1158
 
        return TRUE;
1159
 
    }
1160
 
 
1161
 
/* -------------------------------------------------------------------- */
1162
 
/*      Assign all the record fields.                                   */
1163
 
/* -------------------------------------------------------------------- */
1164
 
    switch( psDBF->pachFieldType[iField] )
1165
 
    {
1166
 
      case 'D':
1167
 
      case 'N':
1168
 
      case 'F':
1169
 
        if( psDBF->panFieldDecimals[iField] == 0 )
1170
 
        {
1171
 
            int         nWidth = psDBF->panFieldSize[iField];
1172
 
 
1173
 
            if( sizeof(szSField)-2 < nWidth )
1174
 
                nWidth = sizeof(szSField)-2;
1175
 
 
1176
 
            sprintf( szFormat, "%%%dd", nWidth );
1177
 
            sprintf(szSField, szFormat, (int) *((double *) pValue) );
1178
 
            if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
1179
 
            {
1180
 
                szSField[psDBF->panFieldSize[iField]] = '\0';
1181
 
                nRetResult = FALSE;
1182
 
            }
1183
 
 
1184
 
            strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1185
 
                    szSField, strlen(szSField) );
1186
 
        }
1187
 
        else
1188
 
        {
1189
 
            int         nWidth = psDBF->panFieldSize[iField];
1190
 
 
1191
 
            if( sizeof(szSField)-2 < nWidth )
1192
 
                nWidth = sizeof(szSField)-2;
1193
 
 
1194
 
            sprintf( szFormat, "%%%d.%df", 
1195
 
                     nWidth, psDBF->panFieldDecimals[iField] );
1196
 
            sprintf(szSField, szFormat, *((double *) pValue) );
1197
 
            if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
1198
 
            {
1199
 
                szSField[psDBF->panFieldSize[iField]] = '\0';
1200
 
                nRetResult = FALSE;
1201
 
            }
1202
 
            strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1203
 
                    szSField, strlen(szSField) );
1204
 
        }
1205
 
        break;
1206
 
 
1207
 
      case 'L':
1208
 
        if (psDBF->panFieldSize[iField] >= 1  && 
1209
 
            (*(char*)pValue == 'F' || *(char*)pValue == 'T'))
1210
 
            *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
1211
 
        break;
1212
 
 
1213
 
      default:
1214
 
        if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1215
 
        {
1216
 
            j = psDBF->panFieldSize[iField];
1217
 
            nRetResult = FALSE;
1218
 
        }
1219
 
        else
1220
 
        {
1221
 
            memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
1222
 
                    psDBF->panFieldSize[iField] );
1223
 
            j = strlen((char *) pValue);
1224
 
        }
1225
 
 
1226
 
        strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1227
 
                (char *) pValue, j );
1228
 
        break;
1229
 
    }
1230
 
 
1231
 
    return( nRetResult );
 
1076
        int             nRecordOffset, i, j, nRetResult = TRUE;
 
1077
        unsigned char   *pabyRec;
 
1078
        char    szSField[400], szFormat[20];
 
1079
 
 
1080
        /* -------------------------------------------------------------------- */
 
1081
        /*      Is this a valid record?                                         */
 
1082
        /* -------------------------------------------------------------------- */
 
1083
        if ( hEntity < 0 || hEntity > psDBF->nRecords )
 
1084
                return( FALSE );
 
1085
 
 
1086
        if ( psDBF->bNoHeader )
 
1087
                DBFWriteHeader(psDBF);
 
1088
 
 
1089
        /* -------------------------------------------------------------------- */
 
1090
        /*      Is this a brand new record?                                     */
 
1091
        /* -------------------------------------------------------------------- */
 
1092
        if ( hEntity == psDBF->nRecords )
 
1093
        {
 
1094
                DBFFlushRecord( psDBF );
 
1095
 
 
1096
                psDBF->nRecords++;
 
1097
                for ( i = 0; i < psDBF->nRecordLength; i++ )
 
1098
                        psDBF->pszCurrentRecord[i] = ' ';
 
1099
 
 
1100
                psDBF->nCurrentRecord = hEntity;
 
1101
        }
 
1102
 
 
1103
        /* -------------------------------------------------------------------- */
 
1104
        /*      Is this an existing record, but different than the last one     */
 
1105
        /*      we accessed?                                                    */
 
1106
        /* -------------------------------------------------------------------- */
 
1107
        if ( psDBF->nCurrentRecord != hEntity )
 
1108
        {
 
1109
                DBFFlushRecord( psDBF );
 
1110
 
 
1111
                nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
 
1112
 
 
1113
                fseek( psDBF->fp, nRecordOffset, 0 );
 
1114
                fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
 
1115
 
 
1116
                psDBF->nCurrentRecord = hEntity;
 
1117
        }
 
1118
 
 
1119
        pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
1120
 
 
1121
        psDBF->bCurrentRecordModified = TRUE;
 
1122
        psDBF->bUpdated = TRUE;
 
1123
 
 
1124
        /* -------------------------------------------------------------------- */
 
1125
        /*      Translate NULL value to valid DBF file representation.          */
 
1126
        /*                                                                      */
 
1127
        /*      Contributed by Jim Matthews.                                    */
 
1128
        /* -------------------------------------------------------------------- */
 
1129
        if ( pValue == NULL )
 
1130
        {
 
1131
                switch (psDBF->pachFieldType[iField])
 
1132
                {
 
1133
                case 'N':
 
1134
                case 'F':
 
1135
                        /* NULL numeric fields have value "****************" */
 
1136
                        memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*',
 
1137
                                psDBF->panFieldSize[iField] );
 
1138
                        break;
 
1139
 
 
1140
                case 'D':
 
1141
                        /* NULL date fields have value "00000000" */
 
1142
                        memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0',
 
1143
                                psDBF->panFieldSize[iField] );
 
1144
                        break;
 
1145
 
 
1146
                case 'L':
 
1147
                        /* NULL boolean fields have value "?" */
 
1148
                        memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?',
 
1149
                                psDBF->panFieldSize[iField] );
 
1150
                        break;
 
1151
 
 
1152
                default:
 
1153
                        /* empty string fields are considered NULL */
 
1154
                        memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0',
 
1155
                                psDBF->panFieldSize[iField] );
 
1156
                        break;
 
1157
                }
 
1158
                return TRUE;
 
1159
        }
 
1160
 
 
1161
        /* -------------------------------------------------------------------- */
 
1162
        /*      Assign all the record fields.                                   */
 
1163
        /* -------------------------------------------------------------------- */
 
1164
        switch ( psDBF->pachFieldType[iField] )
 
1165
        {
 
1166
        case 'D':
 
1167
        case 'N':
 
1168
        case 'F':
 
1169
                if ( psDBF->panFieldDecimals[iField] == 0 )
 
1170
                {
 
1171
                        int             nWidth = psDBF->panFieldSize[iField];
 
1172
 
 
1173
                        if ( sizeof(szSField)-2 < nWidth )
 
1174
                                nWidth = sizeof(szSField)-2;
 
1175
 
 
1176
                        sprintf( szFormat, "%%%dd", nWidth );
 
1177
                        sprintf(szSField, szFormat, (int) *((double *) pValue) );
 
1178
                        if ( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
 
1179
                        {
 
1180
                                szSField[psDBF->panFieldSize[iField]] = '\0';
 
1181
                                nRetResult = FALSE;
 
1182
                        }
 
1183
 
 
1184
                        strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
 
1185
                                szSField, strlen(szSField) );
 
1186
                }
 
1187
                else
 
1188
                {
 
1189
                        int             nWidth = psDBF->panFieldSize[iField];
 
1190
 
 
1191
                        if ( sizeof(szSField)-2 < nWidth )
 
1192
                                nWidth = sizeof(szSField)-2;
 
1193
 
 
1194
                        sprintf( szFormat, "%%%d.%df",
 
1195
                                 nWidth, psDBF->panFieldDecimals[iField] );
 
1196
                        sprintf(szSField, szFormat, *((double *) pValue) );
 
1197
                        if ( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
 
1198
                        {
 
1199
                                szSField[psDBF->panFieldSize[iField]] = '\0';
 
1200
                                nRetResult = FALSE;
 
1201
                        }
 
1202
                        strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
 
1203
                                szSField, strlen(szSField) );
 
1204
                }
 
1205
                break;
 
1206
 
 
1207
        case 'L':
 
1208
                if (psDBF->panFieldSize[iField] >= 1  &&
 
1209
                        (*(char*)pValue == 'F' || *(char*)pValue == 'T'))
 
1210
                        *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
 
1211
                break;
 
1212
 
 
1213
        default:
 
1214
                if ( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
 
1215
                {
 
1216
                        j = psDBF->panFieldSize[iField];
 
1217
                        nRetResult = FALSE;
 
1218
                }
 
1219
                else
 
1220
                {
 
1221
                        memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
 
1222
                                psDBF->panFieldSize[iField] );
 
1223
                        j = strlen((char *) pValue);
 
1224
                }
 
1225
 
 
1226
                strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
 
1227
                        (char *) pValue, j );
 
1228
                break;
 
1229
        }
 
1230
 
 
1231
        return( nRetResult );
1232
1232
}
1233
1233
 
1234
1234
/************************************************************************/
1243
1243
                              const void * pValue )
1244
1244
 
1245
1245
{
1246
 
    int         nRecordOffset, i, j;
1247
 
    unsigned char       *pabyRec;
1248
 
 
1249
 
/* -------------------------------------------------------------------- */
1250
 
/*      Is this a valid record?                                         */
1251
 
/* -------------------------------------------------------------------- */
1252
 
    if( hEntity < 0 || hEntity > psDBF->nRecords )
1253
 
        return( FALSE );
1254
 
 
1255
 
    if( psDBF->bNoHeader )
1256
 
        DBFWriteHeader(psDBF);
1257
 
 
1258
 
/* -------------------------------------------------------------------- */
1259
 
/*      Is this a brand new record?                                     */
1260
 
/* -------------------------------------------------------------------- */
1261
 
    if( hEntity == psDBF->nRecords )
1262
 
    {
1263
 
        DBFFlushRecord( psDBF );
1264
 
 
1265
 
        psDBF->nRecords++;
1266
 
        for( i = 0; i < psDBF->nRecordLength; i++ )
1267
 
            psDBF->pszCurrentRecord[i] = ' ';
1268
 
 
1269
 
        psDBF->nCurrentRecord = hEntity;
1270
 
    }
1271
 
 
1272
 
/* -------------------------------------------------------------------- */
1273
 
/*      Is this an existing record, but different than the last one     */
1274
 
/*      we accessed?                                                    */
1275
 
/* -------------------------------------------------------------------- */
1276
 
    if( psDBF->nCurrentRecord != hEntity )
1277
 
    {
1278
 
        DBFFlushRecord( psDBF );
1279
 
 
1280
 
        nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1281
 
 
1282
 
        fseek( psDBF->fp, nRecordOffset, 0 );
1283
 
        fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1284
 
 
1285
 
        psDBF->nCurrentRecord = hEntity;
1286
 
    }
1287
 
 
1288
 
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1289
 
 
1290
 
/* -------------------------------------------------------------------- */
1291
 
/*      Assign all the record fields.                                   */
1292
 
/* -------------------------------------------------------------------- */
1293
 
    if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1294
 
        j = psDBF->panFieldSize[iField];
1295
 
    else
1296
 
    {
1297
 
        memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
1298
 
                psDBF->panFieldSize[iField] );
1299
 
        j = strlen((char *) pValue);
1300
 
    }
1301
 
 
1302
 
    strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1303
 
            (char *) pValue, j );
1304
 
 
1305
 
    psDBF->bCurrentRecordModified = TRUE;
1306
 
    psDBF->bUpdated = TRUE;
1307
 
 
1308
 
    return( TRUE );
 
1246
        int             nRecordOffset, i, j;
 
1247
        unsigned char   *pabyRec;
 
1248
 
 
1249
        /* -------------------------------------------------------------------- */
 
1250
        /*      Is this a valid record?                                         */
 
1251
        /* -------------------------------------------------------------------- */
 
1252
        if ( hEntity < 0 || hEntity > psDBF->nRecords )
 
1253
                return( FALSE );
 
1254
 
 
1255
        if ( psDBF->bNoHeader )
 
1256
                DBFWriteHeader(psDBF);
 
1257
 
 
1258
        /* -------------------------------------------------------------------- */
 
1259
        /*      Is this a brand new record?                                     */
 
1260
        /* -------------------------------------------------------------------- */
 
1261
        if ( hEntity == psDBF->nRecords )
 
1262
        {
 
1263
                DBFFlushRecord( psDBF );
 
1264
 
 
1265
                psDBF->nRecords++;
 
1266
                for ( i = 0; i < psDBF->nRecordLength; i++ )
 
1267
                        psDBF->pszCurrentRecord[i] = ' ';
 
1268
 
 
1269
                psDBF->nCurrentRecord = hEntity;
 
1270
        }
 
1271
 
 
1272
        /* -------------------------------------------------------------------- */
 
1273
        /*      Is this an existing record, but different than the last one     */
 
1274
        /*      we accessed?                                                    */
 
1275
        /* -------------------------------------------------------------------- */
 
1276
        if ( psDBF->nCurrentRecord != hEntity )
 
1277
        {
 
1278
                DBFFlushRecord( psDBF );
 
1279
 
 
1280
                nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
 
1281
 
 
1282
                fseek( psDBF->fp, nRecordOffset, 0 );
 
1283
                fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
 
1284
 
 
1285
                psDBF->nCurrentRecord = hEntity;
 
1286
        }
 
1287
 
 
1288
        pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
1289
 
 
1290
        /* -------------------------------------------------------------------- */
 
1291
        /*      Assign all the record fields.                                   */
 
1292
        /* -------------------------------------------------------------------- */
 
1293
        if ( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
 
1294
                j = psDBF->panFieldSize[iField];
 
1295
        else
 
1296
        {
 
1297
                memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
 
1298
                        psDBF->panFieldSize[iField] );
 
1299
                j = strlen((char *) pValue);
 
1300
        }
 
1301
 
 
1302
        strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
 
1303
                (char *) pValue, j );
 
1304
 
 
1305
        psDBF->bCurrentRecordModified = TRUE;
 
1306
        psDBF->bUpdated = TRUE;
 
1307
 
 
1308
        return( TRUE );
1309
1309
}
1310
1310
 
1311
1311
/************************************************************************/
1319
1319
                         double dValue )
1320
1320
 
1321
1321
{
1322
 
    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
 
1322
        return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
1323
1323
}
1324
1324
 
1325
1325
/************************************************************************/
1333
1333
                          int nValue )
1334
1334
 
1335
1335
{
1336
 
    double      dValue = nValue;
 
1336
        double  dValue = nValue;
1337
1337
 
1338
 
    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
 
1338
        return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) );
1339
1339
}
1340
1340
 
1341
1341
/************************************************************************/
1349
1349
                         const char * pszValue )
1350
1350
 
1351
1351
{
1352
 
    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) );
 
1352
        return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) );
1353
1353
}
1354
1354
 
1355
1355
/************************************************************************/
1362
1362
DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField )
1363
1363
 
1364
1364
{
1365
 
    return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) );
 
1365
        return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) );
1366
1366
}
1367
1367
 
1368
1368
/************************************************************************/
1373
1373
 
1374
1374
int SHPAPI_CALL
1375
1375
DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField,
1376
 
                       const char lValue)
 
1376
                          const char lValue)
1377
1377
 
1378
1378
{
1379
 
    return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) );
 
1379
        return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) );
1380
1380
}
1381
1381
 
1382
1382
/************************************************************************/
1389
1389
DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple )
1390
1390
 
1391
1391
{
1392
 
    int         nRecordOffset, i;
1393
 
    unsigned char       *pabyRec;
1394
 
 
1395
 
/* -------------------------------------------------------------------- */
1396
 
/*      Is this a valid record?                                         */
1397
 
/* -------------------------------------------------------------------- */
1398
 
    if( hEntity < 0 || hEntity > psDBF->nRecords )
1399
 
        return( FALSE );
1400
 
 
1401
 
    if( psDBF->bNoHeader )
1402
 
        DBFWriteHeader(psDBF);
1403
 
 
1404
 
/* -------------------------------------------------------------------- */
1405
 
/*      Is this a brand new record?                                     */
1406
 
/* -------------------------------------------------------------------- */
1407
 
    if( hEntity == psDBF->nRecords )
1408
 
    {
1409
 
        DBFFlushRecord( psDBF );
1410
 
 
1411
 
        psDBF->nRecords++;
1412
 
        for( i = 0; i < psDBF->nRecordLength; i++ )
1413
 
            psDBF->pszCurrentRecord[i] = ' ';
1414
 
 
1415
 
        psDBF->nCurrentRecord = hEntity;
1416
 
    }
1417
 
 
1418
 
/* -------------------------------------------------------------------- */
1419
 
/*      Is this an existing record, but different than the last one     */
1420
 
/*      we accessed?                                                    */
1421
 
/* -------------------------------------------------------------------- */
1422
 
    if( psDBF->nCurrentRecord != hEntity )
1423
 
    {
1424
 
        DBFFlushRecord( psDBF );
1425
 
 
1426
 
        nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1427
 
 
1428
 
        fseek( psDBF->fp, nRecordOffset, 0 );
1429
 
        fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1430
 
 
1431
 
        psDBF->nCurrentRecord = hEntity;
1432
 
    }
1433
 
 
1434
 
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1435
 
 
1436
 
    memcpy ( pabyRec, pRawTuple,  psDBF->nRecordLength );
1437
 
 
1438
 
    psDBF->bCurrentRecordModified = TRUE;
1439
 
    psDBF->bUpdated = TRUE;
1440
 
 
1441
 
    return( TRUE );
 
1392
        int             nRecordOffset, i;
 
1393
        unsigned char   *pabyRec;
 
1394
 
 
1395
        /* -------------------------------------------------------------------- */
 
1396
        /*      Is this a valid record?                                         */
 
1397
        /* -------------------------------------------------------------------- */
 
1398
        if ( hEntity < 0 || hEntity > psDBF->nRecords )
 
1399
                return( FALSE );
 
1400
 
 
1401
        if ( psDBF->bNoHeader )
 
1402
                DBFWriteHeader(psDBF);
 
1403
 
 
1404
        /* -------------------------------------------------------------------- */
 
1405
        /*      Is this a brand new record?                                     */
 
1406
        /* -------------------------------------------------------------------- */
 
1407
        if ( hEntity == psDBF->nRecords )
 
1408
        {
 
1409
                DBFFlushRecord( psDBF );
 
1410
 
 
1411
                psDBF->nRecords++;
 
1412
                for ( i = 0; i < psDBF->nRecordLength; i++ )
 
1413
                        psDBF->pszCurrentRecord[i] = ' ';
 
1414
 
 
1415
                psDBF->nCurrentRecord = hEntity;
 
1416
        }
 
1417
 
 
1418
        /* -------------------------------------------------------------------- */
 
1419
        /*      Is this an existing record, but different than the last one     */
 
1420
        /*      we accessed?                                                    */
 
1421
        /* -------------------------------------------------------------------- */
 
1422
        if ( psDBF->nCurrentRecord != hEntity )
 
1423
        {
 
1424
                DBFFlushRecord( psDBF );
 
1425
 
 
1426
                nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
 
1427
 
 
1428
                fseek( psDBF->fp, nRecordOffset, 0 );
 
1429
                fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
 
1430
 
 
1431
                psDBF->nCurrentRecord = hEntity;
 
1432
        }
 
1433
 
 
1434
        pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
1435
 
 
1436
        memcpy ( pabyRec, pRawTuple,  psDBF->nRecordLength );
 
1437
 
 
1438
        psDBF->bCurrentRecordModified = TRUE;
 
1439
        psDBF->bUpdated = TRUE;
 
1440
 
 
1441
        return( TRUE );
1442
1442
}
1443
1443
 
1444
1444
/************************************************************************/
1451
1451
DBFReadTuple(DBFHandle psDBF, int hEntity )
1452
1452
 
1453
1453
{
1454
 
    int         nRecordOffset;
1455
 
    unsigned char       *pabyRec;
1456
 
    static char *pReturnTuple = NULL;
1457
 
 
1458
 
    static int  nTupleLen = 0;
1459
 
 
1460
 
/* -------------------------------------------------------------------- */
1461
 
/*      Have we read the record?                                        */
1462
 
/* -------------------------------------------------------------------- */
1463
 
    if( hEntity < 0 || hEntity >= psDBF->nRecords )
1464
 
        return( NULL );
1465
 
 
1466
 
    if( psDBF->nCurrentRecord != hEntity )
1467
 
    {
1468
 
        DBFFlushRecord( psDBF );
1469
 
 
1470
 
        nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1471
 
 
1472
 
        fseek( psDBF->fp, nRecordOffset, 0 );
1473
 
        fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1474
 
 
1475
 
        psDBF->nCurrentRecord = hEntity;
1476
 
    }
1477
 
 
1478
 
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1479
 
 
1480
 
    if ( nTupleLen < psDBF->nRecordLength) {
1481
 
      nTupleLen = psDBF->nRecordLength;
1482
 
      pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
1483
 
    }
1484
 
    
1485
 
    memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
1486
 
        
1487
 
    return( pReturnTuple );
 
1454
        int             nRecordOffset;
 
1455
        unsigned char   *pabyRec;
 
1456
        static char     *pReturnTuple = NULL;
 
1457
 
 
1458
        static int      nTupleLen = 0;
 
1459
 
 
1460
        /* -------------------------------------------------------------------- */
 
1461
        /*      Have we read the record?                                        */
 
1462
        /* -------------------------------------------------------------------- */
 
1463
        if ( hEntity < 0 || hEntity >= psDBF->nRecords )
 
1464
                return( NULL );
 
1465
 
 
1466
        if ( psDBF->nCurrentRecord != hEntity )
 
1467
        {
 
1468
                DBFFlushRecord( psDBF );
 
1469
 
 
1470
                nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
 
1471
 
 
1472
                fseek( psDBF->fp, nRecordOffset, 0 );
 
1473
                fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
 
1474
 
 
1475
                psDBF->nCurrentRecord = hEntity;
 
1476
        }
 
1477
 
 
1478
        pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
 
1479
 
 
1480
        if ( nTupleLen < psDBF->nRecordLength)
 
1481
        {
 
1482
                nTupleLen = psDBF->nRecordLength;
 
1483
                pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength);
 
1484
        }
 
1485
 
 
1486
        memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength );
 
1487
 
 
1488
        return( pReturnTuple );
1488
1489
}
1489
1490
 
1490
1491
/************************************************************************/
1494
1495
/************************************************************************/
1495
1496
 
1496
1497
DBFHandle SHPAPI_CALL
1497
 
DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) 
 
1498
DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename )
1498
1499
{
1499
 
    DBFHandle   newDBF;
1500
 
 
1501
 
   newDBF = DBFCreate ( pszFilename );
1502
 
   if ( newDBF == NULL ) return ( NULL ); 
1503
 
   
1504
 
   newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
1505
 
   memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
1506
 
   
1507
 
   newDBF->nFields = psDBF->nFields;
1508
 
   newDBF->nRecordLength = psDBF->nRecordLength;
1509
 
   newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
1510
 
    
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 );
1519
 
 
1520
 
   newDBF->bNoHeader = TRUE;
1521
 
   newDBF->bUpdated = TRUE;
1522
 
   
1523
 
   DBFWriteHeader ( newDBF );
1524
 
   DBFClose ( newDBF );
1525
 
   
1526
 
   newDBF = DBFOpen ( pszFilename, "rb+" );
1527
 
 
1528
 
   return ( newDBF );
 
1500
        DBFHandle       newDBF;
 
1501
 
 
1502
        newDBF = DBFCreate ( pszFilename );
 
1503
        if ( newDBF == NULL ) return ( NULL );
 
1504
 
 
1505
        newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
 
1506
        memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
 
1507
 
 
1508
        newDBF->nFields = psDBF->nFields;
 
1509
        newDBF->nRecordLength = psDBF->nRecordLength;
 
1510
        newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
 
1511
 
 
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 );
 
1520
 
 
1521
        newDBF->bNoHeader = TRUE;
 
1522
        newDBF->bUpdated = TRUE;
 
1523
 
 
1524
        DBFWriteHeader ( newDBF );
 
1525
        DBFClose ( newDBF );
 
1526
 
 
1527
        newDBF = DBFOpen ( pszFilename, "rb+" );
 
1528
 
 
1529
        return ( newDBF );
1529
1530
}
1530
1531
 
1531
1532
/************************************************************************/
1543
1544
DBFGetNativeFieldType( DBFHandle psDBF, int iField )
1544
1545
 
1545
1546
{
1546
 
    if( iField >=0 && iField < psDBF->nFields )
1547
 
        return psDBF->pachFieldType[iField];
 
1547
        if ( iField >=0 && iField < psDBF->nFields )
 
1548
                return psDBF->pachFieldType[iField];
1548
1549
 
1549
 
    return  ' ';
 
1550
        return  ' ';
1550
1551
}
1551
1552
 
1552
1553
/************************************************************************/
1555
1556
 
1556
1557
static void str_to_upper (char *string)
1557
1558
{
1558
 
    int len;
1559
 
    short i = -1;
1560
 
 
1561
 
    len = strlen (string);
1562
 
 
1563
 
    while (++i < len)
1564
 
        if (isalpha(string[i]) && islower(string[i]))
1565
 
            string[i] = (char) toupper ((int)string[i]);
 
1559
        int len;
 
1560
        short i = -1;
 
1561
 
 
1562
        len = strlen (string);
 
1563
 
 
1564
        while (++i < len)
 
1565
                if (isalpha(string[i]) && islower(string[i]))
 
1566
                        string[i] = (char) toupper ((int)string[i]);
1566
1567
}
1567
1568
 
1568
1569
/************************************************************************/
1577
1578
DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName)
1578
1579
 
1579
1580
{
1580
 
    char          name[12], name1[12], name2[12];
1581
 
    int           i;
1582
 
 
1583
 
    strncpy(name1, pszFieldName,11);
1584
 
    name1[11] = '\0';
1585
 
    str_to_upper(name1);
1586
 
 
1587
 
    for( i = 0; i < DBFGetFieldCount(psDBF); i++ )
1588
 
    {
1589
 
        DBFGetFieldInfo( psDBF, i, name, NULL, NULL );
1590
 
        strncpy(name2,name,11);
1591
 
        str_to_upper(name2);
1592
 
 
1593
 
        if(!strncmp(name1,name2,10))
1594
 
            return(i);
1595
 
    }
1596
 
    return(-1);
 
1581
        char          name[12], name1[12], name2[12];
 
1582
        int           i;
 
1583
 
 
1584
        strncpy(name1, pszFieldName,11);
 
1585
        name1[11] = '\0';
 
1586
        str_to_upper(name1);
 
1587
 
 
1588
        for ( i = 0; i < DBFGetFieldCount(psDBF); i++ )
 
1589
        {
 
1590
                DBFGetFieldInfo( psDBF, i, name, NULL, NULL );
 
1591
                strncpy(name2,name,11);
 
1592
                str_to_upper(name2);
 
1593
 
 
1594
                if (!strncmp(name1,name2,10))
 
1595
                        return(i);
 
1596
        }
 
1597
        return(-1);
1597
1598
}