PostGIS  2.2.8dev-r@@SVN_REVISION@@

◆ DBFAddNativeFieldType()

int SHPAPI_CALL DBFAddNativeFieldType ( DBFHandle  hDBF,
const char *  pszFieldName,
char  chType,
int  nWidth,
int  nDecimals 
)

Definition at line 816 of file dbfopen.c.

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

Referenced by DBFAddField().

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