PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ DBFAddNativeFieldType()

int SHPAPI_CALL DBFAddNativeFieldType ( DBFHandle  psDBF,
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}
static void * SfRealloc(void *pMem, int nNewSize)
Definition dbfopen.c:180
#define TRUE
Definition dbfopen.c:169
#define FALSE
Definition dbfopen.c:168
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: