/[thuban]/branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/thuban/libraries/shapelib/dbfopen.c revision 1612 by jan, Tue Aug 19 21:29:25 2003 UTC branches/WIP-pyshapelib-bramz/libraries/shapelib/dbfopen.c revision 2752 by bramz, Tue Apr 10 23:45:00 2007 UTC
# Line 3  Line 3 
3   *   *
4   * Project:  Shapelib   * Project:  Shapelib
5   * Purpose:  Implementation of .dbf access API documented in dbf_api.html.   * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
6   * Author:   Frank Warmerdam, [email protected]   * Author:   Frank Warmerdam, [email protected]
7   *   *
8   ******************************************************************************   ******************************************************************************
9   * Copyright (c) 1999, Frank Warmerdam   * Copyright (c) 1999, Frank Warmerdam
# Line 34  Line 34 
34   ******************************************************************************   ******************************************************************************
35   *   *
36   * $Log$   * $Log$
37   * Revision 1.1  2003/08/19 21:29:25  jan   * Revision 1.3  2004/05/17 15:47:57  bh
38   * These files have been moved here from thuban/extensions/shapelib/   * Update to newest shapelib and get rid of Thuban specific extensions,
39   * See there in the Attic for the older history.   * i.e. use the new DBFUpdateHeader instead of our DBFCommit kludge
40   *   *
41   * Revision 1.4  2002/08/22 16:00:01  bh   * * libraries/shapelib/shpopen.c: Update to version from current
42   * * extensions/shapelib/shapefil.h (DBFCommit),   * shapelib CVS.
43   * extensions/shapelib/dbfopen.c (DBFCommit): New API function to   *
44   * commit any changes made to the DBF file.   * * libraries/shapelib/shapefil.h: Update to version from current
45   *   * shapelib CVS.
46   * Revision 1.3  2002/05/07 14:09:45  bh   *
47   * * extensions/shapelib/shpopen.c, extensions/shapelib/shapefil.h,   * * libraries/shapelib/dbfopen.c: Update to version from current
48   * extensions/shapelib/dbfopen.c: Really update to the versions of   * shapelib CVS.
49   * shapelib 1.2.9. For some reason it wasn't really done on   * (DBFCommit): Effectively removed since shapelib itself has
50   * 2002-04-11.   * DBFUpdateHeader now which is better for what DBFCommit wanted to
51     * achieve.
52     * We're now using an unmodified version of dbfopen.
53     *
54     * * libraries/pyshapelib/dbflib_wrap.c, libraries/pyshapelib/dbflib.py:
55     * Update from dbflib.i
56     *
57     * * libraries/pyshapelib/dbflib.i (DBFInfo_commit): New. Implementation of
58     * the commit method.  This new indirection is necessary because we use the
59     * DBFUpdateHeader function now which is not available in shapelib <=
60     * 1.2.10
61     * (DBFFile::commit): Use DBFInfo_commit as implementation
62     * (pragma __class__): New. Kludge to remove the commit method when
63     * the DBFUpdateHeader function isn't available
64     * (_have_commit): New. Helper for the pragma kludge.
65     *
66     * * libraries/pyshapelib/setup.py (dbf_macros): New. Return the
67     * preprocessor macros needed to compile the dbflib wrapper.  Determine
68     * whether DBFUpdateHeader is available and define the right value of
69     * HAVE_UPDATE_HEADER
70     * (extensions): Use dbf_macros for the dbflibc extension
71     *
72     * * setup.py (extensions): Add the HAVE_UPDATE_HEADER macro with
73     * value '1' to the Lib.dbflibc extension.  This simply reflects the
74     * shapelib and pyshapelib updates
75     *
76     * Revision 1.53  2003/12/29 00:00:30  fwarmerdam
77     * mark DBFWriteAttributeDirectly as SHPAPI_CALL
78     *
79     * Revision 1.52  2003/07/08 15:20:03  warmerda
80     * avoid warnings about downcasting to unsigned char
81     *
82     * Revision 1.51  2003/07/08 13:50:15  warmerda
83     * DBFIsAttributeNULL check for pszValue==NULL - bug 360
84     *
85     * Revision 1.50  2003/04/21 18:58:25  warmerda
86     * ensure current record is flushed at same time as header is updated
87     *
88     * Revision 1.49  2003/04/21 18:30:37  warmerda
89     * added header write/update public methods
90     *
91     * Revision 1.48  2003/03/10 14:51:27  warmerda
92     * DBFWrite* calls now return FALSE if they have to truncate
93     *
94     * Revision 1.47  2002/11/20 03:32:22  warmerda
95     * Ensure field name in DBFGetFieldIndex() is properly terminated.
96     *
97     * Revision 1.46  2002/10/09 13:10:21  warmerda
98     * Added check that width is positive.
99     *
100     * Revision 1.45  2002/09/29 00:00:08  warmerda
101     * added FTLogical and logical attribute read/write calls
102     *
103     * Revision 1.44  2002/05/07 13:46:11  warmerda
104     * Added DBFWriteAttributeDirectly().
105     *
106     * Revision 1.43  2002/02/13 19:39:21  warmerda
107     * Fix casting issues in DBFCloneEmpty().
108     *
109     * Revision 1.42  2002/01/15 14:36:07  warmerda
110     * updated email address
111     *
112     * Revision 1.41  2002/01/15 14:31:49  warmerda
113     * compute rather than copying nHeaderLength in DBFCloneEmpty()
114     *
115     * Revision 1.40  2002/01/09 04:32:35  warmerda
116     * fixed to read correct amount of header
117     *
118     * Revision 1.39  2001/12/11 22:41:03  warmerda
119     * improve io related error checking when reading header
120     *
121     * Revision 1.38  2001/11/28 16:07:31  warmerda
122     * Cleanup to avoid compiler warnings as suggested by Richard Hash.
123   *   *
124   * Revision 1.37  2001/07/04 05:18:09  warmerda   * Revision 1.37  2001/07/04 05:18:09  warmerda
125   * do last fix properly   * do last fix properly
# Line 179  static char rcsid[] = Line 251  static char rcsid[] =
251  #  define TRUE          1  #  define TRUE          1
252  #endif  #endif
253    
254    #if defined(_WIN32) || defined(_WIN64)
255    #       define MS_WINDOWS
256    #endif
257    
258  static int      nStringFieldLen = 0;  static int      nStringFieldLen = 0;
259  static char * pszStringField = NULL;  static char * pszStringField = NULL;
260    
261  /************************************************************************/  /************************************************************************/
262    /*                             DBFSet_atof_function()                   */
263    /*                                                                      */
264    /* This makes it possible to initialise a different atof() function     */
265    /* which might be necessary because the standard atof() might be        */
266    /* sensitive to locale settings.                                        */
267    /*                                                                      */
268    /* If the calling application uses a locale with different decimal_point*/
269    /* it should better also give us a locale agnostic atof() function.     */
270    /*                                                                      */
271    /* As far as I can see from Python PEP331 and GNU libc documentation    */
272    /* there is no standard for such a function yet.                        */
273    /*                                                                      */
274    /* [email protected] 20060924                               */
275    /************************************************************************/
276    
277    static double (* atof_function)(const char *nptr)  = &atof;
278    
279    void SHPAPI_CALL
280            DBFSetatof_function(  double (* new_atof_function)(const char *nptr))
281    {
282            atof_function = new_atof_function;
283    }
284    
285    /************************************************************************/
286  /*                             SfRealloc()                              */  /*                             SfRealloc()                              */
287  /*                                                                      */  /*                                                                      */
288  /*      A realloc cover function that will access a NULL pointer as     */  /*      A realloc cover function that will access a NULL pointer as     */
# Line 226  static void DBFWriteHeader(DBFHandle psD Line 326  static void DBFWriteHeader(DBFHandle psD
326    
327      abyHeader[0] = 0x03;                /* memo field? - just copying   */      abyHeader[0] = 0x03;                /* memo field? - just copying   */
328    
329      /* date updated on close, record count preset at zero */      /* write out a dummy date */
330        abyHeader[1] = 95;                  /* YY */
331        abyHeader[2] = 7;                   /* MM */
332        abyHeader[3] = 26;                  /* DD */
333    
334        /* record count preset at zero */
335    
336      abyHeader[8] = psDBF->nHeaderLength % 256;      abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
337      abyHeader[9] = psDBF->nHeaderLength / 256;      abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
338            
339      abyHeader[10] = psDBF->nRecordLength % 256;      abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
340      abyHeader[11] = psDBF->nRecordLength / 256;      abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
341    
342            abyHeader[29] = (unsigned char) (psDBF->nLanguageDriver);
343    
344  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
345  /*      Write the initial 32 byte file header, and all the field        */  /*      Write the initial 32 byte file header, and all the field        */
# Line 278  static void DBFFlushRecord( DBFHandle ps Line 385  static void DBFFlushRecord( DBFHandle ps
385  }  }
386    
387  /************************************************************************/  /************************************************************************/
388    /*                          DBFUpdateHeader()                           */
389    /************************************************************************/
390    
391    void SHPAPI_CALL
392    DBFUpdateHeader( DBFHandle psDBF )
393    
394    {
395        unsigned char               abyFileHeader[32];
396    
397        if( psDBF->bNoHeader )
398            DBFWriteHeader( psDBF );
399    
400        DBFFlushRecord( psDBF );
401    
402        fseek( psDBF->fp, 0, 0 );
403        fread( abyFileHeader, 32, 1, psDBF->fp );
404        
405        abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
406        abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);
407        abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);
408        abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);
409        
410        fseek( psDBF->fp, 0, 0 );
411        fwrite( abyFileHeader, 32, 1, psDBF->fp );
412    
413        fflush( psDBF->fp );
414    }
415    
416    /************************************************************************/
417  /*                              DBFOpen()                               */  /*                              DBFOpen()                               */
418  /*                                                                      */  /*                                                                      */
419  /*      Open a .dbf file.                                               */  /*      Open a .dbf file.                                               */
# Line 287  DBFHandle SHPAPI_CALL Line 423  DBFHandle SHPAPI_CALL
423  DBFOpen( const char * pszFilename, const char * pszAccess )  DBFOpen( const char * pszFilename, const char * pszAccess )
424    
425  {  {
426      DBFHandle           psDBF;          FILE*           fp;
427      unsigned char               *pabyBuf;      int                 i;
     int                 nFields, nRecords, nHeadLen, nRecLen, iField, i;  
428      char                *pszBasename, *pszFullname;      char                *pszBasename, *pszFullname;
429    
430  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
# Line 323  DBFOpen( const char * pszFilename, const Line 458  DBFOpen( const char * pszFilename, const
458      pszFullname = (char *) malloc(strlen(pszBasename) + 5);      pszFullname = (char *) malloc(strlen(pszBasename) + 5);
459      sprintf( pszFullname, "%s.dbf", pszBasename );      sprintf( pszFullname, "%s.dbf", pszBasename );
460                    
461      psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );      fp = fopen( pszFullname, pszAccess );
     psDBF->fp = fopen( pszFullname, pszAccess );  
462    
463      if( psDBF->fp == NULL )      if( fp == NULL )
464      {      {
465          sprintf( pszFullname, "%s.DBF", pszBasename );          sprintf( pszFullname, "%s.DBF", pszBasename );
466          psDBF->fp = fopen(pszFullname, pszAccess );          fp = fopen(pszFullname, pszAccess );
467      }      }
468            
469      free( pszBasename );      free( pszBasename );
470      free( pszFullname );      free( pszFullname );
471        
472      if( psDBF->fp == NULL )          return DBFOpenEx( fp );
473      {  }
474          free( psDBF );  
475    
476    
477    /************************************************************************/
478    /*                              DBFOpenW()                              */
479    /*                                                                      */
480    /*      Open a .dbf file with a wide character filename                 */
481    /************************************************************************/
482    
483    #ifdef SHPAPI_HAS_WIDE
484    
485    DBFHandle SHPAPI_CALL
486    DBFOpenW( const wchar_t * pszFilename, const wchar_t * pszAccess )
487    
488    {
489        FILE*               fp;
490        int                 i;
491        wchar_t             *pszBasename, *pszFullname;
492    
493    /* -------------------------------------------------------------------- */
494    /*      We only allow the access strings "rb" and "r+".                  */
495    /* -------------------------------------------------------------------- */
496        if( wcscmp(pszAccess,L"r") != 0 && wcscmp(pszAccess,L"r+") != 0
497            && wcscmp(pszAccess,L"rb") != 0 && wcscmp(pszAccess,L"rb+") != 0
498            && wcscmp(pszAccess,L"r+b") != 0 )
499          return( NULL );          return( NULL );
500    
501        if( wcscmp(pszAccess,L"r") == 0 )
502            pszAccess = L"rb";
503    
504        if( wcscmp(pszAccess,L"r+") == 0 )
505            pszAccess = L"rb+";
506    
507    /* -------------------------------------------------------------------- */
508    /*      Compute the base (layer) name.  If there is any extension       */
509    /*      on the passed in filename we will strip it off.                 */
510    /* -------------------------------------------------------------------- */
511        pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszFilename)+5));
512        wcscpy( pszBasename, pszFilename );
513        for( i = wcslen(pszBasename)-1;
514             i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/'
515                   && pszBasename[i] != L'\\';
516             i-- ) {}
517    
518        if( pszBasename[i] == L'.' )
519            pszBasename[i] = L'\0';
520    
521        pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5));
522        swprintf( pszFullname, L"%s.dbf", pszBasename );
523            
524        fp = _wfopen( pszFullname, pszAccess );
525    
526        if( fp == NULL )
527        {
528            swprintf( pszFullname, L"%s.DBF", pszBasename );
529            fp = _wfopen(pszFullname, pszAccess );
530      }      }
531        
532        free( pszBasename );
533        free( pszFullname );
534    
535            return DBFOpenEx( fp );
536    }
537    
538    #endif
539    
540    
541    
542    /************************************************************************/
543    /*                              DBFOpenEx()                             */
544    /*                                                                      */
545    /*      Open a .dbf file from a freshly opened FILE                     */
546    /************************************************************************/
547      
548    DBFHandle SHPAPI_CALL
549    DBFOpenEx( FILE* fp )
550    
551    {
552        unsigned char       *pabyBuf;
553        int                 nFields, nHeadLen, nRecLen, iField;
554            DBFHandle       psDBF = NULL;
555    
556            if( fp == NULL )
557            {
558                    return( NULL );
559            }
560    
561        psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );
562            psDBF->fp = fp;
563    
564      psDBF->bNoHeader = FALSE;      psDBF->bNoHeader = FALSE;
565      psDBF->nCurrentRecord = -1;      psDBF->nCurrentRecord = -1;
# Line 349  DBFOpen( const char * pszFilename, const Line 569  DBFOpen( const char * pszFilename, const
569  /*  Read Table Header info                                              */  /*  Read Table Header info                                              */
570  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
571      pabyBuf = (unsigned char *) malloc(500);      pabyBuf = (unsigned char *) malloc(500);
572      fread( pabyBuf, 32, 1, psDBF->fp );      if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )
573        {
574            fclose( psDBF->fp );
575            free( pabyBuf );
576            free( psDBF );
577            return NULL;
578        }
579    
580      psDBF->nRecords = nRecords =      psDBF->nRecords =
581       pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;       pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
582    
583      psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;      psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
584      psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;      psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
585            psDBF->nLanguageDriver = pabyBuf[29];
586            
587      psDBF->nFields = nFields = (nHeadLen - 32) / 32;      psDBF->nFields = nFields = (nHeadLen - 32) / 32;
588    
# Line 369  DBFOpen( const char * pszFilename, const Line 596  DBFOpen( const char * pszFilename, const
596      psDBF->pszHeader = (char *) pabyBuf;      psDBF->pszHeader = (char *) pabyBuf;
597    
598      fseek( psDBF->fp, 32, 0 );      fseek( psDBF->fp, 32, 0 );
599      fread( pabyBuf, nHeadLen, 1, psDBF->fp );      if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 )
600        {
601            fclose( psDBF->fp );
602            free( pabyBuf );
603            free( psDBF );
604            return NULL;
605        }
606    
607      psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields);      psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields);
608      psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields);      psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields);
# Line 411  DBFOpen( const char * pszFilename, const Line 644  DBFOpen( const char * pszFilename, const
644  void SHPAPI_CALL  void SHPAPI_CALL
645  DBFClose(DBFHandle psDBF)  DBFClose(DBFHandle psDBF)
646  {  {
647            if( psDBF == NULL )
648                    return;
649                    
650  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
651  /*      Write out header if not already written.                        */  /*      Write out header if not already written.                        */
652  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
# Line 424  DBFClose(DBFHandle psDBF) Line 660  DBFClose(DBFHandle psDBF)
660  /*      write access.                                                   */  /*      write access.                                                   */
661  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
662      if( psDBF->bUpdated )      if( psDBF->bUpdated )
663      {          DBFUpdateHeader( psDBF );
         unsigned char           abyFileHeader[32];  
   
         fseek( psDBF->fp, 0, 0 );  
         fread( abyFileHeader, 32, 1, psDBF->fp );  
   
         abyFileHeader[1] = 95;                  /* YY */  
         abyFileHeader[2] = 7;                   /* MM */  
         abyFileHeader[3] = 26;                  /* DD */  
   
         abyFileHeader[4] = psDBF->nRecords % 256;  
         abyFileHeader[5] = (psDBF->nRecords/256) % 256;  
         abyFileHeader[6] = (psDBF->nRecords/(256*256)) % 256;  
         abyFileHeader[7] = (psDBF->nRecords/(256*256*256)) % 256;  
   
         fseek( psDBF->fp, 0, 0 );  
         fwrite( abyFileHeader, 32, 1, psDBF->fp );  
     }  
664    
665  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
666  /*      Close, and free resources.                                      */  /*      Close, and free resources.                                      */
# Line 479  DBFHandle SHPAPI_CALL Line 698  DBFHandle SHPAPI_CALL
698  DBFCreate( const char * pszFilename )  DBFCreate( const char * pszFilename )
699    
700  {  {
     DBFHandle   psDBF;  
701      FILE        *fp;      FILE        *fp;
702      char        *pszFullname, *pszBasename;      char        *pszFullname, *pszBasename;
703      int         i;      int         i;
# Line 518  DBFCreate( const char * pszFilename ) Line 736  DBFCreate( const char * pszFilename )
736    
737      free( pszFullname );      free( pszFullname );
738    
739            return DBFCreateEx( fp );
740    }
741    
742    
743    
744    /************************************************************************/
745    /*                             DBFCreateW()                             */
746    /*                                                                      */
747    /*      Create a new .dbf file with a wide character filename           */
748    /************************************************************************/
749    
750    #ifdef SHPAPI_HAS_WIDE
751    
752    DBFHandle SHPAPI_CALL
753    DBFCreateW( const wchar_t * pszFilename )
754    
755    {
756        FILE        *fp;
757        wchar_t     *pszFullname, *pszBasename;
758        int         i;
759    
760    /* -------------------------------------------------------------------- */
761    /*      Compute the base (layer) name.  If there is any extension       */
762    /*      on the passed in filename we will strip it off.                 */
763    /* -------------------------------------------------------------------- */
764        pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszFilename)+5));
765        wcscpy( pszBasename, pszFilename );
766        for( i = wcslen(pszBasename)-1;
767             i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/'
768                   && pszBasename[i] != L'\\';
769             i-- ) {}
770    
771        if( pszBasename[i] == L'.' )
772            pszBasename[i] = L'\0';
773    
774        pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5));
775        swprintf( pszFullname, L"%s.dbf", pszBasename );
776        free( pszBasename );
777    
778    /* -------------------------------------------------------------------- */
779    /*      Create the file.                                                */
780    /* -------------------------------------------------------------------- */
781        fp = _wfopen( pszFullname, L"wb" );
782        if( fp == NULL )
783            return( NULL );
784    
785        fputc( 0, fp );
786        fclose( fp );
787    
788        fp = _wfopen( pszFullname, L"rb+" );
789        if( fp == NULL )
790            return( NULL );
791    
792        free( pszFullname );
793    
794            return DBFCreateEx( fp );
795    }
796    
797    #endif
798    
799    
800    /************************************************************************/
801    /*                             DBFCreateEx()                            */
802    /*                                                                      */
803    /*      Create a new .dbf file from a freshly created file              */
804    /************************************************************************/
805    
806    DBFHandle SHPAPI_CALL
807    DBFCreateEx( FILE* fp )
808    
809    {
810        DBFHandle   psDBF;
811    
812  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
813  /*      Create the info structure.                                      */  /*      Create the info structure.                                      */
814  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
# Line 540  DBFCreate( const char * pszFilename ) Line 831  DBFCreate( const char * pszFilename )
831      psDBF->pszCurrentRecord = NULL;      psDBF->pszCurrentRecord = NULL;
832    
833      psDBF->bNoHeader = TRUE;      psDBF->bNoHeader = TRUE;
834            psDBF->nLanguageDriver = 0x03; // ANSI
835    
836      return( psDBF );      return( psDBF );
837  }  }
838    
839    
840    
841  /************************************************************************/  /************************************************************************/
842  /*                            DBFAddField()                             */  /*                            DBFAddField()                             */
843  /*                                                                      */  /*                                                                      */
# Line 571  DBFAddField(DBFHandle psDBF, const char Line 865  DBFAddField(DBFHandle psDBF, const char
865      if( eType != FTDouble && nDecimals != 0 )      if( eType != FTDouble && nDecimals != 0 )
866          return( -1 );          return( -1 );
867    
868        if( nWidth < 1 )
869            return -1;
870    
871  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
872  /*      SfRealloc all the arrays larger to hold the additional field      */  /*      SfRealloc all the arrays larger to hold the additional field      */
873  /*      information.                                                    */  /*      information.                                                    */
# Line 597  DBFAddField(DBFHandle psDBF, const char Line 894  DBFAddField(DBFHandle psDBF, const char
894      psDBF->panFieldSize[psDBF->nFields-1] = nWidth;      psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
895      psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;      psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
896    
897      if( eType == FTString )      if( eType == FTLogical )
898            psDBF->pachFieldType[psDBF->nFields-1] = 'L';
899        else if( eType == FTString )
900          psDBF->pachFieldType[psDBF->nFields-1] = 'C';          psDBF->pachFieldType[psDBF->nFields-1] = 'C';
901      else      else
902          psDBF->pachFieldType[psDBF->nFields-1] = 'N';          psDBF->pachFieldType[psDBF->nFields-1] = 'N';
# Line 624  DBFAddField(DBFHandle psDBF, const char Line 923  DBFAddField(DBFHandle psDBF, const char
923    
924      if( eType == FTString )      if( eType == FTString )
925      {      {
926          pszFInfo[16] = nWidth % 256;          pszFInfo[16] = (unsigned char) (nWidth % 256);
927          pszFInfo[17] = nWidth / 256;          pszFInfo[17] = (unsigned char) (nWidth / 256);
928      }      }
929      else      else
930      {      {
931          pszFInfo[16] = nWidth;          pszFInfo[16] = (unsigned char) nWidth;
932          pszFInfo[17] = nDecimals;          pszFInfo[17] = (unsigned char) nDecimals;
933      }      }
934            
935  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
# Line 720  static void *DBFReadAttribute(DBFHandle Line 1019  static void *DBFReadAttribute(DBFHandle
1019  /* -------------------------------------------------------------------- */  /* -------------------------------------------------------------------- */
1020      if( chReqType == 'N' )      if( chReqType == 'N' )
1021      {      {
1022          dDoubleField = atof(pszStringField);          dDoubleField = (*atof_function)(pszStringField);
1023    
1024          pReturnField = &dDoubleField;          pReturnField = &dDoubleField;
1025      }      }
# Line 803  DBFReadStringAttribute( DBFHandle psDBF, Line 1102  DBFReadStringAttribute( DBFHandle psDBF,
1102  }  }
1103    
1104  /************************************************************************/  /************************************************************************/
1105    /*                        DBFReadLogicalAttribute()                     */
1106    /*                                                                      */
1107    /*      Read a logical attribute.                                       */
1108    /************************************************************************/
1109    
1110    const char SHPAPI_CALL1(*)
1111    DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField )
1112    
1113    {
1114        return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) );
1115    }
1116    
1117    /************************************************************************/
1118  /*                         DBFIsAttributeNULL()                         */  /*                         DBFIsAttributeNULL()                         */
1119  /*                                                                      */  /*                                                                      */
1120  /*      Return TRUE if value for field is NULL.                         */  /*      Return TRUE if value for field is NULL.                         */
# Line 818  DBFIsAttributeNULL( DBFHandle psDBF, int Line 1130  DBFIsAttributeNULL( DBFHandle psDBF, int
1130    
1131      pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );      pszValue = DBFReadStringAttribute( psDBF, iRecord, iField );
1132    
1133        if( pszValue == NULL )
1134            return TRUE;
1135    
1136      switch(psDBF->pachFieldType[iField])      switch(psDBF->pachFieldType[iField])
1137      {      {
1138        case 'N':        case 'N':
# Line 837  DBFIsAttributeNULL( DBFHandle psDBF, int Line 1152  DBFIsAttributeNULL( DBFHandle psDBF, int
1152          /* empty string fields are considered NULL */          /* empty string fields are considered NULL */
1153          return strlen(pszValue) == 0;          return strlen(pszValue) == 0;
1154      }      }
     return FALSE;  
1155  }  }
1156    
1157  /************************************************************************/  /************************************************************************/
# Line 896  DBFGetFieldInfo( DBFHandle psDBF, int iF Line 1210  DBFGetFieldInfo( DBFHandle psDBF, int iF
1210              pszFieldName[i] = '\0';              pszFieldName[i] = '\0';
1211      }      }
1212    
1213      if( psDBF->pachFieldType[iField] == 'N'      if ( psDBF->pachFieldType[iField] == 'L' )
1214          || psDBF->pachFieldType[iField] == 'F'          return( FTLogical);
1215          || psDBF->pachFieldType[iField] == 'D' )  
1216        else if( psDBF->pachFieldType[iField] == 'N'
1217                 || psDBF->pachFieldType[iField] == 'F'
1218                 || psDBF->pachFieldType[iField] == 'D' )
1219      {      {
1220          if( psDBF->panFieldDecimals[iField] > 0 )          if( psDBF->panFieldDecimals[iField] > 0 )
1221              return( FTDouble );              return( FTDouble );
# Line 921  static int DBFWriteAttribute(DBFHandle p Line 1238  static int DBFWriteAttribute(DBFHandle p
1238                               void * pValue )                               void * pValue )
1239    
1240  {  {
1241      int         nRecordOffset, i, j;      int         nRecordOffset, i, j, nRetResult = TRUE;
1242      unsigned char       *pabyRec;      unsigned char       *pabyRec;
1243      char        szSField[400], szFormat[20];      char        szSField[400], szFormat[20];
1244    
# Line 1024  static int DBFWriteAttribute(DBFHandle p Line 1341  static int DBFWriteAttribute(DBFHandle p
1341              sprintf( szFormat, "%%%dd", nWidth );              sprintf( szFormat, "%%%dd", nWidth );
1342              sprintf(szSField, szFormat, (int) *((double *) pValue) );              sprintf(szSField, szFormat, (int) *((double *) pValue) );
1343              if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )              if( (int)strlen(szSField) > psDBF->panFieldSize[iField] )
1344                {
1345                  szSField[psDBF->panFieldSize[iField]] = '\0';                  szSField[psDBF->panFieldSize[iField]] = '\0';
1346                    nRetResult = FALSE;
1347                }
1348    
1349              strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),              strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1350                      szSField, strlen(szSField) );                      szSField, strlen(szSField) );
# Line 1040  static int DBFWriteAttribute(DBFHandle p Line 1360  static int DBFWriteAttribute(DBFHandle p
1360                       nWidth, psDBF->panFieldDecimals[iField] );                       nWidth, psDBF->panFieldDecimals[iField] );
1361              sprintf(szSField, szFormat, *((double *) pValue) );              sprintf(szSField, szFormat, *((double *) pValue) );
1362              if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )              if( (int) strlen(szSField) > psDBF->panFieldSize[iField] )
1363                {
1364                  szSField[psDBF->panFieldSize[iField]] = '\0';                  szSField[psDBF->panFieldSize[iField]] = '\0';
1365                    nRetResult = FALSE;
1366                }
1367              strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),              strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1368                      szSField, strlen(szSField) );                      szSField, strlen(szSField) );
1369          }          }
1370          break;          break;
1371    
1372          case 'L':
1373            if (psDBF->panFieldSize[iField] >= 1  &&
1374                (*(char*)pValue == 'F' || *(char*)pValue == 'T'))
1375                *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue;
1376            break;
1377    
1378        default:        default:
1379          if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )          if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1380            {
1381              j = psDBF->panFieldSize[iField];              j = psDBF->panFieldSize[iField];
1382                nRetResult = FALSE;
1383            }
1384          else          else
1385          {          {
1386              memset( pabyRec+psDBF->panFieldOffset[iField], ' ',              memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
# Line 1061  static int DBFWriteAttribute(DBFHandle p Line 1393  static int DBFWriteAttribute(DBFHandle p
1393          break;          break;
1394      }      }
1395    
1396        return( nRetResult );
1397    }
1398    
1399    /************************************************************************/
1400    /*                     DBFWriteAttributeDirectly()                      */
1401    /*                                                                      */
1402    /*      Write an attribute record to the file, but without any          */
1403    /*      reformatting based on type.  The provided buffer is written     */
1404    /*      as is to the field position in the record.                      */
1405    /************************************************************************/
1406    
1407    int SHPAPI_CALL
1408    DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField,
1409                                  void * pValue )
1410    
1411    {
1412        int         nRecordOffset, i, j;
1413        unsigned char       *pabyRec;
1414    
1415    /* -------------------------------------------------------------------- */
1416    /*      Is this a valid record?                                         */
1417    /* -------------------------------------------------------------------- */
1418        if( hEntity < 0 || hEntity > psDBF->nRecords )
1419            return( FALSE );
1420    
1421        if( psDBF->bNoHeader )
1422            DBFWriteHeader(psDBF);
1423    
1424    /* -------------------------------------------------------------------- */
1425    /*      Is this a brand new record?                                     */
1426    /* -------------------------------------------------------------------- */
1427        if( hEntity == psDBF->nRecords )
1428        {
1429            DBFFlushRecord( psDBF );
1430    
1431            psDBF->nRecords++;
1432            for( i = 0; i < psDBF->nRecordLength; i++ )
1433                psDBF->pszCurrentRecord[i] = ' ';
1434    
1435            psDBF->nCurrentRecord = hEntity;
1436        }
1437    
1438    /* -------------------------------------------------------------------- */
1439    /*      Is this an existing record, but different than the last one     */
1440    /*      we accessed?                                                    */
1441    /* -------------------------------------------------------------------- */
1442        if( psDBF->nCurrentRecord != hEntity )
1443        {
1444            DBFFlushRecord( psDBF );
1445    
1446            nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength;
1447    
1448            fseek( psDBF->fp, nRecordOffset, 0 );
1449            fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp );
1450    
1451            psDBF->nCurrentRecord = hEntity;
1452        }
1453    
1454        pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
1455    
1456    /* -------------------------------------------------------------------- */
1457    /*      Assign all the record fields.                                   */
1458    /* -------------------------------------------------------------------- */
1459        if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] )
1460            j = psDBF->panFieldSize[iField];
1461        else
1462        {
1463            memset( pabyRec+psDBF->panFieldOffset[iField], ' ',
1464                    psDBF->panFieldSize[iField] );
1465            j = strlen((char *) pValue);
1466        }
1467    
1468        strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]),
1469                (char *) pValue, j );
1470    
1471        psDBF->bCurrentRecordModified = TRUE;
1472        psDBF->bUpdated = TRUE;
1473    
1474      return( TRUE );      return( TRUE );
1475  }  }
1476    
# Line 1122  DBFWriteNULLAttribute( DBFHandle psDBF, Line 1532  DBFWriteNULLAttribute( DBFHandle psDBF,
1532  }  }
1533    
1534  /************************************************************************/  /************************************************************************/
1535    /*                      DBFWriteLogicalAttribute()                      */
1536    /*                                                                      */
1537    /*      Write a logical attribute.                                      */
1538    /************************************************************************/
1539    
1540    int SHPAPI_CALL
1541    DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField,
1542                           const char lValue)
1543    
1544    {
1545        return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) );
1546    }
1547    
1548    /************************************************************************/
1549  /*                         DBFWriteTuple()                              */  /*                         DBFWriteTuple()                              */
1550  /*                                                                      */  /*                                                                      */
1551  /*      Write an attribute record to the file.                          */  /*      Write an attribute record to the file.                          */
# Line 1241  DBFCloneEmpty(DBFHandle psDBF, const cha Line 1665  DBFCloneEmpty(DBFHandle psDBF, const cha
1665      DBFHandle   newDBF;      DBFHandle   newDBF;
1666    
1667     newDBF = DBFCreate ( pszFilename );     newDBF = DBFCreate ( pszFilename );
1668     if ( newDBF == NULL ) return ( NULL );     if ( newDBF == NULL ) return ( NULL );
1669    
1670       DBFCloneEmptyEx( psDBF, newDBF );
1671    
1672       DBFClose( newDBF );      
1673       newDBF = DBFOpen ( pszFilename, "rb+" );
1674    
1675       return ( newDBF );
1676    }
1677    
1678    
1679    
1680    
1681    /************************************************************************/
1682    /*                          DBFCloneEmptyW                              */
1683    /*                                                                      */
1684    /*      Read one of the attribute fields of a record.                   */
1685    /************************************************************************/
1686    
1687    #ifdef SHPAPI_HAS_WIDE
1688    
1689    DBFHandle SHPAPI_CALL
1690    DBFCloneEmptyW(DBFHandle psDBF, const wchar_t * pszFilename )
1691    {
1692        DBFHandle   newDBF;
1693    
1694       newDBF = DBFCreateW ( pszFilename );
1695       if ( newDBF == NULL ) return ( NULL );
1696    
1697       DBFCloneEmptyEx( psDBF, newDBF );
1698    
1699       DBFClose( newDBF );      
1700       newDBF = DBFOpenW ( pszFilename, L"rb+" );
1701    
1702       return ( newDBF );
1703    }
1704    
1705    #endif
1706    
1707    /************************************************************************/
1708    /*                          DBFCloneEmptyEx()                           */
1709    /*                                                                      */
1710    /*      Read one of the attribute fields of a record.                   */
1711    /************************************************************************/
1712    
1713    void SHPAPI_CALL
1714    DBFCloneEmptyEx(DBFHandle psDBF, DBFHandle newDBF)
1715    {
1716       if ( newDBF == NULL ) return;
1717        
1718     newDBF->pszHeader = (void *) malloc ( 32 * psDBF->nFields );     newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields );
1719     memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );     memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields );
1720        
1721     newDBF->nFields = psDBF->nFields;     newDBF->nFields = psDBF->nFields;
1722     newDBF->nRecordLength = psDBF->nRecordLength;     newDBF->nRecordLength = psDBF->nRecordLength;
1723     newDBF->nHeaderLength = psDBF->nHeaderLength;     newDBF->nHeaderLength = 32 * (psDBF->nFields+1);
1724            
1725     newDBF->panFieldOffset = (void *) malloc ( sizeof(int) * psDBF->nFields );     newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields );
1726     memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );     memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
1727     newDBF->panFieldSize = (void *) malloc ( sizeof(int) * psDBF->nFields );     newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields );
1728     memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );     memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
1729     newDBF->panFieldDecimals = (void *) malloc ( sizeof(int) * psDBF->nFields );     newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields );
1730     memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );     memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
1731     newDBF->pachFieldType = (void *) malloc ( sizeof(int) * psDBF->nFields );     newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields );
1732     memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );     memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields );
1733    
1734     newDBF->bNoHeader = TRUE;     newDBF->bNoHeader = TRUE;
1735     newDBF->bUpdated = TRUE;     newDBF->bUpdated = TRUE;
1736        
1737     DBFWriteHeader ( newDBF );     DBFWriteHeader ( newDBF );
    DBFClose ( newDBF );  
     
    newDBF = DBFOpen ( pszFilename, "rb+" );  
   
    return ( newDBF );  
1738  }  }
1739    
1740  /************************************************************************/  /************************************************************************/
# Line 1304  static void str_to_upper (char *string) Line 1771  static void str_to_upper (char *string)
1771    
1772      while (++i < len)      while (++i < len)
1773          if (isalpha(string[i]) && islower(string[i]))          if (isalpha(string[i]) && islower(string[i]))
1774              string[i] = toupper ((int)string[i]);              string[i] = (char) toupper ((int)string[i]);
1775  }  }
1776    
1777  /************************************************************************/  /************************************************************************/
# Line 1323  DBFGetFieldIndex(DBFHandle psDBF, const Line 1790  DBFGetFieldIndex(DBFHandle psDBF, const
1790      int           i;      int           i;
1791    
1792      strncpy(name1, pszFieldName,11);      strncpy(name1, pszFieldName,11);
1793        name1[11] = '\0';
1794      str_to_upper(name1);      str_to_upper(name1);
1795    
1796      for( i = 0; i < DBFGetFieldCount(psDBF); i++ )      for( i = 0; i < DBFGetFieldCount(psDBF); i++ )
# Line 1336  DBFGetFieldIndex(DBFHandle psDBF, const Line 1804  DBFGetFieldIndex(DBFHandle psDBF, const
1804      }      }
1805      return(-1);      return(-1);
1806  }  }
   
 /************************************************************************/  
 /*                          DBFCommit()                                 */  
 /*                                                                      */  
 /*      Write any changes made into the file.                           */  
 /*                                                                      */  
 /************************************************************************/  
 int SHPAPI_CALL  
 DBFCommit( DBFHandle psDBF )  
   
 {  
     DBFFlushRecord( psDBF );  
     if (fflush( psDBF->fp ) == EOF)  
         return FALSE;  
   
     return TRUE;  
 }  

Legend:
Removed from v.1612  
changed lines
  Added in v.2752

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26