[prev in list] [next in list] [prev in thread] [next in thread] 

List:       postgis-users
Subject:    Re: [postgis-users] Read file encoding from from shape file
From:       Peter Hopfgartner <peter.hopfgartner () r3-gis ! com>
Date:       2010-03-25 17:18:20
Message-ID: 4BAB9ADC.6050606 () r3-gis ! com
[Download RAW message or body]

Well, I've started to compare the version in PostGIS with that from 
shapelib, dated 2003-07-08 (that should be approx the date of the fork). 
I've run indent on those files, so that diff produces less noise caused 
by changing white spaces.

In the PostGIS version are:

 1) a lot of added casts to unsigned int
 2) some bug fixes, which I would be cautious to port, since the same 
bugs may have been fixed in the main shapelib
 3) 2 new functions: DBFReadDeleted and DBFReadSetup. Here I'm not sure 
what really happens here.
 4) support for date. This seems to be easy and I've posted the diffs to 
the shapelib mailing list.

The diff between current PostGIS version and those of Shapefile dated 
2003-07-08 are attached.

Regards,

Peter

Paul Ramsey wrote:
> Yes, there's patches to our shapelib that don't exist in the mainline.
> The process needs to identify our changes to feed back to mainline,
> update mainline, then bring that in.
>
> P.
>
> On Sat, Mar 20, 2010 at 3:41 PM, Peter Hopfgartner
> <peter.hopfgartner@r3-gis.com> wrote:
>   
>> Paul Ramsey wrote:
>>     
>>> I was never certain that ESRI software actually respected the DBF code
>>> page flags, but your reference indicates they do, so this seems
>>> reasonable. Some investigation of the current state of shapelib WRT
>>> encoding would be wise, as I think we should update our shapelib to
>>> the current version when we release 2.0.
>>>
>>> P.
>>>
>>>
>>>       
>> I had a look if it was quick deal to upgrade to current shapelib. I copied
>> dbfopen.c, shpopen.c and shapefil.h from a currrent the shapelib checkout.
>> Unfortunatly, it seems to me that date handling has disappeared from
>> shapelib. At least FTDate is not defined anymore and in DBFOpen no 'D' is
>> assigned as field type.
>>
>> Am I missing something obvious here?
>>
>> Regards,
>>
>> Peter
>>     
>>> On Fri, Feb 26, 2010 at 5:55 AM, Peter Hopfgartner
>>> <peter.hopfgartner@r3-gis.com> wrote:
>>>
>>>       
>>>> Hi
>>>>
>>>> Looking into the sources of shp2pgsql, [0], it seems that the loader
>>>> assumes
>>>> that the encoding of the dbf file is  "WINDOWS-1252", if not specified
>>>> differently by the -W command line option.
>>>>
>>>> From [1], shape files carry some information about their encoding, either
>>>> in
>>>> the dbf file header at byte position 29, [2], or in a separate file with
>>>> extension CPG.
>>>>
>>>> Would it make sense to change the default behaviour of shp2pgsql into:
>>>>
>>>> 1) try to get file encoding from dbf file or cpg file
>>>> 2) if 1) fails, take WINDOWS-1252 as default
>>>> 3) if -W is given, take this option
>>>>
>>>> And then, is the information about the encoding set by pgsql2shp? It
>>>> would
>>>> be smooth, if shapes generated by pgsql2shp could be imported by
>>>> shp2pgsql
>>>> without specifying any encoding during import ("just works").
>>>>
>>>> Regards,
>>>>
>>>> Peter
>>>>
>>>> [0] http://trac.osgeo.org/postgis/browser/trunk/loader/
>>>> [1]
>>>>
>>>> http://support.esri.com/index.cfm?fa=knowledgebase.techArticles.articleShow&d=21106
>>>> [2] http://www.dbase.com/knowledgebase/int/db7_file_fmt.htm
>>>>
>>>> --
>>>>
>>>> Dott. Peter Hopfgartner
>>>>
>>>> R3 GIS Srl - GmbH
>>>> Via Johann Kravogl-Str. 2
>>>> I-39012 Meran/Merano (BZ)
>>>> Email: peter.hopfgartner@r3-gis.com
>>>> Tel. : +39 0473 494949
>>>> Fax  : +39 0473 069902
>>>> www  : http://www.r3-gis.com
>>>>
>>>> XING : http://www.xing.com/go/invita/8917535
>>>> _______________________________________________
>>>> postgis-users mailing list
>>>> postgis-users@postgis.refractions.net
>>>> http://postgis.refractions.net/mailman/listinfo/postgis-users
>>>>
>>>>
>>>>         
>>> _______________________________________________
>>> postgis-users mailing list
>>> postgis-users@postgis.refractions.net
>>> http://postgis.refractions.net/mailman/listinfo/postgis-users
>>>
>>>
>>>       
>> --
>>
>> Dott. Peter Hopfgartner
>>
>> R3 GIS Srl - GmbH
>> Via Johann Kravogl-Str. 2
>> I-39012 Meran/Merano (BZ)
>> Email: peter.hopfgartner@r3-gis.com
>> Tel. : +39 0473 494949
>> Fax  : +39 0473 069902
>> www  : http://www.r3-gis.com
>>
>> XING : http://www.xing.com/go/invita/8917535
>> _______________________________________________
>> postgis-users mailing list
>> postgis-users@postgis.refractions.net
>> http://postgis.refractions.net/mailman/listinfo/postgis-users
>>
>>     
> _______________________________________________
> postgis-users mailing list
> postgis-users@postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users
>
>   


-- 
 
Dott. Peter Hopfgartner
 
R3 GIS Srl - GmbH
Via Johann Kravogl-Str. 2
I-39012 Meran/Merano (BZ)
Email: peter.hopfgartner@r3-gis.com
Tel. : +39 0473 494949
Fax  : +39 0473 069902
www  : http://www.r3-gis.com

XING : http://www.xing.com/go/invita/8917535 


["dbfopen.c.diff" (text/x-patch)]

*** dbfopen.c	2010-03-25 17:30:34.355819107 +0100
--- ../postgis-svn/loader/dbfopen.c.orig	2010-03-25 17:05:18.785815799 +0100
***************
*** 1,5 ****
  /******************************************************************************
!  * $Id: dbfopen.c,v 1.50 2003-04-21 18:58:25 warmerda Exp $
   *
   * Project:  Shapelib
   * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
--- 1,5 ----
  /******************************************************************************
!  * $Id: dbfopen.c 5181 2010-02-01 17:35:55Z pramsey $
   *
   * Project:  Shapelib
   * Purpose:  Implementation of .dbf access API documented in dbf_api.html.
***************
*** 13,19 ****
   * option is discussed in more detail in shapelib.html.
   *
   * --
!  * 
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
--- 13,19 ----
   * option is discussed in more detail in shapelib.html.
   *
   * --
!  *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
***************
*** 33,40 ****
   * DEALINGS IN THE SOFTWARE.
   ******************************************************************************
   *
!  * $Log: dbfopen.c,v $
!  * Revision 1.50  2003-04-21 18:58:25  warmerda
   * ensure current record is flushed at same time as header is updated
   *
   * Revision 1.49  2003/04/21 18:30:37  warmerda
--- 33,55 ----
   * DEALINGS IN THE SOFTWARE.
   ******************************************************************************
   *
!  * $Log$
!  * Revision 1.8  2006/01/16 10:42:57  strk
!  * Added support for Bool and Date DBF<=>PGIS mapping
!  *
!  * Revision 1.7  2006/01/09 16:40:16  strk
!  * ISO C90 comments, signedness mismatch fixes
!  *
!  * Revision 1.6  2003/12/01 20:52:00  strk
!  * shapelib put in sync with gdal cvs
!  *
!  * Revision 1.52  2003/07/08 15:20:03  warmerda
!  * avoid warnings about downcasting to unsigned char
!  *
!  * Revision 1.51  2003/07/08 13:50:15  warmerda
!  * DBFIsAttributeNULL check for pszValue==NULL - bug 360
!  *
!  * Revision 1.50  2003/04/21 18:58:25  warmerda
   * ensure current record is flushed at same time as header is updated
   *
   * Revision 1.49  2003/04/21 18:30:37  warmerda
***************
*** 188,196 ****
   * Added header.
   */
  
- static char rcsid[] =
-   "$Id: dbfopen.c,v 1.50 2003-04-21 18:58:25 warmerda Exp $";
- 
  #include "shapefil.h"
  
  #include <math.h>
--- 203,208 ----
***************
*** 242,250 ****
  
    psDBF->bNoHeader = FALSE;
  
! /* -------------------------------------------------------------------- */
! /*	Initialize the file header information.				*/
! /* -------------------------------------------------------------------- */
    for (i = 0; i < XBASE_FLDHDR_SZ; i++)
      abyHeader[i] = 0;
  
--- 254,262 ----
  
    psDBF->bNoHeader = FALSE;
  
!   /* -------------------------------------------------------------------- */
!   /*      Initialize the file header information.                         */
!   /* -------------------------------------------------------------------- */
    for (i = 0; i < XBASE_FLDHDR_SZ; i++)
      abyHeader[i] = 0;
  
***************
*** 257,279 ****
  
    /* record count preset at zero */
  
!   abyHeader[8] = psDBF->nHeaderLength % 256;
!   abyHeader[9] = psDBF->nHeaderLength / 256;
  
!   abyHeader[10] = psDBF->nRecordLength % 256;
!   abyHeader[11] = psDBF->nRecordLength / 256;
  
! /* -------------------------------------------------------------------- */
! /*      Write the initial 32 byte file header, and all the field        */
! /*      descriptions.                                     		*/
! /* -------------------------------------------------------------------- */
    fseek (psDBF->fp, 0, 0);
    fwrite (abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp);
    fwrite (psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp);
  
! /* -------------------------------------------------------------------- */
! /*      Write out the newline character if there is room for it.        */
! /* -------------------------------------------------------------------- */
    if (psDBF->nHeaderLength > 32 * psDBF->nFields + 32)
      {
        char cNewline;
--- 269,291 ----
  
    /* record count preset at zero */
  
!   abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);
!   abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);
  
!   abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);
!   abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);
  
!   /* -------------------------------------------------------------------- */
!   /*      Write the initial 32 byte file header, and all the field        */
!   /*      descriptions.                                                   */
!   /* -------------------------------------------------------------------- */
    fseek (psDBF->fp, 0, 0);
    fwrite (abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp);
    fwrite (psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp);
  
!   /* -------------------------------------------------------------------- */
!   /*      Write out the newline character if there is room for it.        */
!   /* -------------------------------------------------------------------- */
    if (psDBF->nHeaderLength > 32 * psDBF->nFields + 32)
      {
        char cNewline;
***************
*** 323,332 ****
    fseek (psDBF->fp, 0, 0);
    fread (abyFileHeader, 32, 1, psDBF->fp);
  
!   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);
--- 335,345 ----
    fseek (psDBF->fp, 0, 0);
    fread (abyFileHeader, 32, 1, psDBF->fp);
  
!   abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);
!   abyFileHeader[5] = (unsigned char) ((psDBF->nRecords / 256) % 256);
!   abyFileHeader[6] = (unsigned char) ((psDBF->nRecords / (256 * 256)) % 256);
!   abyFileHeader[7] =
!     (unsigned char) ((psDBF->nRecords / (256 * 256 * 256)) % 256);
  
    fseek (psDBF->fp, 0, 0);
    fwrite (abyFileHeader, 32, 1, psDBF->fp);
***************
*** 348,356 ****
    int nFields, nHeadLen, nRecLen, iField, i;
    char *pszBasename, *pszFullname;
  
! /* -------------------------------------------------------------------- */
! /*      We only allow the access strings "rb" and "r+".                  */
! /* -------------------------------------------------------------------- */
    if (strcmp (pszAccess, "r") != 0 && strcmp (pszAccess, "r+") != 0
        && strcmp (pszAccess, "rb") != 0 && strcmp (pszAccess, "rb+") != 0
        && strcmp (pszAccess, "r+b") != 0)
--- 361,369 ----
    int nFields, nHeadLen, nRecLen, iField, i;
    char *pszBasename, *pszFullname;
  
!   /* -------------------------------------------------------------------- */
!   /*      We only allow the access strings "rb" and "r+".                  */
!   /* -------------------------------------------------------------------- */
    if (strcmp (pszAccess, "r") != 0 && strcmp (pszAccess, "r+") != 0
        && strcmp (pszAccess, "rb") != 0 && strcmp (pszAccess, "rb+") != 0
        && strcmp (pszAccess, "r+b") != 0)
***************
*** 362,371 ****
    if (strcmp (pszAccess, "r+") == 0)
      pszAccess = "rb+";
  
! /* -------------------------------------------------------------------- */
! /*	Compute the base (layer) name.  If there is any extension	*/
! /*	on the passed in filename we will strip it off.			*/
! /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszFilename) + 5);
    strcpy (pszBasename, pszFilename);
    for (i = strlen (pszBasename) - 1;
--- 375,384 ----
    if (strcmp (pszAccess, "r+") == 0)
      pszAccess = "rb+";
  
!   /* -------------------------------------------------------------------- */
!   /*      Compute the base (layer) name.  If there is any extension       */
!   /*      on the passed in filename we will strip it off.                 */
!   /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszFilename) + 5);
    strcpy (pszBasename, pszFilename);
    for (i = strlen (pszBasename) - 1;
***************
*** 402,410 ****
    psDBF->nCurrentRecord = -1;
    psDBF->bCurrentRecordModified = FALSE;
  
! /* -------------------------------------------------------------------- */
! /*  Read Table Header info                                              */
! /* -------------------------------------------------------------------- */
    pabyBuf = (unsigned char *) malloc (500);
    if (fread (pabyBuf, 32, 1, psDBF->fp) != 1)
      {
--- 415,423 ----
    psDBF->nCurrentRecord = -1;
    psDBF->bCurrentRecordModified = FALSE;
  
!   /* -------------------------------------------------------------------- */
!   /*  Read Table Header info                                              */
!   /* -------------------------------------------------------------------- */
    pabyBuf = (unsigned char *) malloc (500);
    if (fread (pabyBuf, 32, 1, psDBF->fp) != 1)
      {
***************
*** 425,433 ****
  
    psDBF->pszCurrentRecord = (char *) malloc (nRecLen);
  
! /* -------------------------------------------------------------------- */
! /*  Read in Field Definitions                                           */
! /* -------------------------------------------------------------------- */
  
    pabyBuf = (unsigned char *) SfRealloc (pabyBuf, nHeadLen);
    psDBF->pszHeader = (char *) pabyBuf;
--- 438,446 ----
  
    psDBF->pszCurrentRecord = (char *) malloc (nRecLen);
  
!   /* -------------------------------------------------------------------- */
!   /*  Read in Field Definitions                                           */
!   /* -------------------------------------------------------------------- */
  
    pabyBuf = (unsigned char *) SfRealloc (pabyBuf, nHeadLen);
    psDBF->pszHeader = (char *) pabyBuf;
***************
*** 481,504 ****
  void SHPAPI_CALL
  DBFClose (DBFHandle psDBF)
  {
! /* -------------------------------------------------------------------- */
! /*      Write out header if not already written.                        */
! /* -------------------------------------------------------------------- */
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
    DBFFlushRecord (psDBF);
  
! /* -------------------------------------------------------------------- */
! /*      Update last access date, and number of records if we have	*/
! /*	write access.                					*/
! /* -------------------------------------------------------------------- */
    if (psDBF->bUpdated)
      DBFUpdateHeader (psDBF);
  
! /* -------------------------------------------------------------------- */
! /*      Close, and free resources.                                      */
! /* -------------------------------------------------------------------- */
    fclose (psDBF->fp);
  
    if (psDBF->panFieldOffset != NULL)
--- 494,532 ----
  void SHPAPI_CALL
  DBFClose (DBFHandle psDBF)
  {
!   static char eof = 0x1a;
!   char eof_test;
! 
!   /* -------------------------------------------------------------------- */
!   /*      Write out header if not already written.                        */
!   /* -------------------------------------------------------------------- */
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
    DBFFlushRecord (psDBF);
  
!   /* -------------------------------------------------------------------- */
!   /*      Update last access date, and number of records if we have       */
!   /*      write access.                                                   */
!   /* -------------------------------------------------------------------- */
    if (psDBF->bUpdated)
      DBFUpdateHeader (psDBF);
  
!   /* -------------------------------------------------------------------- */
!   /*  Add the DBF end-of-file marker after the last record.               */
!   /* -------------------------------------------------------------------- */
! 
!   fseek (psDBF->fp, -1, SEEK_END);
!   fread (&eof_test, 1, 1, psDBF->fp);
!   if (eof_test != 0x1a)		/* no EOF exists, so write one */
!     {
!       fseek (psDBF->fp, 0, SEEK_END);
!       fwrite (&eof, 1, 1, psDBF->fp);
!     }
! 
!   /* -------------------------------------------------------------------- */
!   /*      Close, and free resources.                                      */
!   /* -------------------------------------------------------------------- */
    fclose (psDBF->fp);
  
    if (psDBF->panFieldOffset != NULL)
***************
*** 536,545 ****
    char *pszFullname, *pszBasename;
    int i;
  
! /* -------------------------------------------------------------------- */
! /*	Compute the base (layer) name.  If there is any extension	*/
! /*	on the passed in filename we will strip it off.			*/
! /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszFilename) + 5);
    strcpy (pszBasename, pszFilename);
    for (i = strlen (pszBasename) - 1;
--- 564,573 ----
    char *pszFullname, *pszBasename;
    int i;
  
!   /* -------------------------------------------------------------------- */
!   /*      Compute the base (layer) name.  If there is any extension       */
!   /*      on the passed in filename we will strip it off.                 */
!   /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszFilename) + 5);
    strcpy (pszBasename, pszFilename);
    for (i = strlen (pszBasename) - 1;
***************
*** 555,563 ****
    sprintf (pszFullname, "%s.dbf", pszBasename);
    free (pszBasename);
  
! /* -------------------------------------------------------------------- */
! /*      Create the file.                                                */
! /* -------------------------------------------------------------------- */
    fp = fopen (pszFullname, "wb");
    if (fp == NULL)
      return (NULL);
--- 583,591 ----
    sprintf (pszFullname, "%s.dbf", pszBasename);
    free (pszBasename);
  
!   /* -------------------------------------------------------------------- */
!   /*      Create the file.                                                */
!   /* -------------------------------------------------------------------- */
    fp = fopen (pszFullname, "wb");
    if (fp == NULL)
      return (NULL);
***************
*** 571,579 ****
  
    free (pszFullname);
  
! /* -------------------------------------------------------------------- */
! /*	Create the info structure.					*/
! /* -------------------------------------------------------------------- */
    psDBF = (DBFHandle) malloc (sizeof (DBFInfo));
  
    psDBF->fp = fp;
--- 599,607 ----
  
    free (pszFullname);
  
!   /* -------------------------------------------------------------------- */
!   /*      Create the info structure.                                      */
!   /* -------------------------------------------------------------------- */
    psDBF = (DBFHandle) malloc (sizeof (DBFInfo));
  
    psDBF->fp = fp;
***************
*** 581,586 ****
--- 609,615 ----
    psDBF->nFields = 0;
    psDBF->nRecordLength = 1;
    psDBF->nHeaderLength = 33;
+   psDBF->bUpdated = FALSE;
  
    psDBF->panFieldOffset = NULL;
    psDBF->panFieldSize = NULL;
***************
*** 611,619 ****
    char *pszFInfo;
    int i;
  
! /* -------------------------------------------------------------------- */
! /*      Do some checking to ensure we can add records to this file.     */
! /* -------------------------------------------------------------------- */
    if (psDBF->nRecords > 0)
      return (-1);
  
--- 640,648 ----
    char *pszFInfo;
    int i;
  
!   /* -------------------------------------------------------------------- */
!   /*      Do some checking to ensure we can add records to this file.     */
!   /* -------------------------------------------------------------------- */
    if (psDBF->nRecords > 0)
      return (-1);
  
***************
*** 626,635 ****
    if (nWidth < 1)
      return -1;
  
! /* -------------------------------------------------------------------- */
! /*      SfRealloc all the arrays larger to hold the additional field      */
! /*      information.                                                    */
! /* -------------------------------------------------------------------- */
    psDBF->nFields++;
  
    psDBF->panFieldOffset = (int *)
--- 655,664 ----
    if (nWidth < 1)
      return -1;
  
!   /* -------------------------------------------------------------------- */
!   /*      SfRealloc all the arrays larger to hold the additional field      */
!   /*      information.                                                    */
!   /* -------------------------------------------------------------------- */
    psDBF->nFields++;
  
    psDBF->panFieldOffset = (int *)
***************
*** 644,652 ****
    psDBF->pachFieldType = (char *)
      SfRealloc (psDBF->pachFieldType, sizeof (char) * psDBF->nFields);
  
! /* -------------------------------------------------------------------- */
! /*      Assign the new field information fields.                        */
! /* -------------------------------------------------------------------- */
    psDBF->panFieldOffset[psDBF->nFields - 1] = psDBF->nRecordLength;
    psDBF->nRecordLength += nWidth;
    psDBF->panFieldSize[psDBF->nFields - 1] = nWidth;
--- 673,681 ----
    psDBF->pachFieldType = (char *)
      SfRealloc (psDBF->pachFieldType, sizeof (char) * psDBF->nFields);
  
!   /* -------------------------------------------------------------------- */
!   /*      Assign the new field information fields.                        */
!   /* -------------------------------------------------------------------- */
    psDBF->panFieldOffset[psDBF->nFields - 1] = psDBF->nRecordLength;
    psDBF->nRecordLength += nWidth;
    psDBF->panFieldSize[psDBF->nFields - 1] = nWidth;
***************
*** 656,667 ****
      psDBF->pachFieldType[psDBF->nFields - 1] = 'L';
    else if (eType == FTString)
      psDBF->pachFieldType[psDBF->nFields - 1] = 'C';
    else
      psDBF->pachFieldType[psDBF->nFields - 1] = 'N';
  
! /* -------------------------------------------------------------------- */
! /*      Extend the required header information.                         */
! /* -------------------------------------------------------------------- */
    psDBF->nHeaderLength += 32;
    psDBF->bUpdated = FALSE;
  
--- 685,698 ----
      psDBF->pachFieldType[psDBF->nFields - 1] = 'L';
    else if (eType == FTString)
      psDBF->pachFieldType[psDBF->nFields - 1] = 'C';
+   else if (eType == FTDate)
+     psDBF->pachFieldType[psDBF->nFields - 1] = 'D';
    else
      psDBF->pachFieldType[psDBF->nFields - 1] = 'N';
  
!   /* -------------------------------------------------------------------- */
!   /*      Extend the required header information.                         */
!   /* -------------------------------------------------------------------- */
    psDBF->nHeaderLength += 32;
    psDBF->bUpdated = FALSE;
  
***************
*** 682,732 ****
  
    if (eType == FTString)
      {
!       pszFInfo[16] = nWidth % 256;
!       pszFInfo[17] = nWidth / 256;
      }
    else
      {
!       pszFInfo[16] = nWidth;
!       pszFInfo[17] = nDecimals;
      }
  
! /* -------------------------------------------------------------------- */
! /*      Make the current record buffer appropriately larger.            */
! /* -------------------------------------------------------------------- */
    psDBF->pszCurrentRecord = (char *) SfRealloc (psDBF->pszCurrentRecord,
  						psDBF->nRecordLength);
  
    return (psDBF->nFields - 1);
  }
  
  /************************************************************************/
! /*                          DBFReadAttribute()                          */
  /*                                                                      */
! /*      Read one of the attribute fields of a record.                   */
  /************************************************************************/
  
! static void *
! DBFReadAttribute (DBFHandle psDBF, int hEntity, int iField, char chReqType)
  {
    int nRecordOffset;
-   unsigned char *pabyRec;
-   void *pReturnField = NULL;
- 
-   static double dDoubleField;
  
! /* -------------------------------------------------------------------- */
! /*      Verify selection.                                               */
! /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity >= psDBF->nRecords)
!     return (NULL);
! 
!   if (iField < 0 || iField >= psDBF->nFields)
!     return (NULL);
  
! /* -------------------------------------------------------------------- */
! /*	Have we read the record?					*/
! /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
--- 713,757 ----
  
    if (eType == FTString)
      {
!       pszFInfo[16] = (unsigned char) (nWidth % 256);
!       pszFInfo[17] = (unsigned char) (nWidth / 256);
      }
    else
      {
!       pszFInfo[16] = (unsigned char) nWidth;
!       pszFInfo[17] = (unsigned char) nDecimals;
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Make the current record buffer appropriately larger.            */
!   /* -------------------------------------------------------------------- */
    psDBF->pszCurrentRecord = (char *) SfRealloc (psDBF->pszCurrentRecord,
  						psDBF->nRecordLength);
  
    return (psDBF->nFields - 1);
  }
  
+ 
  /************************************************************************/
! /*                        DBFReadSetup()                                */
  /*                                                                      */
! /*      Prep a record for reading.                                      */
  /************************************************************************/
  
! int
! DBFReadSetup (DBFHandle psDBF, int hEntity)
  {
    int nRecordOffset;
  
!   /* -------------------------------------------------------------------- */
!   /*      Verify selection.                                               */
!   /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity >= psDBF->nRecords)
!     return (0);
  
!   /* -------------------------------------------------------------------- */
!   /*      Have we read the record?                                        */
!   /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
***************
*** 736,742 ****
        if (fseek (psDBF->fp, nRecordOffset, 0) != 0)
  	{
  	  fprintf (stderr, "fseek(%d) failed on DBF file.\n", nRecordOffset);
! 	  return NULL;
  	}
  
        if (fread (psDBF->pszCurrentRecord, psDBF->nRecordLength,
--- 761,767 ----
        if (fseek (psDBF->fp, nRecordOffset, 0) != 0)
  	{
  	  fprintf (stderr, "fseek(%d) failed on DBF file.\n", nRecordOffset);
! 	  return 0;
  	}
  
        if (fread (psDBF->pszCurrentRecord, psDBF->nRecordLength,
***************
*** 744,769 ****
  	{
  	  fprintf (stderr, "fread(%d) failed on DBF file.\n",
  		   psDBF->nRecordLength);
! 	  return NULL;
  	}
  
        psDBF->nCurrentRecord = hEntity;
      }
  
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
  
! /* -------------------------------------------------------------------- */
! /*	Ensure our field buffer is large enough to hold this buffer.	*/
! /* -------------------------------------------------------------------- */
    if (psDBF->panFieldSize[iField] + 1 > nStringFieldLen)
      {
        nStringFieldLen = psDBF->panFieldSize[iField] * 2 + 10;
        pszStringField = (char *) SfRealloc (pszStringField, nStringFieldLen);
      }
  
! /* -------------------------------------------------------------------- */
! /*	Extract the requested field.					*/
! /* -------------------------------------------------------------------- */
    strncpy (pszStringField,
  	   ((const char *) pabyRec) + psDBF->panFieldOffset[iField],
  	   psDBF->panFieldSize[iField]);
--- 769,845 ----
  	{
  	  fprintf (stderr, "fread(%d) failed on DBF file.\n",
  		   psDBF->nRecordLength);
! 	  return 0;
  	}
  
        psDBF->nCurrentRecord = hEntity;
      }
  
+   return 1;
+ 
+ }
+ 
+ 
+ /************************************************************************/
+ /*                        DBFReadDeleted()                              */
+ /*                                                                      */
+ /*      Read whether a record is deleted.                               */
+ /************************************************************************/
+ 
+ int
+ DBFReadDeleted (DBFHandle psDBF, int hEntity)
+ {
+   unsigned char *pabyRec;
+ 
+   if (!DBFReadSetup (psDBF, hEntity))
+     return 0;
+ 
+   /* get reference to current record */
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
  
!   /* 0x20 => not deleted, 0x24 => deleted */
!   return *pabyRec == 0x20 ? 0 : 1;
! 
! }
! 
! /************************************************************************/
! /*                          DBFReadAttribute()                          */
! /*                                                                      */
! /*      Read one of the attribute fields of a record.                   */
! /************************************************************************/
! 
! static void *
! DBFReadAttribute (DBFHandle psDBF, int hEntity, int iField, char chReqType)
! {
!   unsigned char *pabyRec;
!   void *pReturnField = NULL;
! 
!   static double dDoubleField;
! 
!   /* -------------------------------------------------------------------- */
!   /*      Verify selection.                                               */
!   /* -------------------------------------------------------------------- */
!   if (iField < 0 || iField >= psDBF->nFields)
!     return (NULL);
! 
!   if (!DBFReadSetup (psDBF, hEntity))
!     return (NULL);
! 
!   /* get reference to current record */
!   pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
! 
!   /* -------------------------------------------------------------------- */
!   /*      Ensure our field buffer is large enough to hold this buffer.          */
!   /* -------------------------------------------------------------------- */
    if (psDBF->panFieldSize[iField] + 1 > nStringFieldLen)
      {
        nStringFieldLen = psDBF->panFieldSize[iField] * 2 + 10;
        pszStringField = (char *) SfRealloc (pszStringField, nStringFieldLen);
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Extract the requested field.                                                            */
!   /* -------------------------------------------------------------------- */
    strncpy (pszStringField,
  	   ((const char *) pabyRec) + psDBF->panFieldOffset[iField],
  	   psDBF->panFieldSize[iField]);
***************
*** 771,789 ****
  
    pReturnField = pszStringField;
  
! /* -------------------------------------------------------------------- */
! /*      Decode the field.                                               */
! /* -------------------------------------------------------------------- */
    if (chReqType == 'N')
      {
        dDoubleField = atof (pszStringField);
- 
        pReturnField = &dDoubleField;
      }
  
! /* -------------------------------------------------------------------- */
! /*      Should we trim white space off the string attribute value?      */
! /* -------------------------------------------------------------------- */
  #ifdef TRIM_DBF_WHITESPACE
    else
      {
--- 847,864 ----
  
    pReturnField = pszStringField;
  
!   /* -------------------------------------------------------------------- */
!   /*      Decode the field.                                               */
!   /* -------------------------------------------------------------------- */
    if (chReqType == 'N')
      {
        dDoubleField = atof (pszStringField);
        pReturnField = &dDoubleField;
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Should we trim white space off the string attribute value?      */
!   /* -------------------------------------------------------------------- */
  #ifdef TRIM_DBF_WHITESPACE
    else
      {
***************
*** 884,889 ****
--- 959,967 ----
  
    pszValue = DBFReadStringAttribute (psDBF, iRecord, iField);
  
+   if (pszValue == NULL)
+     return TRUE;
+ 
    switch (psDBF->pachFieldType[iField])
      {
      case 'N':
***************
*** 893,899 ****
  
      case 'D':
        /* NULL date fields have value "00000000" */
!       return strncmp (pszValue, "00000000", 8) == 0;
  
      case 'L':
        /* NULL boolean fields have value "?" */
--- 971,978 ----
  
      case 'D':
        /* NULL date fields have value "00000000" */
!       return (strncmp (pszValue, "00000000", 8) == 0
! 	      || strlen (pszValue) == 0);
  
      case 'L':
        /* NULL boolean fields have value "?" */
***************
*** 961,969 ****
    if (psDBF->pachFieldType[iField] == 'L')
      return (FTLogical);
  
    else if (psDBF->pachFieldType[iField] == 'N'
! 	   || psDBF->pachFieldType[iField] == 'F'
! 	   || psDBF->pachFieldType[iField] == 'D')
      {
        if (psDBF->panFieldDecimals[iField] > 0)
  	return (FTDouble);
--- 1040,1050 ----
    if (psDBF->pachFieldType[iField] == 'L')
      return (FTLogical);
  
+   else if (psDBF->pachFieldType[iField] == 'D')
+     return (FTDate);
+ 
    else if (psDBF->pachFieldType[iField] == 'N'
! 	   || psDBF->pachFieldType[iField] == 'F')
      {
        if (psDBF->panFieldDecimals[iField] > 0)
  	return (FTDouble);
***************
*** 989,1006 ****
    unsigned char *pabyRec;
    char szSField[400], szFormat[20];
  
! /* -------------------------------------------------------------------- */
! /*	Is this a valid record?						*/
! /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity > psDBF->nRecords)
      return (FALSE);
  
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
! /* -------------------------------------------------------------------- */
! /*      Is this a brand new record?                                     */
! /* -------------------------------------------------------------------- */
    if (hEntity == psDBF->nRecords)
      {
        DBFFlushRecord (psDBF);
--- 1070,1087 ----
    unsigned char *pabyRec;
    char szSField[400], szFormat[20];
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this a valid record?                                         */
!   /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity > psDBF->nRecords)
      return (FALSE);
  
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this a brand new record?                                     */
!   /* -------------------------------------------------------------------- */
    if (hEntity == psDBF->nRecords)
      {
        DBFFlushRecord (psDBF);
***************
*** 1012,1021 ****
        psDBF->nCurrentRecord = hEntity;
      }
  
! /* -------------------------------------------------------------------- */
! /*      Is this an existing record, but different than the last one     */
! /*      we accessed?                                                    */
! /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
--- 1093,1102 ----
        psDBF->nCurrentRecord = hEntity;
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this an existing record, but different than the last one     */
!   /*      we accessed?                                                    */
!   /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
***************
*** 1033,1043 ****
    psDBF->bCurrentRecordModified = TRUE;
    psDBF->bUpdated = TRUE;
  
! /* -------------------------------------------------------------------- */
! /*      Translate NULL value to valid DBF file representation.          */
! /*                                                                      */
! /*      Contributed by Jim Matthews.                                    */
! /* -------------------------------------------------------------------- */
    if (pValue == NULL)
      {
        switch (psDBF->pachFieldType[iField])
--- 1114,1124 ----
    psDBF->bCurrentRecordModified = TRUE;
    psDBF->bUpdated = TRUE;
  
!   /* -------------------------------------------------------------------- */
!   /*      Translate NULL value to valid DBF file representation.          */
!   /*                                                                      */
!   /*      Contributed by Jim Matthews.                                    */
!   /* -------------------------------------------------------------------- */
    if (pValue == NULL)
      {
        switch (psDBF->pachFieldType[iField])
***************
*** 1070,1078 ****
        return TRUE;
      }
  
! /* -------------------------------------------------------------------- */
! /*      Assign all the record fields.                                   */
! /* -------------------------------------------------------------------- */
    switch (psDBF->pachFieldType[iField])
      {
      case 'D':
--- 1151,1159 ----
        return TRUE;
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Assign all the record fields.                                   */
!   /* -------------------------------------------------------------------- */
    switch (psDBF->pachFieldType[iField])
      {
      case 'D':
***************
*** 1153,1175 ****
  
  int
  DBFWriteAttributeDirectly (DBFHandle psDBF, int hEntity, int iField,
! 			   void *pValue)
  {
    int nRecordOffset, i, j;
    unsigned char *pabyRec;
  
! /* -------------------------------------------------------------------- */
! /*	Is this a valid record?						*/
! /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity > psDBF->nRecords)
      return (FALSE);
  
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
! /* -------------------------------------------------------------------- */
! /*      Is this a brand new record?                                     */
! /* -------------------------------------------------------------------- */
    if (hEntity == psDBF->nRecords)
      {
        DBFFlushRecord (psDBF);
--- 1234,1256 ----
  
  int
  DBFWriteAttributeDirectly (DBFHandle psDBF, int hEntity, int iField,
! 			   const void *pValue)
  {
    int nRecordOffset, i, j;
    unsigned char *pabyRec;
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this a valid record?                                         */
!   /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity > psDBF->nRecords)
      return (FALSE);
  
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this a brand new record?                                     */
!   /* -------------------------------------------------------------------- */
    if (hEntity == psDBF->nRecords)
      {
        DBFFlushRecord (psDBF);
***************
*** 1181,1190 ****
        psDBF->nCurrentRecord = hEntity;
      }
  
! /* -------------------------------------------------------------------- */
! /*      Is this an existing record, but different than the last one     */
! /*      we accessed?                                                    */
! /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
--- 1262,1271 ----
        psDBF->nCurrentRecord = hEntity;
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this an existing record, but different than the last one     */
!   /*      we accessed?                                                    */
!   /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
***************
*** 1199,1207 ****
  
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
  
! /* -------------------------------------------------------------------- */
! /*      Assign all the record fields.                                   */
! /* -------------------------------------------------------------------- */
    if ((int) strlen ((char *) pValue) > psDBF->panFieldSize[iField])
      j = psDBF->panFieldSize[iField];
    else
--- 1280,1288 ----
  
    pabyRec = (unsigned char *) psDBF->pszCurrentRecord;
  
!   /* -------------------------------------------------------------------- */
!   /*      Assign all the record fields.                                   */
!   /* -------------------------------------------------------------------- */
    if ((int) strlen ((char *) pValue) > psDBF->panFieldSize[iField])
      j = psDBF->panFieldSize[iField];
    else
***************
*** 1298,1315 ****
    int nRecordOffset, i;
    unsigned char *pabyRec;
  
! /* -------------------------------------------------------------------- */
! /*	Is this a valid record?						*/
! /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity > psDBF->nRecords)
      return (FALSE);
  
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
! /* -------------------------------------------------------------------- */
! /*      Is this a brand new record?                                     */
! /* -------------------------------------------------------------------- */
    if (hEntity == psDBF->nRecords)
      {
        DBFFlushRecord (psDBF);
--- 1379,1396 ----
    int nRecordOffset, i;
    unsigned char *pabyRec;
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this a valid record?                                         */
!   /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity > psDBF->nRecords)
      return (FALSE);
  
    if (psDBF->bNoHeader)
      DBFWriteHeader (psDBF);
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this a brand new record?                                     */
!   /* -------------------------------------------------------------------- */
    if (hEntity == psDBF->nRecords)
      {
        DBFFlushRecord (psDBF);
***************
*** 1321,1330 ****
        psDBF->nCurrentRecord = hEntity;
      }
  
! /* -------------------------------------------------------------------- */
! /*      Is this an existing record, but different than the last one     */
! /*      we accessed?                                                    */
! /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
--- 1402,1411 ----
        psDBF->nCurrentRecord = hEntity;
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Is this an existing record, but different than the last one     */
!   /*      we accessed?                                                    */
!   /* -------------------------------------------------------------------- */
    if (psDBF->nCurrentRecord != hEntity)
      {
        DBFFlushRecord (psDBF);
***************
*** 1363,1371 ****
  
    static int nTupleLen = 0;
  
! /* -------------------------------------------------------------------- */
! /*	Have we read the record?					*/
! /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity >= psDBF->nRecords)
      return (NULL);
  
--- 1444,1452 ----
  
    static int nTupleLen = 0;
  
!   /* -------------------------------------------------------------------- */
!   /*      Have we read the record?                                        */
!   /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity >= psDBF->nRecords)
      return (NULL);
  
***************
*** 1474,1480 ****
  
    while (++i < len)
      if (isalpha (string[i]) && islower (string[i]))
!       string[i] = toupper ((int) string[i]);
  }
  
  /************************************************************************/
--- 1555,1561 ----
  
    while (++i < len)
      if (isalpha (string[i]) && islower (string[i]))
!       string[i] = (char) toupper ((int) string[i]);
  }
  
  /************************************************************************/

["shapefil.h.diff" (text/x-patch)]

*** shapefil.h	2010-03-25 17:39:33.695830541 +0100
--- ../postgis-svn/loader/shapefil.h.orig	2010-03-25 17:39:43.545834457 +0100
***************
*** 2,8 ****
  #define _SHAPEFILE_H_INCLUDED
  
  /******************************************************************************
!  * $Id: shapefil.h,v 1.27 2003-04-21 18:30:37 warmerda Exp $
   *
   * Project:  Shapelib
   * Purpose:  Primary include file for Shapelib.
--- 2,8 ----
  #define _SHAPEFILE_H_INCLUDED
  
  /******************************************************************************
!  * $Id: shapefil.h 4168 2009-06-11 16:44:03Z pramsey $
   *
   * Project:  Shapelib
   * Purpose:  Primary include file for Shapelib.
***************
*** 16,22 ****
   * option is discussed in more detail in shapelib.html.
   *
   * --
!  * 
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
--- 16,22 ----
   * option is discussed in more detail in shapelib.html.
   *
   * --
!  *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
***************
*** 36,43 ****
   * DEALINGS IN THE SOFTWARE.
   ******************************************************************************
   *
!  * $Log: shapefil.h,v $
!  * Revision 1.27  2003-04-21 18:30:37  warmerda
   * added header write/update public methods
   *
   * Revision 1.26  2002/09/29 00:00:08  warmerda
--- 36,49 ----
   * DEALINGS IN THE SOFTWARE.
   ******************************************************************************
   *
!  * $Log$
!  * Revision 1.5  2006/01/16 10:42:58  strk
!  * Added support for Bool and Date DBF<=>PGIS mapping
!  *
!  * Revision 1.4  2003/12/01 20:52:00  strk
!  * shapelib put in sync with gdal cvs
!  *
!  * Revision 1.27  2003/04/21 18:30:37  warmerda
   * added header write/update public methods
   *
   * Revision 1.26  2002/09/29 00:00:08  warmerda
***************
*** 128,178 ****
  {
  #endif
  
! /************************************************************************/
! /*                        Configuration options.                        */
! /************************************************************************/
! 
! /* -------------------------------------------------------------------- */
! /*      Should the DBFReadStringAttribute() strip leading and           */
! /*      trailing white space?                                           */
! /* -------------------------------------------------------------------- */
  #define TRIM_DBF_WHITESPACE
  
! /* -------------------------------------------------------------------- */
! /*      Should we write measure values to the Multipatch object?        */
! /*      Reportedly ArcView crashes if we do write it, so for now it     */
! /*      is disabled.                                                    */
! /* -------------------------------------------------------------------- */
  #define DISABLE_MULTIPATCH_MEASURE
  
! /* -------------------------------------------------------------------- */
! /*      SHPAPI_CALL                                                     */
! /*                                                                      */
! /*      The following two macros are present to allow forcing           */
! /*      various calling conventions on the Shapelib API.                */
! /*                                                                      */
! /*      To force __stdcall conventions (needed to call Shapelib         */
! /*      from Visual Basic and/or Dephi I believe) the makefile could    */
! /*      be modified to define:                                          */
! /*                                                                      */
! /*        /DSHPAPI_CALL=__stdcall                                       */
! /*                                                                      */
! /*      If it is desired to force export of the Shapelib API without    */
! /*      using the shapelib.def file, use the following definition.      */
! /*                                                                      */
! /*        /DSHAPELIB_DLLEXPORT                                          */
! /*                                                                      */
! /*      To get both at once it will be necessary to hack this           */
! /*      include file to define:                                         */
! /*                                                                      */
! /*        #define SHPAPI_CALL __declspec(dllexport) __stdcall           */
! /*        #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall        */
! /*                                                                      */
! /*      The complexity of the situtation is partly caused by the        */
! /*      peculiar requirement of Visual C++ that __stdcall appear        */
! /*      after any "*"'s in the return value of a function while the     */
! /*      __declspec(dllexport) must appear before them.                  */
! /* -------------------------------------------------------------------- */
  
  #ifdef SHAPELIB_DLLEXPORT
  #  define SHPAPI_CALL __declspec(dllexport)
--- 134,184 ----
  {
  #endif
  
! 	/************************************************************************/
!   /*                        Configuration options.                        */
! 	/************************************************************************/
! 
!   /* -------------------------------------------------------------------- */
!   /*      Should the DBFReadStringAttribute() strip leading and           */
!   /*      trailing white space?                                           */
!   /* -------------------------------------------------------------------- */
  #define TRIM_DBF_WHITESPACE
  
!   /* -------------------------------------------------------------------- */
!   /*      Should we write measure values to the Multipatch object?        */
!   /*      Reportedly ArcView crashes if we do write it, so for now it     */
!   /*      is disabled.                                                    */
!   /* -------------------------------------------------------------------- */
  #define DISABLE_MULTIPATCH_MEASURE
  
!   /* -------------------------------------------------------------------- */
!   /*      SHPAPI_CALL                                                     */
!   /*                                                                      */
!   /*      The following two macros are present to allow forcing           */
!   /*      various calling conventions on the Shapelib API.                */
!   /*                                                                      */
!   /*      To force __stdcall conventions (needed to call Shapelib         */
!   /*      from Visual Basic and/or Dephi I believe) the makefile could    */
!   /*      be modified to define:                                          */
!   /*                                                                      */
!   /*        /DSHPAPI_CALL=__stdcall                                       */
!   /*                                                                      */
!   /*      If it is desired to force export of the Shapelib API without    */
!   /*      using the shapelib.def file, use the following definition.      */
!   /*                                                                      */
!   /*        /DSHAPELIB_DLLEXPORT                                          */
!   /*                                                                      */
!   /*      To get both at once it will be necessary to hack this           */
!   /*      include file to define:                                         */
!   /*                                                                      */
!   /*        #define SHPAPI_CALL __declspec(dllexport) __stdcall           */
!   /*        #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall        */
!   /*                                                                      */
!   /*      The complexity of the situtation is partly caused by the        */
!   /*      peculiar requirement of Visual C++ that __stdcall appear        */
!   /*      after any "*"'s in the return value of a function while the     */
!   /*      __declspec(dllexport) must appear before them.                  */
!   /* -------------------------------------------------------------------- */
  
  #ifdef SHAPELIB_DLLEXPORT
  #  define SHPAPI_CALL __declspec(dllexport)
***************
*** 187,195 ****
  #  define SHPAPI_CALL1(x)      x SHPAPI_CALL
  #endif
  
! /************************************************************************/
! /*                             SHP Support.                             */
! /************************************************************************/
    typedef struct
    {
      FILE *fpSHP;
--- 193,201 ----
  #  define SHPAPI_CALL1(x)      x SHPAPI_CALL
  #endif
  
! 	/************************************************************************/
!   /*                             SHP Support.                             */
! 	/************************************************************************/
    typedef struct
    {
      FILE *fpSHP;
***************
*** 211,223 ****
  
      unsigned char *pabyRec;
      int nBufSize;
!   } SHPInfo;
  
    typedef SHPInfo *SHPHandle;
  
! /* -------------------------------------------------------------------- */
! /*      Shape types (nSHPType)                                          */
! /* -------------------------------------------------------------------- */
  #define SHPT_NULL	0
  #define SHPT_POINT	1
  #define SHPT_ARC	3
--- 217,230 ----
  
      unsigned char *pabyRec;
      int nBufSize;
!   }
!   SHPInfo;
  
    typedef SHPInfo *SHPHandle;
  
!   /* -------------------------------------------------------------------- */
!   /*      Shape types (nSHPType)                                          */
!   /* -------------------------------------------------------------------- */
  #define SHPT_NULL	0
  #define SHPT_POINT	1
  #define SHPT_ARC	3
***************
*** 234,243 ****
  #define SHPT_MULTIPATCH 31
  
  
! /* -------------------------------------------------------------------- */
! /*      Part types - everything but SHPT_MULTIPATCH just uses           */
! /*      SHPP_RING.                                                      */
! /* -------------------------------------------------------------------- */
  
  #define SHPP_TRISTRIP	0
  #define SHPP_TRIFAN	1
--- 241,250 ----
  #define SHPT_MULTIPATCH 31
  
  
!   /* -------------------------------------------------------------------- */
!   /*      Part types - everything but SHPT_MULTIPATCH just uses           */
!   /*      SHPP_RING.                                                      */
!   /* -------------------------------------------------------------------- */
  
  #define SHPP_TRISTRIP	0
  #define SHPP_TRIFAN	1
***************
*** 246,255 ****
  #define SHPP_FIRSTRING	4
  #define SHPP_RING	5
  
! /* -------------------------------------------------------------------- */
! /*      SHPObject - represents on shape (without attributes) read       */
! /*      from the .shp file.                                             */
! /* -------------------------------------------------------------------- */
    typedef struct
    {
      int nSHPType;
--- 253,262 ----
  #define SHPP_FIRSTRING	4
  #define SHPP_RING	5
  
!   /* -------------------------------------------------------------------- */
!   /*      SHPObject - represents on shape (without attributes) read       */
!   /*      from the .shp file.                                             */
!   /* -------------------------------------------------------------------- */
    typedef struct
    {
      int nSHPType;
***************
*** 275,285 ****
      double dfYMax;
      double dfZMax;
      double dfMMax;
!   } SHPObject;
  
! /* -------------------------------------------------------------------- */
! /*      SHP API Prototypes                                              */
! /* -------------------------------------------------------------------- */
    SHPHandle SHPAPI_CALL
      SHPOpen (const char *pszShapeFile, const char *pszAccess);
    SHPHandle SHPAPI_CALL SHPCreate (const char *pszShapeFile, int nShapeType);
--- 282,293 ----
      double dfYMax;
      double dfZMax;
      double dfMMax;
!   }
!   SHPObject;
  
!   /* -------------------------------------------------------------------- */
!   /*      SHP API Prototypes                                              */
!   /* -------------------------------------------------------------------- */
    SHPHandle SHPAPI_CALL
      SHPOpen (const char *pszShapeFile, const char *pszAccess);
    SHPHandle SHPAPI_CALL SHPCreate (const char *pszShapeFile, int nShapeType);
***************
*** 310,320 ****
    const char SHPAPI_CALL1 (*) SHPTypeName (int nSHPType);
    const char SHPAPI_CALL1 (*) SHPPartTypeName (int nPartType);
  
! /* -------------------------------------------------------------------- */
! /*      Shape quadtree indexing API.                                    */
! /* -------------------------------------------------------------------- */
  
! /* this can be two or four for binary or quad tree */
  #define MAX_SUBNODE	4
  
    typedef struct shape_tree_node
--- 318,328 ----
    const char SHPAPI_CALL1 (*) SHPTypeName (int nSHPType);
    const char SHPAPI_CALL1 (*) SHPPartTypeName (int nPartType);
  
!   /* -------------------------------------------------------------------- */
!   /*      Shape quadtree indexing API.                                    */
!   /* -------------------------------------------------------------------- */
  
!   /* this can be two or four for binary or quad tree */
  #define MAX_SUBNODE	4
  
    typedef struct shape_tree_node
***************
*** 332,338 ****
      int nSubNodes;
      struct shape_tree_node *apsSubNode[MAX_SUBNODE];
  
!   } SHPTreeNode;
  
    typedef struct
    {
--- 340,347 ----
      int nSubNodes;
      struct shape_tree_node *apsSubNode[MAX_SUBNODE];
  
!   }
!   SHPTreeNode;
  
    typedef struct
    {
***************
*** 342,348 ****
      int nDimension;
  
      SHPTreeNode *psRoot;
!   } SHPTree;
  
    SHPTree SHPAPI_CALL1 (*)
      SHPCreateTree (SHPHandle hSHP, int nDimension, int nMaxDepth,
--- 351,358 ----
      int nDimension;
  
      SHPTreeNode *psRoot;
!   }
!   SHPTree;
  
    SHPTree SHPAPI_CALL1 (*)
      SHPCreateTree (SHPHandle hSHP, int nDimension, int nMaxDepth,
***************
*** 365,373 ****
    int SHPAPI_CALL
      SHPCheckBoundsOverlap (double *, double *, double *, double *, int);
  
! /************************************************************************/
! /*                             DBF Support.                             */
! /************************************************************************/
    typedef struct
    {
      FILE *fp;
--- 375,383 ----
    int SHPAPI_CALL
      SHPCheckBoundsOverlap (double *, double *, double *, double *, int);
  
! 	/************************************************************************/
!   /*                             DBF Support.                             */
! 	/************************************************************************/
    typedef struct
    {
      FILE *fp;
***************
*** 390,396 ****
  
      int bNoHeader;
      int bUpdated;
!   } DBFInfo;
  
    typedef DBFInfo *DBFHandle;
  
--- 400,407 ----
  
      int bNoHeader;
      int bUpdated;
!   }
!   DBFInfo;
  
    typedef DBFInfo *DBFHandle;
  
***************
*** 400,406 ****
      FTInteger,
      FTDouble,
      FTLogical,
!     FTInvalid
    } DBFFieldType;
  
  #define XBASE_FLDHDR_SZ       32
--- 411,418 ----
      FTInteger,
      FTDouble,
      FTLogical,
!     FTInvalid,
!     FTDate
    } DBFFieldType;
  
  #define XBASE_FLDHDR_SZ       32
***************
*** 432,437 ****
--- 444,453 ----
      DBFReadLogicalAttribute (DBFHandle hDBF, int iShape, int iField);
    int SHPAPI_CALL DBFIsAttributeNULL (DBFHandle hDBF, int iShape, int iField);
  
+   int SHPAPI_CALL DBFReadSetup (DBFHandle psDBF, int hEntity);
+ 
+   int SHPAPI_CALL DBFReadDeleted (DBFHandle psDBF, int hEntity);
+ 
    int SHPAPI_CALL
      DBFWriteIntegerAttribute (DBFHandle hDBF, int iShape, int iField,
  			      int nFieldValue);
***************
*** 449,455 ****
  			      const char lFieldValue);
    int SHPAPI_CALL
      DBFWriteAttributeDirectly (DBFHandle psDBF, int hEntity, int iField,
! 			       void *pValue);
    const char SHPAPI_CALL1 (*) DBFReadTuple (DBFHandle psDBF, int hEntity);
    int SHPAPI_CALL
      DBFWriteTuple (DBFHandle psDBF, int hEntity, void *pRawTuple);
--- 465,471 ----
  			      const char lFieldValue);
    int SHPAPI_CALL
      DBFWriteAttributeDirectly (DBFHandle psDBF, int hEntity, int iField,
! 			       const void *pValue);
    const char SHPAPI_CALL1 (*) DBFReadTuple (DBFHandle psDBF, int hEntity);
    int SHPAPI_CALL
      DBFWriteTuple (DBFHandle psDBF, int hEntity, void *pRawTuple);

["shpopen.c.diff" (text/x-patch)]

*** shpopen.c	2010-03-25 18:15:08.925816613 +0100
--- ../postgis-svn/loader/shpopen.c.orig	2010-03-25 17:41:05.368315597 +0100
***************
*** 1,5 ****
  /******************************************************************************
!  * $Id: shpopen.c,v 1.40 2003-04-21 18:30:37 warmerda Exp $
   *
   * Project:  Shapelib
   * Purpose:  Implementation of core Shapefile read/write functions.
--- 1,5 ----
  /******************************************************************************
!  * $Id: shpopen.c 5181 2010-02-01 17:35:55Z pramsey $
   *
   * Project:  Shapelib
   * Purpose:  Implementation of core Shapefile read/write functions.
***************
*** 13,19 ****
   * option is discussed in more detail in shapelib.html.
   *
   * --
!  * 
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
--- 13,19 ----
   * option is discussed in more detail in shapelib.html.
   *
   * --
!  *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
***************
*** 33,40 ****
   * DEALINGS IN THE SOFTWARE.
   ******************************************************************************
   *
!  * $Log: shpopen.c,v $
!  * Revision 1.40  2003-04-21 18:30:37  warmerda
   * added header write/update public methods
   *
   * Revision 1.39  2002/08/26 06:46:56  warmerda
--- 33,52 ----
   * DEALINGS IN THE SOFTWARE.
   ******************************************************************************
   *
!  * $Log$
!  * Revision 1.5  2003/12/01 20:52:00  strk
!  * shapelib put in sync with gdal cvs
!  *
!  * Revision 1.43  2003/12/01 16:20:08  warmerda
!  * be careful of zero vertex shapes
!  *
!  * Revision 1.42  2003/12/01 14:58:27  warmerda
!  * added degenerate object check in SHPRewindObject()
!  *
!  * Revision 1.41  2003/07/08 15:22:43  warmerda
!  * avoid warning
!  *
!  * Revision 1.40  2003/04/21 18:30:37  warmerda
   * added header write/update public methods
   *
   * Revision 1.39  2002/08/26 06:46:56  warmerda
***************
*** 161,169 ****
   *
   */
  
- static char rcsid[] =
-   "$Id: shpopen.c,v 1.40 2003-04-21 18:30:37 warmerda Exp $";
- 
  #include "shapefil.h"
  
  #include <math.h>
--- 173,178 ----
***************
*** 246,254 ****
    double dValue;
    int32 *panSHX;
  
! /* -------------------------------------------------------------------- */
! /*      Prepare header block for .shp file.                             */
! /* -------------------------------------------------------------------- */
    for (i = 0; i < 100; i++)
      abyHeader[i] = 0;
  
--- 255,263 ----
    double dValue;
    int32 *panSHX;
  
!   /* -------------------------------------------------------------------- */
!   /*      Prepare header block for .shp file.                             */
!   /* -------------------------------------------------------------------- */
    for (i = 0; i < 100; i++)
      abyHeader[i] = 0;
  
***************
*** 310,324 ****
    if (bBigEndian)
      SwapWord (8, abyHeader + 92);
  
! /* -------------------------------------------------------------------- */
! /*      Write .shp file header.                                         */
! /* -------------------------------------------------------------------- */
    fseek (psSHP->fpSHP, 0, 0);
    fwrite (abyHeader, 100, 1, psSHP->fpSHP);
  
! /* -------------------------------------------------------------------- */
! /*      Prepare, and write .shx file header.                            */
! /* -------------------------------------------------------------------- */
    i32 = (psSHP->nRecords * 2 * sizeof (int32) + 100) / 2;	/* file size */
    ByteCopy (&i32, abyHeader + 24, 4);
    if (!bBigEndian)
--- 319,333 ----
    if (bBigEndian)
      SwapWord (8, abyHeader + 92);
  
!   /* -------------------------------------------------------------------- */
!   /*      Write .shp file header.                                         */
!   /* -------------------------------------------------------------------- */
    fseek (psSHP->fpSHP, 0, 0);
    fwrite (abyHeader, 100, 1, psSHP->fpSHP);
  
!   /* -------------------------------------------------------------------- */
!   /*      Prepare, and write .shx file header.                            */
!   /* -------------------------------------------------------------------- */
    i32 = (psSHP->nRecords * 2 * sizeof (int32) + 100) / 2;	/* file size */
    ByteCopy (&i32, abyHeader + 24, 4);
    if (!bBigEndian)
***************
*** 327,335 ****
    fseek (psSHP->fpSHX, 0, 0);
    fwrite (abyHeader, 100, 1, psSHP->fpSHX);
  
! /* -------------------------------------------------------------------- */
! /*      Write out the .shx contents.                                    */
! /* -------------------------------------------------------------------- */
    panSHX = (int32 *) malloc (sizeof (int32) * 2 * psSHP->nRecords);
  
    for (i = 0; i < psSHP->nRecords; i++)
--- 336,344 ----
    fseek (psSHP->fpSHX, 0, 0);
    fwrite (abyHeader, 100, 1, psSHP->fpSHX);
  
!   /* -------------------------------------------------------------------- */
!   /*      Write out the .shx contents.                                    */
!   /* -------------------------------------------------------------------- */
    panSHX = (int32 *) malloc (sizeof (int32) * 2 * psSHP->nRecords);
  
    for (i = 0; i < psSHP->nRecords; i++)
***************
*** 346,354 ****
  
    free (panSHX);
  
! /* -------------------------------------------------------------------- */
! /*      Flush to disk.                                                  */
! /* -------------------------------------------------------------------- */
    fflush (psSHP->fpSHP);
    fflush (psSHP->fpSHX);
  }
--- 355,363 ----
  
    free (panSHX);
  
!   /* -------------------------------------------------------------------- */
!   /*      Flush to disk.                                                  */
!   /* -------------------------------------------------------------------- */
    fflush (psSHP->fpSHP);
    fflush (psSHP->fpSHX);
  }
***************
*** 370,406 ****
    int i;
    double dValue;
  
! /* -------------------------------------------------------------------- */
! /*      Ensure the access string is one of the legal ones.  We          */
! /*      ensure the result string indicates binary to avoid common       */
! /*      problems on Windows.                                            */
! /* -------------------------------------------------------------------- */
    if (strcmp (pszAccess, "rb+") == 0 || strcmp (pszAccess, "r+b") == 0
        || strcmp (pszAccess, "r+") == 0)
      pszAccess = "r+b";
    else
      pszAccess = "rb";
  
! /* -------------------------------------------------------------------- */
! /*	Establish the byte order on this machine.			*/
! /* -------------------------------------------------------------------- */
    i = 1;
    if (*((uchar *) & i) == 1)
      bBigEndian = FALSE;
    else
      bBigEndian = TRUE;
  
! /* -------------------------------------------------------------------- */
! /*	Initialize the info structure.					*/
! /* -------------------------------------------------------------------- */
    psSHP = (SHPHandle) calloc (sizeof (SHPInfo), 1);
  
    psSHP->bUpdated = FALSE;
  
! /* -------------------------------------------------------------------- */
! /*	Compute the base (layer) name.  If there is any extension	*/
! /*	on the passed in filename we will strip it off.			*/
! /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszLayer) + 5);
    strcpy (pszBasename, pszLayer);
    for (i = strlen (pszBasename) - 1;
--- 379,415 ----
    int i;
    double dValue;
  
!   /* -------------------------------------------------------------------- */
!   /*      Ensure the access string is one of the legal ones.  We          */
!   /*      ensure the result string indicates binary to avoid common       */
!   /*      problems on Windows.                                            */
!   /* -------------------------------------------------------------------- */
    if (strcmp (pszAccess, "rb+") == 0 || strcmp (pszAccess, "r+b") == 0
        || strcmp (pszAccess, "r+") == 0)
      pszAccess = "r+b";
    else
      pszAccess = "rb";
  
!   /* -------------------------------------------------------------------- */
!   /*      Establish the byte order on this machine.                       */
!   /* -------------------------------------------------------------------- */
    i = 1;
    if (*((uchar *) & i) == 1)
      bBigEndian = FALSE;
    else
      bBigEndian = TRUE;
  
!   /* -------------------------------------------------------------------- */
!   /*      Initialize the info structure.                                  */
!   /* -------------------------------------------------------------------- */
    psSHP = (SHPHandle) calloc (sizeof (SHPInfo), 1);
  
    psSHP->bUpdated = FALSE;
  
!   /* -------------------------------------------------------------------- */
!   /*      Compute the base (layer) name.  If there is any extension       */
!   /*      on the passed in filename we will strip it off.                 */
!   /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszLayer) + 5);
    strcpy (pszBasename, pszLayer);
    for (i = strlen (pszBasename) - 1;
***************
*** 412,421 ****
    if (pszBasename[i] == '.')
      pszBasename[i] = '\0';
  
! /* -------------------------------------------------------------------- */
! /*	Open the .shp and .shx files.  Note that files pulled from	*/
! /*	a PC to Unix with upper case filenames won't work!		*/
! /* -------------------------------------------------------------------- */
    pszFullname = (char *) malloc (strlen (pszBasename) + 5);
    sprintf (pszFullname, "%s.shp", pszBasename);
    psSHP->fpSHP = fopen (pszFullname, pszAccess);
--- 421,430 ----
    if (pszBasename[i] == '.')
      pszBasename[i] = '\0';
  
!   /* -------------------------------------------------------------------- */
!   /*      Open the .shp and .shx files.  Note that files pulled from      */
!   /*      a PC to Unix with upper case filenames won't work!              */
!   /* -------------------------------------------------------------------- */
    pszFullname = (char *) malloc (strlen (pszBasename) + 5);
    sprintf (pszFullname, "%s.shp", pszBasename);
    psSHP->fpSHP = fopen (pszFullname, pszAccess);
***************
*** 453,461 ****
    free (pszFullname);
    free (pszBasename);
  
! /* -------------------------------------------------------------------- */
! /*  Read the file size from the SHP file.				*/
! /* -------------------------------------------------------------------- */
    pabyBuf = (uchar *) malloc (100);
    fread (pabyBuf, 100, 1, psSHP->fpSHP);
  
--- 462,470 ----
    free (pszFullname);
    free (pszBasename);
  
!   /* -------------------------------------------------------------------- */
!   /*  Read the file size from the SHP file.                               */
!   /* -------------------------------------------------------------------- */
    pabyBuf = (uchar *) malloc (100);
    fread (pabyBuf, 100, 1, psSHP->fpSHP);
  
***************
*** 463,471 ****
  		      + pabyBuf[25] * 256 * 256
  		      + pabyBuf[26] * 256 + pabyBuf[27]) * 2;
  
! /* -------------------------------------------------------------------- */
! /*  Read SHX file Header info                                           */
! /* -------------------------------------------------------------------- */
    fread (pabyBuf, 100, 1, psSHP->fpSHX);
  
    if (pabyBuf[0] != 0
--- 472,480 ----
  		      + pabyBuf[25] * 256 * 256
  		      + pabyBuf[26] * 256 + pabyBuf[27]) * 2;
  
!   /* -------------------------------------------------------------------- */
!   /*  Read SHX file Header info                                           */
!   /* -------------------------------------------------------------------- */
    fread (pabyBuf, 100, 1, psSHP->fpSHX);
  
    if (pabyBuf[0] != 0
***************
*** 495,503 ****
        return (NULL);
      }
  
! /* -------------------------------------------------------------------- */
! /*      Read the bounds.                                                */
! /* -------------------------------------------------------------------- */
    if (bBigEndian)
      SwapWord (8, pabyBuf + 36);
    memcpy (&dValue, pabyBuf + 36, 8);
--- 504,512 ----
        return (NULL);
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Read the bounds.                                                */
!   /* -------------------------------------------------------------------- */
    if (bBigEndian)
      SwapWord (8, pabyBuf + 36);
    memcpy (&dValue, pabyBuf + 36, 8);
***************
*** 540,549 ****
  
    free (pabyBuf);
  
! /* -------------------------------------------------------------------- */
! /*	Read the .shx file to get the offsets to each record in 	*/
! /*	the .shp file.							*/
! /* -------------------------------------------------------------------- */
    psSHP->nMaxRecords = psSHP->nRecords;
  
    psSHP->panRecOffset =
--- 549,558 ----
  
    free (pabyBuf);
  
!   /* -------------------------------------------------------------------- */
!   /*      Read the .shx file to get the offsets to each record in         */
!   /*      the .shp file.                                                  */
!   /* -------------------------------------------------------------------- */
    psSHP->nMaxRecords = psSHP->nRecords;
  
    psSHP->panRecOffset =
***************
*** 583,597 ****
  void SHPAPI_CALL
  SHPClose (SHPHandle psSHP)
  {
! /* -------------------------------------------------------------------- */
! /*	Update the header if we have modified anything.			*/
! /* -------------------------------------------------------------------- */
    if (psSHP->bUpdated)
      SHPWriteHeader (psSHP);
  
! /* -------------------------------------------------------------------- */
! /*      Free all resources, and close files.                            */
! /* -------------------------------------------------------------------- */
    free (psSHP->panRecOffset);
    free (psSHP->panRecSize);
  
--- 592,606 ----
  void SHPAPI_CALL
  SHPClose (SHPHandle psSHP)
  {
!   /* -------------------------------------------------------------------- */
!   /*      Update the header if we have modified anything.                 */
!   /* -------------------------------------------------------------------- */
    if (psSHP->bUpdated)
      SHPWriteHeader (psSHP);
  
!   /* -------------------------------------------------------------------- */
!   /*      Free all resources, and close files.                            */
!   /* -------------------------------------------------------------------- */
    free (psSHP->panRecOffset);
    free (psSHP->panRecSize);
  
***************
*** 650,668 ****
    int32 i32;
    double dValue;
  
! /* -------------------------------------------------------------------- */
! /*      Establish the byte order on this system.                        */
! /* -------------------------------------------------------------------- */
    i = 1;
    if (*((uchar *) & i) == 1)
      bBigEndian = FALSE;
    else
      bBigEndian = TRUE;
  
! /* -------------------------------------------------------------------- */
! /*	Compute the base (layer) name.  If there is any extension	*/
! /*	on the passed in filename we will strip it off.			*/
! /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszLayer) + 5);
    strcpy (pszBasename, pszLayer);
    for (i = strlen (pszBasename) - 1;
--- 659,677 ----
    int32 i32;
    double dValue;
  
!   /* -------------------------------------------------------------------- */
!   /*      Establish the byte order on this system.                        */
!   /* -------------------------------------------------------------------- */
    i = 1;
    if (*((uchar *) & i) == 1)
      bBigEndian = FALSE;
    else
      bBigEndian = TRUE;
  
!   /* -------------------------------------------------------------------- */
!   /*      Compute the base (layer) name.  If there is any extension       */
!   /*      on the passed in filename we will strip it off.                 */
!   /* -------------------------------------------------------------------- */
    pszBasename = (char *) malloc (strlen (pszLayer) + 5);
    strcpy (pszBasename, pszLayer);
    for (i = strlen (pszBasename) - 1;
***************
*** 674,682 ****
    if (pszBasename[i] == '.')
      pszBasename[i] = '\0';
  
! /* -------------------------------------------------------------------- */
! /*      Open the two files so we can write their headers.               */
! /* -------------------------------------------------------------------- */
    pszFullname = (char *) malloc (strlen (pszBasename) + 5);
    sprintf (pszFullname, "%s.shp", pszBasename);
    fpSHP = fopen (pszFullname, "wb");
--- 683,691 ----
    if (pszBasename[i] == '.')
      pszBasename[i] = '\0';
  
!   /* -------------------------------------------------------------------- */
!   /*      Open the two files so we can write their headers.               */
!   /* -------------------------------------------------------------------- */
    pszFullname = (char *) malloc (strlen (pszBasename) + 5);
    sprintf (pszFullname, "%s.shp", pszBasename);
    fpSHP = fopen (pszFullname, "wb");
***************
*** 691,699 ****
    free (pszFullname);
    free (pszBasename);
  
! /* -------------------------------------------------------------------- */
! /*      Prepare header block for .shp file.                             */
! /* -------------------------------------------------------------------- */
    for (i = 0; i < 100; i++)
      abyHeader[i] = 0;
  
--- 700,708 ----
    free (pszFullname);
    free (pszBasename);
  
!   /* -------------------------------------------------------------------- */
!   /*      Prepare header block for .shp file.                             */
!   /* -------------------------------------------------------------------- */
    for (i = 0; i < 100; i++)
      abyHeader[i] = 0;
  
***************
*** 721,734 ****
    ByteCopy (&dValue, abyHeader + 52, 8);
    ByteCopy (&dValue, abyHeader + 60, 8);
  
! /* -------------------------------------------------------------------- */
! /*      Write .shp file header.                                         */
! /* -------------------------------------------------------------------- */
    fwrite (abyHeader, 100, 1, fpSHP);
  
! /* -------------------------------------------------------------------- */
! /*      Prepare, and write .shx file header.                            */
! /* -------------------------------------------------------------------- */
    i32 = 50;			/* file size */
    ByteCopy (&i32, abyHeader + 24, 4);
    if (!bBigEndian)
--- 730,743 ----
    ByteCopy (&dValue, abyHeader + 52, 8);
    ByteCopy (&dValue, abyHeader + 60, 8);
  
!   /* -------------------------------------------------------------------- */
!   /*      Write .shp file header.                                         */
!   /* -------------------------------------------------------------------- */
    fwrite (abyHeader, 100, 1, fpSHP);
  
!   /* -------------------------------------------------------------------- */
!   /*      Prepare, and write .shx file header.                            */
!   /* -------------------------------------------------------------------- */
    i32 = 50;			/* file size */
    ByteCopy (&i32, abyHeader + 24, 4);
    if (!bBigEndian)
***************
*** 736,744 ****
  
    fwrite (abyHeader, 100, 1, fpSHX);
  
! /* -------------------------------------------------------------------- */
! /*      Close the files, and then open them as regular existing files.  */
! /* -------------------------------------------------------------------- */
    fclose (fpSHP);
    fclose (fpSHX);
  
--- 745,753 ----
  
    fwrite (abyHeader, 100, 1, fpSHX);
  
!   /* -------------------------------------------------------------------- */
!   /*      Close the files, and then open them as regular existing files.  */
!   /* -------------------------------------------------------------------- */
    fclose (fpSHP);
    fclose (fpSHX);
  
***************
*** 781,789 ****
  {
    int i;
  
! /* -------------------------------------------------------------------- */
! /*      Build extents for this object.                                  */
! /* -------------------------------------------------------------------- */
    if (psObject->nVertices > 0)
      {
        psObject->dfXMin = psObject->dfXMax = psObject->padfX[0];
--- 790,798 ----
  {
    int i;
  
!   /* -------------------------------------------------------------------- */
!   /*      Build extents for this object.                                  */
!   /* -------------------------------------------------------------------- */
    if (psObject->nVertices > 0)
      {
        psObject->dfXMin = psObject->dfXMax = psObject->padfX[0];
***************
*** 827,835 ****
    psObject->nSHPType = nSHPType;
    psObject->nShapeId = nShapeId;
  
! /* -------------------------------------------------------------------- */
! /*	Establish whether this shape type has M, and Z values.		*/
! /* -------------------------------------------------------------------- */
    if (nSHPType == SHPT_ARCM
        || nSHPType == SHPT_POINTM
        || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_MULTIPOINTM)
--- 836,844 ----
    psObject->nSHPType = nSHPType;
    psObject->nShapeId = nShapeId;
  
!   /* -------------------------------------------------------------------- */
!   /*      Establish whether this shape type has M, and Z values.          */
!   /* -------------------------------------------------------------------- */
    if (nSHPType == SHPT_ARCM
        || nSHPType == SHPT_POINTM
        || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_MULTIPOINTM)
***************
*** 851,860 ****
        bHasZ = FALSE;
      }
  
! /* -------------------------------------------------------------------- */
! /*      Capture parts.  Note that part type is optional, and            */
! /*      defaults to ring.                                               */
! /* -------------------------------------------------------------------- */
    if (nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON
        || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM
        || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ
--- 860,869 ----
        bHasZ = FALSE;
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Capture parts.  Note that part type is optional, and            */
!   /*      defaults to ring.                                               */
!   /* -------------------------------------------------------------------- */
    if (nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON
        || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM
        || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ
***************
*** 880,889 ****
  	}
      }
  
! /* -------------------------------------------------------------------- */
! /*      Capture vertices.  Note that Z and M are optional, but X and    */
! /*      Y are not.                                                      */
! /* -------------------------------------------------------------------- */
    if (nVertices > 0)
      {
        psObject->padfX = (double *) calloc (sizeof (double), nVertices);
--- 889,898 ----
  	}
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Capture vertices.  Note that Z and M are optional, but X and    */
!   /*      Y are not.                                                      */
!   /* -------------------------------------------------------------------- */
    if (nVertices > 0)
      {
        psObject->padfX = (double *) calloc (sizeof (double), nVertices);
***************
*** 905,913 ****
  	}
      }
  
! /* -------------------------------------------------------------------- */
! /*      Compute the extents.                                            */
! /* -------------------------------------------------------------------- */
    psObject->nVertices = nVertices;
    SHPComputeExtents (psObject);
  
--- 914,922 ----
  	}
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Compute the extents.                                            */
!   /* -------------------------------------------------------------------- */
    psObject->nVertices = nVertices;
    SHPComputeExtents (psObject);
  
***************
*** 940,971 ****
  int SHPAPI_CALL
  SHPWriteObject (SHPHandle psSHP, int nShapeId, SHPObject * psObject)
  {
!   int nRecordOffset, i, nRecordSize;
    uchar *pabyRec;
    int32 i32;
  
    psSHP->bUpdated = TRUE;
  
! /* -------------------------------------------------------------------- */
! /*      Ensure that shape object matches the type of the file it is     */
! /*      being written to.                                               */
! /* -------------------------------------------------------------------- */
    assert (psObject->nSHPType == psSHP->nShapeType
  	  || psObject->nSHPType == SHPT_NULL);
  
! /* -------------------------------------------------------------------- */
! /*      Ensure that -1 is used for appends.  Either blow an             */
! /*      assertion, or if they are disabled, set the shapeid to -1       */
! /*      for appends.                                                    */
! /* -------------------------------------------------------------------- */
    assert (nShapeId == -1 || (nShapeId >= 0 && nShapeId < psSHP->nRecords));
  
    if (nShapeId != -1 && nShapeId >= psSHP->nRecords)
      nShapeId = -1;
  
! /* -------------------------------------------------------------------- */
! /*      Add the new entity to the in memory index.                      */
! /* -------------------------------------------------------------------- */
    if (nShapeId == -1 && psSHP->nRecords + 1 > psSHP->nMaxRecords)
      {
        psSHP->nMaxRecords = (int) (psSHP->nMaxRecords * 1.3 + 100);
--- 949,980 ----
  int SHPAPI_CALL
  SHPWriteObject (SHPHandle psSHP, int nShapeId, SHPObject * psObject)
  {
!   int nRecordOffset, i, nRecordSize = 0;
    uchar *pabyRec;
    int32 i32;
  
    psSHP->bUpdated = TRUE;
  
!   /* -------------------------------------------------------------------- */
!   /*      Ensure that shape object matches the type of the file it is     */
!   /*      being written to.                                               */
!   /* -------------------------------------------------------------------- */
    assert (psObject->nSHPType == psSHP->nShapeType
  	  || psObject->nSHPType == SHPT_NULL);
  
!   /* -------------------------------------------------------------------- */
!   /*      Ensure that -1 is used for appends.  Either blow an             */
!   /*      assertion, or if they are disabled, set the shapeid to -1       */
!   /*      for appends.                                                    */
!   /* -------------------------------------------------------------------- */
    assert (nShapeId == -1 || (nShapeId >= 0 && nShapeId < psSHP->nRecords));
  
    if (nShapeId != -1 && nShapeId >= psSHP->nRecords)
      nShapeId = -1;
  
!   /* -------------------------------------------------------------------- */
!   /*      Add the new entity to the in memory index.                      */
!   /* -------------------------------------------------------------------- */
    if (nShapeId == -1 && psSHP->nRecords + 1 > psSHP->nMaxRecords)
      {
        psSHP->nMaxRecords = (int) (psSHP->nMaxRecords * 1.3 + 100);
***************
*** 976,990 ****
  	SfRealloc (psSHP->panRecSize, sizeof (int) * psSHP->nMaxRecords);
      }
  
! /* -------------------------------------------------------------------- */
! /*      Initialize record.                                              */
! /* -------------------------------------------------------------------- */
    pabyRec = (uchar *) malloc (psObject->nVertices * 4 * sizeof (double)
  			      + psObject->nParts * 8 + 128);
  
! /* -------------------------------------------------------------------- */
! /*  Extract vertices for a Polygon or Arc.				*/
! /* -------------------------------------------------------------------- */
    if (psObject->nSHPType == SHPT_POLYGON
        || psObject->nSHPType == SHPT_POLYGONZ
        || psObject->nSHPType == SHPT_POLYGONM
--- 985,999 ----
  	SfRealloc (psSHP->panRecSize, sizeof (int) * psSHP->nMaxRecords);
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Initialize record.                                              */
!   /* -------------------------------------------------------------------- */
    pabyRec = (uchar *) malloc (psObject->nVertices * 4 * sizeof (double)
  			      + psObject->nParts * 8 + 128);
  
!   /* -------------------------------------------------------------------- */
!   /*  Extract vertices for a Polygon or Arc.                              */
!   /* -------------------------------------------------------------------- */
    if (psObject->nSHPType == SHPT_POLYGON
        || psObject->nSHPType == SHPT_POLYGONZ
        || psObject->nSHPType == SHPT_POLYGONM
***************
*** 1112,1120 ****
  	}
      }
  
! /* -------------------------------------------------------------------- */
! /*  Extract vertices for a MultiPoint.					*/
! /* -------------------------------------------------------------------- */
    else if (psObject->nSHPType == SHPT_MULTIPOINT
  	   || psObject->nSHPType == SHPT_MULTIPOINTZ
  	   || psObject->nSHPType == SHPT_MULTIPOINTM)
--- 1121,1129 ----
  	}
      }
  
!   /* -------------------------------------------------------------------- */
!   /*  Extract vertices for a MultiPoint.                                  */
!   /* -------------------------------------------------------------------- */
    else if (psObject->nSHPType == SHPT_MULTIPOINT
  	   || psObject->nSHPType == SHPT_MULTIPOINTZ
  	   || psObject->nSHPType == SHPT_MULTIPOINTM)
***************
*** 1187,1195 ****
  	}
      }
  
! /* -------------------------------------------------------------------- */
! /*      Write point.							*/
! /* -------------------------------------------------------------------- */
    else if (psObject->nSHPType == SHPT_POINT
  	   || psObject->nSHPType == SHPT_POINTZ
  	   || psObject->nSHPType == SHPT_POINTM)
--- 1196,1204 ----
  	}
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Write point.                                                    */
!   /* -------------------------------------------------------------------- */
    else if (psObject->nSHPType == SHPT_POINT
  	   || psObject->nSHPType == SHPT_POINTZ
  	   || psObject->nSHPType == SHPT_POINTM)
***************
*** 1222,1230 ****
  	}
      }
  
! /* -------------------------------------------------------------------- */
! /*      Not much to do for null geometries.                             */
! /* -------------------------------------------------------------------- */
    else if (psObject->nSHPType == SHPT_NULL)
      {
        nRecordSize = 12;
--- 1231,1239 ----
  	}
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Not much to do for null geometries.                             */
!   /* -------------------------------------------------------------------- */
    else if (psObject->nSHPType == SHPT_NULL)
      {
        nRecordSize = 12;
***************
*** 1236,1246 ****
        assert (FALSE);
      }
  
! /* -------------------------------------------------------------------- */
! /*      Establish where we are going to put this record. If we are      */
! /*      rewriting and existing record, and it will fit, then put it     */
! /*      back where the original came from.  Otherwise write at the end. */
! /* -------------------------------------------------------------------- */
    if (nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize - 8)
      {
        if (nShapeId == -1)
--- 1245,1255 ----
        assert (FALSE);
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Establish where we are going to put this record. If we are      */
!   /*      rewriting and existing record, and it will fit, then put it     */
!   /*      back where the original came from.  Otherwise write at the end. */
!   /* -------------------------------------------------------------------- */
    if (nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize - 8)
      {
        if (nShapeId == -1)
***************
*** 1255,1263 ****
        nRecordOffset = psSHP->panRecOffset[nShapeId];
      }
  
! /* -------------------------------------------------------------------- */
! /*      Set the shape type, record number, and record size.             */
! /* -------------------------------------------------------------------- */
    i32 = nShapeId + 1;		/* record # */
    if (!bBigEndian)
      SwapWord (4, &i32);
--- 1264,1272 ----
        nRecordOffset = psSHP->panRecOffset[nShapeId];
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Set the shape type, record number, and record size.             */
!   /* -------------------------------------------------------------------- */
    i32 = nShapeId + 1;		/* record # */
    if (!bBigEndian)
      SwapWord (4, &i32);
***************
*** 1273,1281 ****
      SwapWord (4, &i32);
    ByteCopy (&i32, pabyRec + 8, 4);
  
! /* -------------------------------------------------------------------- */
! /*      Write out record.                                               */
! /* -------------------------------------------------------------------- */
    if (fseek (psSHP->fpSHP, nRecordOffset, 0) != 0
        || fwrite (pabyRec, nRecordSize, 1, psSHP->fpSHP) < 1)
      {
--- 1282,1290 ----
      SwapWord (4, &i32);
    ByteCopy (&i32, pabyRec + 8, 4);
  
!   /* -------------------------------------------------------------------- */
!   /*      Write out record.                                               */
!   /* -------------------------------------------------------------------- */
    if (fseek (psSHP->fpSHP, nRecordOffset, 0) != 0
        || fwrite (pabyRec, nRecordSize, 1, psSHP->fpSHP) < 1)
      {
***************
*** 1286,1303 ****
  
    free (pabyRec);
  
! /* -------------------------------------------------------------------- */
! /*	Expand file wide bounds based on this shape.			*/
! /* -------------------------------------------------------------------- */
    if (psSHP->adBoundsMin[0] == 0.0
        && psSHP->adBoundsMax[0] == 0.0
!       && psSHP->adBoundsMin[1] == 0.0
!       && psSHP->adBoundsMax[1] == 0.0 && psObject->nSHPType != SHPT_NULL)
      {
!       psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
!       psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
!       psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
!       psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
      }
  
    for (i = 0; i < psObject->nVertices; i++)
--- 1295,1321 ----
  
    free (pabyRec);
  
!   /* -------------------------------------------------------------------- */
!   /*      Expand file wide bounds based on this shape.                    */
!   /* -------------------------------------------------------------------- */
    if (psSHP->adBoundsMin[0] == 0.0
        && psSHP->adBoundsMax[0] == 0.0
!       && psSHP->adBoundsMin[1] == 0.0 && psSHP->adBoundsMax[1] == 0.0)
      {
!       if (psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0)
! 	{
! 	  psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0;
! 	  psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0;
! 	  psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0;
! 	  psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0;
! 	}
!       else
! 	{
! 	  psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0];
! 	  psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0];
! 	  psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0];
! 	  psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0];
! 	}
      }
  
    for (i = 0; i < psObject->nVertices; i++)
***************
*** 1328,1357 ****
  {
    SHPObject *psShape;
  
! /* -------------------------------------------------------------------- */
! /*      Validate the record/entity number.                              */
! /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity >= psSHP->nRecords)
      return (NULL);
  
! /* -------------------------------------------------------------------- */
! /*      Ensure our record buffer is large enough.                       */
! /* -------------------------------------------------------------------- */
    if (psSHP->panRecSize[hEntity] + 8 > psSHP->nBufSize)
      {
        psSHP->nBufSize = psSHP->panRecSize[hEntity] + 8;
        psSHP->pabyRec = (uchar *) SfRealloc (psSHP->pabyRec, psSHP->nBufSize);
      }
  
! /* -------------------------------------------------------------------- */
! /*      Read the record.                                                */
! /* -------------------------------------------------------------------- */
    fseek (psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0);
    fread (psSHP->pabyRec, psSHP->panRecSize[hEntity] + 8, 1, psSHP->fpSHP);
  
! /* -------------------------------------------------------------------- */
! /*	Allocate and minimally initialize the object.			*/
! /* -------------------------------------------------------------------- */
    psShape = (SHPObject *) calloc (1, sizeof (SHPObject));
    psShape->nShapeId = hEntity;
  
--- 1346,1375 ----
  {
    SHPObject *psShape;
  
!   /* -------------------------------------------------------------------- */
!   /*      Validate the record/entity number.                              */
!   /* -------------------------------------------------------------------- */
    if (hEntity < 0 || hEntity >= psSHP->nRecords)
      return (NULL);
  
!   /* -------------------------------------------------------------------- */
!   /*      Ensure our record buffer is large enough.                       */
!   /* -------------------------------------------------------------------- */
    if (psSHP->panRecSize[hEntity] + 8 > psSHP->nBufSize)
      {
        psSHP->nBufSize = psSHP->panRecSize[hEntity] + 8;
        psSHP->pabyRec = (uchar *) SfRealloc (psSHP->pabyRec, psSHP->nBufSize);
      }
  
!   /* -------------------------------------------------------------------- */
!   /*      Read the record.                                                */
!   /* -------------------------------------------------------------------- */
    fseek (psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0);
    fread (psSHP->pabyRec, psSHP->panRecSize[hEntity] + 8, 1, psSHP->fpSHP);
  
!   /* -------------------------------------------------------------------- */
!   /*      Allocate and minimally initialize the object.                   */
!   /* -------------------------------------------------------------------- */
    psShape = (SHPObject *) calloc (1, sizeof (SHPObject));
    psShape->nShapeId = hEntity;
  
***************
*** 1359,1367 ****
    if (bBigEndian)
      SwapWord (4, &(psShape->nSHPType));
  
! /* ==================================================================== */
! /*  Extract vertices for a Polygon or Arc.				*/
! /* ==================================================================== */
    if (psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC
        || psShape->nSHPType == SHPT_POLYGONZ
        || psShape->nSHPType == SHPT_POLYGONM
--- 1377,1385 ----
    if (bBigEndian)
      SwapWord (4, &(psShape->nSHPType));
  
!   /* ==================================================================== */
!   /*  Extract vertices for a Polygon or Arc.                              */
!   /* ==================================================================== */
    if (psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC
        || psShape->nSHPType == SHPT_POLYGONZ
        || psShape->nSHPType == SHPT_POLYGONM
***************
*** 1372,1380 ****
        int32 nPoints, nParts;
        int i, nOffset;
  
! /* -------------------------------------------------------------------- */
! /*	Get the X/Y bounds.						*/
! /* -------------------------------------------------------------------- */
        memcpy (&(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8);
        memcpy (&(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8);
        memcpy (&(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8);
--- 1390,1398 ----
        int32 nPoints, nParts;
        int i, nOffset;
  
!       /* -------------------------------------------------------------------- */
!       /*      Get the X/Y bounds.                                             */
!       /* -------------------------------------------------------------------- */
        memcpy (&(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8);
        memcpy (&(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8);
        memcpy (&(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8);
***************
*** 1389,1398 ****
        if (bBigEndian)
  	SwapWord (8, &(psShape->dfYMax));
  
! /* -------------------------------------------------------------------- */
! /*      Extract part/point count, and build vertex and part arrays      */
! /*      to proper size.                                                 */
! /* -------------------------------------------------------------------- */
        memcpy (&nPoints, psSHP->pabyRec + 40 + 8, 4);
        memcpy (&nParts, psSHP->pabyRec + 36 + 8, 4);
  
--- 1407,1416 ----
        if (bBigEndian)
  	SwapWord (8, &(psShape->dfYMax));
  
!       /* -------------------------------------------------------------------- */
!       /*      Extract part/point count, and build vertex and part arrays      */
!       /*      to proper size.                                                 */
!       /* -------------------------------------------------------------------- */
        memcpy (&nPoints, psSHP->pabyRec + 40 + 8, 4);
        memcpy (&nParts, psSHP->pabyRec + 36 + 8, 4);
  
***************
*** 1414,1422 ****
        for (i = 0; i < nParts; i++)
  	psShape->panPartType[i] = SHPP_RING;
  
! /* -------------------------------------------------------------------- */
! /*      Copy out the part array from the record.                        */
! /* -------------------------------------------------------------------- */
        memcpy (psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts);
        for (i = 0; i < nParts; i++)
  	{
--- 1432,1440 ----
        for (i = 0; i < nParts; i++)
  	psShape->panPartType[i] = SHPP_RING;
  
!       /* -------------------------------------------------------------------- */
!       /*      Copy out the part array from the record.                        */
!       /* -------------------------------------------------------------------- */
        memcpy (psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts);
        for (i = 0; i < nParts; i++)
  	{
***************
*** 1426,1434 ****
  
        nOffset = 44 + 8 + 4 * nParts;
  
! /* -------------------------------------------------------------------- */
! /*      If this is a multipatch, we will also have parts types.         */
! /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_MULTIPATCH)
  	{
  	  memcpy (psShape->panPartType, psSHP->pabyRec + nOffset, 4 * nParts);
--- 1444,1452 ----
  
        nOffset = 44 + 8 + 4 * nParts;
  
!       /* -------------------------------------------------------------------- */
!       /*      If this is a multipatch, we will also have parts types.         */
!       /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_MULTIPATCH)
  	{
  	  memcpy (psShape->panPartType, psSHP->pabyRec + nOffset, 4 * nParts);
***************
*** 1441,1449 ****
  	  nOffset += 4 * nParts;
  	}
  
! /* -------------------------------------------------------------------- */
! /*      Copy out the vertices from the record.                          */
! /* -------------------------------------------------------------------- */
        for (i = 0; i < nPoints; i++)
  	{
  	  memcpy (psShape->padfX + i, psSHP->pabyRec + nOffset + i * 16, 8);
--- 1459,1467 ----
  	  nOffset += 4 * nParts;
  	}
  
!       /* -------------------------------------------------------------------- */
!       /*      Copy out the vertices from the record.                          */
!       /* -------------------------------------------------------------------- */
        for (i = 0; i < nPoints; i++)
  	{
  	  memcpy (psShape->padfX + i, psSHP->pabyRec + nOffset + i * 16, 8);
***************
*** 1459,1467 ****
  
        nOffset += 16 * nPoints;
  
! /* -------------------------------------------------------------------- */
! /*      If we have a Z coordinate, collect that now.                    */
! /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_POLYGONZ
  	  || psShape->nSHPType == SHPT_ARCZ
  	  || psShape->nSHPType == SHPT_MULTIPATCH)
--- 1477,1485 ----
  
        nOffset += 16 * nPoints;
  
!       /* -------------------------------------------------------------------- */
!       /*      If we have a Z coordinate, collect that now.                    */
!       /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_POLYGONZ
  	  || psShape->nSHPType == SHPT_ARCZ
  	  || psShape->nSHPType == SHPT_MULTIPATCH)
***************
*** 1485,1496 ****
  	  nOffset += 16 + 8 * nPoints;
  	}
  
! /* -------------------------------------------------------------------- */
! /*      If we have a M measure value, then read it now.  We assume      */
! /*      that the measure can be present for any shape if the size is    */
! /*      big enough, but really it will only occur for the Z shapes      */
! /*      (options), and the M shapes.                                    */
! /* -------------------------------------------------------------------- */
        if (psSHP->panRecSize[hEntity] + 8 >= nOffset + 16 + 8 * nPoints)
  	{
  	  memcpy (&(psShape->dfMMin), psSHP->pabyRec + nOffset, 8);
--- 1503,1514 ----
  	  nOffset += 16 + 8 * nPoints;
  	}
  
!       /* -------------------------------------------------------------------- */
!       /*      If we have a M measure value, then read it now.  We assume      */
!       /*      that the measure can be present for any shape if the size is    */
!       /*      big enough, but really it will only occur for the Z shapes      */
!       /*      (options), and the M shapes.                                    */
!       /* -------------------------------------------------------------------- */
        if (psSHP->panRecSize[hEntity] + 8 >= nOffset + 16 + 8 * nPoints)
  	{
  	  memcpy (&(psShape->dfMMin), psSHP->pabyRec + nOffset, 8);
***************
*** 1512,1520 ****
  
      }
  
! /* ==================================================================== */
! /*  Extract vertices for a MultiPoint.					*/
! /* ==================================================================== */
    else if (psShape->nSHPType == SHPT_MULTIPOINT
  	   || psShape->nSHPType == SHPT_MULTIPOINTM
  	   || psShape->nSHPType == SHPT_MULTIPOINTZ)
--- 1530,1538 ----
  
      }
  
!   /* ==================================================================== */
!   /*  Extract vertices for a MultiPoint.                                  */
!   /* ==================================================================== */
    else if (psShape->nSHPType == SHPT_MULTIPOINT
  	   || psShape->nSHPType == SHPT_MULTIPOINTM
  	   || psShape->nSHPType == SHPT_MULTIPOINTZ)
***************
*** 1545,1553 ****
  
        nOffset = 48 + 16 * nPoints;
  
! /* -------------------------------------------------------------------- */
! /*	Get the X/Y bounds.						*/
! /* -------------------------------------------------------------------- */
        memcpy (&(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8);
        memcpy (&(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8);
        memcpy (&(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8);
--- 1563,1571 ----
  
        nOffset = 48 + 16 * nPoints;
  
!       /* -------------------------------------------------------------------- */
!       /*      Get the X/Y bounds.                                             */
!       /* -------------------------------------------------------------------- */
        memcpy (&(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8);
        memcpy (&(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8);
        memcpy (&(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8);
***************
*** 1562,1570 ****
        if (bBigEndian)
  	SwapWord (8, &(psShape->dfYMax));
  
! /* -------------------------------------------------------------------- */
! /*      If we have a Z coordinate, collect that now.                    */
! /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_MULTIPOINTZ)
  	{
  	  memcpy (&(psShape->dfZMin), psSHP->pabyRec + nOffset, 8);
--- 1580,1588 ----
        if (bBigEndian)
  	SwapWord (8, &(psShape->dfYMax));
  
!       /* -------------------------------------------------------------------- */
!       /*      If we have a Z coordinate, collect that now.                    */
!       /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_MULTIPOINTZ)
  	{
  	  memcpy (&(psShape->dfZMin), psSHP->pabyRec + nOffset, 8);
***************
*** 1586,1597 ****
  	  nOffset += 16 + 8 * nPoints;
  	}
  
! /* -------------------------------------------------------------------- */
! /*      If we have a M measure value, then read it now.  We assume      */
! /*      that the measure can be present for any shape if the size is    */
! /*      big enough, but really it will only occur for the Z shapes      */
! /*      (options), and the M shapes.                                    */
! /* -------------------------------------------------------------------- */
        if (psSHP->panRecSize[hEntity] + 8 >= nOffset + 16 + 8 * nPoints)
  	{
  	  memcpy (&(psShape->dfMMin), psSHP->pabyRec + nOffset, 8);
--- 1604,1615 ----
  	  nOffset += 16 + 8 * nPoints;
  	}
  
!       /* -------------------------------------------------------------------- */
!       /*      If we have a M measure value, then read it now.  We assume      */
!       /*      that the measure can be present for any shape if the size is    */
!       /*      big enough, but really it will only occur for the Z shapes      */
!       /*      (options), and the M shapes.                                    */
!       /* -------------------------------------------------------------------- */
        if (psSHP->panRecSize[hEntity] + 8 >= nOffset + 16 + 8 * nPoints)
  	{
  	  memcpy (&(psShape->dfMMin), psSHP->pabyRec + nOffset, 8);
***************
*** 1612,1620 ****
  	}
      }
  
! /* ==================================================================== */
! /*      Extract vertices for a point.                                   */
! /* ==================================================================== */
    else if (psShape->nSHPType == SHPT_POINT
  	   || psShape->nSHPType == SHPT_POINTM
  	   || psShape->nSHPType == SHPT_POINTZ)
--- 1630,1638 ----
  	}
      }
  
!   /* ==================================================================== */
!   /*      Extract vertices for a point.                                   */
!   /* ==================================================================== */
    else if (psShape->nSHPType == SHPT_POINT
  	   || psShape->nSHPType == SHPT_POINTM
  	   || psShape->nSHPType == SHPT_POINTZ)
***************
*** 1637,1645 ****
  
        nOffset = 20 + 8;
  
! /* -------------------------------------------------------------------- */
! /*      If we have a Z coordinate, collect that now.                    */
! /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_POINTZ)
  	{
  	  memcpy (psShape->padfZ, psSHP->pabyRec + nOffset, 8);
--- 1655,1663 ----
  
        nOffset = 20 + 8;
  
!       /* -------------------------------------------------------------------- */
!       /*      If we have a Z coordinate, collect that now.                    */
!       /* -------------------------------------------------------------------- */
        if (psShape->nSHPType == SHPT_POINTZ)
  	{
  	  memcpy (psShape->padfZ, psSHP->pabyRec + nOffset, 8);
***************
*** 1650,1661 ****
  	  nOffset += 8;
  	}
  
! /* -------------------------------------------------------------------- */
! /*      If we have a M measure value, then read it now.  We assume      */
! /*      that the measure can be present for any shape if the size is    */
! /*      big enough, but really it will only occur for the Z shapes      */
! /*      (options), and the M shapes.                                    */
! /* -------------------------------------------------------------------- */
        if (psSHP->panRecSize[hEntity] + 8 >= nOffset + 8)
  	{
  	  memcpy (psShape->padfM, psSHP->pabyRec + nOffset, 8);
--- 1668,1679 ----
  	  nOffset += 8;
  	}
  
!       /* -------------------------------------------------------------------- */
!       /*      If we have a M measure value, then read it now.  We assume      */
!       /*      that the measure can be present for any shape if the size is    */
!       /*      big enough, but really it will only occur for the Z shapes      */
!       /*      (options), and the M shapes.                                    */
!       /* -------------------------------------------------------------------- */
        if (psSHP->panRecSize[hEntity] + 8 >= nOffset + 8)
  	{
  	  memcpy (psShape->padfM, psSHP->pabyRec + nOffset, 8);
***************
*** 1664,1673 ****
  	    SwapWord (8, psShape->padfM);
  	}
  
! /* -------------------------------------------------------------------- */
! /*      Since no extents are supplied in the record, we will apply      */
! /*      them from the single vertex.                                    */
! /* -------------------------------------------------------------------- */
        psShape->dfXMin = psShape->dfXMax = psShape->padfX[0];
        psShape->dfYMin = psShape->dfYMax = psShape->padfY[0];
        psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0];
--- 1682,1691 ----
  	    SwapWord (8, psShape->padfM);
  	}
  
!       /* -------------------------------------------------------------------- */
!       /*      Since no extents are supplied in the record, we will apply      */
!       /*      them from the single vertex.                                    */
!       /* -------------------------------------------------------------------- */
        psShape->dfXMin = psShape->dfXMax = psShape->padfX[0];
        psShape->dfYMin = psShape->dfYMax = psShape->padfY[0];
        psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0];
***************
*** 1806,1834 ****
  {
    int iOpRing, bAltered = 0;
  
! /* -------------------------------------------------------------------- */
! /*      Do nothing if this is not a polygon object.                     */
! /* -------------------------------------------------------------------- */
    if (psObject->nSHPType != SHPT_POLYGON
        && psObject->nSHPType != SHPT_POLYGONZ
        && psObject->nSHPType != SHPT_POLYGONM)
      return 0;
  
! /* -------------------------------------------------------------------- */
! /*      Process each of the rings.                                      */
! /* -------------------------------------------------------------------- */
    for (iOpRing = 0; iOpRing < psObject->nParts; iOpRing++)
      {
        int bInner, iVert, nVertCount, nVertStart, iCheckRing;
        double dfSum, dfTestX, dfTestY;
  
! /* -------------------------------------------------------------------- */
! /*      Determine if this ring is an inner ring or an outer ring        */
! /*      relative to all the other rings.  For now we assume the         */
! /*      first ring is outer and all others are inner, but eventually    */
! /*      we need to fix this to handle multiple island polygons and      */
! /*      unordered sets of rings.                                        */
! /* -------------------------------------------------------------------- */
        dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]];
        dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]];
  
--- 1824,1855 ----
  {
    int iOpRing, bAltered = 0;
  
!   /* -------------------------------------------------------------------- */
!   /*      Do nothing if this is not a polygon object.                     */
!   /* -------------------------------------------------------------------- */
    if (psObject->nSHPType != SHPT_POLYGON
        && psObject->nSHPType != SHPT_POLYGONZ
        && psObject->nSHPType != SHPT_POLYGONM)
      return 0;
  
!   if (psObject->nVertices == 0 || psObject->nParts == 0)
!     return 0;
! 
!   /* -------------------------------------------------------------------- */
!   /*      Process each of the rings.                                      */
!   /* -------------------------------------------------------------------- */
    for (iOpRing = 0; iOpRing < psObject->nParts; iOpRing++)
      {
        int bInner, iVert, nVertCount, nVertStart, iCheckRing;
        double dfSum, dfTestX, dfTestY;
  
!       /* -------------------------------------------------------------------- */
!       /*      Determine if this ring is an inner ring or an outer ring        */
!       /*      relative to all the other rings.  For now we assume the         */
!       /*      first ring is outer and all others are inner, but eventually    */
!       /*      we need to fix this to handle multiple island polygons and      */
!       /*      unordered sets of rings.                                        */
!       /* -------------------------------------------------------------------- */
        dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]];
        dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]];
  
***************
*** 1874,1883 ****
  	    }
  	}
  
! /* -------------------------------------------------------------------- */
! /*      Determine the current order of this ring so we will know if     */
! /*      it has to be reversed.                                          */
! /* -------------------------------------------------------------------- */
        nVertStart = psObject->panPartStart[iOpRing];
  
        if (iOpRing == psObject->nParts - 1)
--- 1895,1904 ----
  	    }
  	}
  
!       /* -------------------------------------------------------------------- */
!       /*      Determine the current order of this ring so we will know if     */
!       /*      it has to be reversed.                                          */
!       /* -------------------------------------------------------------------- */
        nVertStart = psObject->panPartStart[iOpRing];
  
        if (iOpRing == psObject->nParts - 1)
***************
*** 1896,1904 ****
        dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
  	- psObject->padfY[iVert] * psObject->padfX[nVertStart];
  
! /* -------------------------------------------------------------------- */
! /*      Reverse if necessary.                                           */
! /* -------------------------------------------------------------------- */
        if ((dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner))
  	{
  	  int i;
--- 1917,1925 ----
        dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart]
  	- psObject->padfY[iVert] * psObject->padfX[nVertStart];
  
!       /* -------------------------------------------------------------------- */
!       /*      Reverse if necessary.                                           */
!       /* -------------------------------------------------------------------- */
        if ((dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner))
  	{
  	  int i;


_______________________________________________
postgis-users mailing list
postgis-users@postgis.refractions.net
http://postgis.refractions.net/mailman/listinfo/postgis-users


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic