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

Definition at line 817 of file dbfopen.c.

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

Referenced by DBFAddField().

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

Here is the call graph for this function:

Here is the caller graph for this function: