PostGIS  2.3.7dev-r@@SVN_REVISION@@
int SHPAPI_CALL DBFAddNativeFieldType ( DBFHandle  hDBF,
const char *  pszFieldName,
char  chType,
int  nWidth,
int  nDecimals 
)

Definition at line 820 of file dbfopen.c.

References DBFFlushRecord(), DBFGetNullCharacter(), DBFUpdateHeader(), FALSE, free(), malloc(), SfRealloc(), and TRUE.

Referenced by DBFAddField().

823 {
824  char *pszFInfo;
825  int i;
826  int nOldRecordLength, nOldHeaderLength;
827  char *pszRecord;
828  char chFieldFill;
829  SAOffset nRecordOffset;
830 
831  /* make sure that everything is written in .dbf */
832  if( !DBFFlushRecord( psDBF ) )
833  return -1;
834 
835 /* -------------------------------------------------------------------- */
836 /* Do some checking to ensure we can add records to this file. */
837 /* -------------------------------------------------------------------- */
838  if( nWidth < 1 )
839  return -1;
840 
841  if( nWidth > 255 )
842  nWidth = 255;
843 
844  nOldRecordLength = psDBF->nRecordLength;
845  nOldHeaderLength = psDBF->nHeaderLength;
846 
847 /* -------------------------------------------------------------------- */
848 /* SfRealloc all the arrays larger to hold the additional field */
849 /* information. */
850 /* -------------------------------------------------------------------- */
851  psDBF->nFields++;
852 
853  psDBF->panFieldOffset = (int *)
854  SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields );
855 
856  psDBF->panFieldSize = (int *)
857  SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields );
858 
859  psDBF->panFieldDecimals = (int *)
860  SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields );
861 
862  psDBF->pachFieldType = (char *)
863  SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );
864 
865 /* -------------------------------------------------------------------- */
866 /* Assign the new field information fields. */
867 /* -------------------------------------------------------------------- */
868  psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
869  psDBF->nRecordLength += nWidth;
870  psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
871  psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
872  psDBF->pachFieldType[psDBF->nFields-1] = chType;
873 
874 /* -------------------------------------------------------------------- */
875 /* Extend the required header information. */
876 /* -------------------------------------------------------------------- */
877  psDBF->nHeaderLength += 32;
878  psDBF->bUpdated = FALSE;
879 
880  psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32);
881 
882  pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1);
883 
884  for( i = 0; i < 32; i++ )
885  pszFInfo[i] = '\0';
886 
887  if( (int) strlen(pszFieldName) < 10 )
888  strncpy( pszFInfo, pszFieldName, strlen(pszFieldName));
889  else
890  strncpy( pszFInfo, pszFieldName, 10);
891 
892  pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
893 
894  if( chType == 'C' )
895  {
896  pszFInfo[16] = (unsigned char) (nWidth % 256);
897  pszFInfo[17] = (unsigned char) (nWidth / 256);
898  }
899  else
900  {
901  pszFInfo[16] = (unsigned char) nWidth;
902  pszFInfo[17] = (unsigned char) nDecimals;
903  }
904 
905 /* -------------------------------------------------------------------- */
906 /* Make the current record buffer appropriately larger. */
907 /* -------------------------------------------------------------------- */
908  psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord,
909  psDBF->nRecordLength);
910 
911  /* we're done if dealing with new .dbf */
912  if( psDBF->bNoHeader )
913  return( psDBF->nFields - 1 );
914 
915 /* -------------------------------------------------------------------- */
916 /* For existing .dbf file, shift records */
917 /* -------------------------------------------------------------------- */
918 
919  /* alloc record */
920  pszRecord = (char *) malloc(sizeof(char) * psDBF->nRecordLength);
921 
922  chFieldFill = DBFGetNullCharacter(chType);
923 
924  for (i = psDBF->nRecords-1; i >= 0; --i)
925  {
926  nRecordOffset = nOldRecordLength * (SAOffset) i + nOldHeaderLength;
927 
928  /* load record */
929  psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
930  psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
931 
932  /* set new field's value to NULL */
933  memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
934 
935  nRecordOffset = psDBF->nRecordLength * (SAOffset) i + psDBF->nHeaderLength;
936 
937  /* move record to the new place*/
938  psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
939  psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
940  }
941 
942  /* free record */
943  free(pszRecord);
944 
945  /* force update of header with new header, record length and new field */
946  psDBF->bNoHeader = TRUE;
947  DBFUpdateHeader( psDBF );
948 
949  psDBF->nCurrentRecord = -1;
950  psDBF->bCurrentRecordModified = FALSE;
951 
952  return( psDBF->nFields-1 );
953 }
static void * SfRealloc(void *pMem, int nNewSize)
Definition: dbfopen.c:179
unsigned long SAOffset
Definition: shapefil.h:250
static int DBFFlushRecord(DBFHandle psDBF)
Definition: dbfopen.c:258
#define FALSE
Definition: dbfopen.c:168
static char DBFGetNullCharacter(char chType)
Definition: dbfopen.c:796
void free(void *)
void * malloc(YYSIZE_T)
#define TRUE
Definition: dbfopen.c:169
void SHPAPI_CALL DBFUpdateHeader(DBFHandle psDBF)
Definition: dbfopen.c:334

Here is the call graph for this function:

Here is the caller graph for this function: