PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ DBFAddNativeFieldType()

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

Definition at line 802 of file dbfopen.c.

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

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

Referenced by DBFAddField().

Here is the call graph for this function:
Here is the caller graph for this function: