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

◆ DBFAddNativeFieldType()

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

Definition at line 835 of file dbfopen.c.

838{
839 char *pszFInfo;
840 int i;
841 int nOldRecordLength, nOldHeaderLength;
842 char *pszRecord;
843 char chFieldFill;
844 SAOffset nRecordOffset;
845
846 /* make sure that everything is written in .dbf */
847 if( !DBFFlushRecord( psDBF ) )
848 return -1;
849
850 if( psDBF->nHeaderLength + XBASE_FLDHDR_SZ > 65535 )
851 {
852 char szMessage[128];
853 snprintf( szMessage, sizeof(szMessage),
854 "Cannot add field %s. Header length limit reached "
855 "(max 65535 bytes, 2046 fields).",
856 pszFieldName );
857 psDBF->sHooks.Error( szMessage );
858 return -1;
859 }
860
861/* -------------------------------------------------------------------- */
862/* Do some checking to ensure we can add records to this file. */
863/* -------------------------------------------------------------------- */
864 if( nWidth < 1 )
865 return -1;
866
867 if( nWidth > XBASE_FLD_MAX_WIDTH )
868 nWidth = XBASE_FLD_MAX_WIDTH;
869
870 if( psDBF->nRecordLength + nWidth > 65535 )
871 {
872 char szMessage[128];
873 snprintf( szMessage, sizeof(szMessage),
874 "Cannot add field %s. Record length limit reached "
875 "(max 65535 bytes).",
876 pszFieldName );
877 psDBF->sHooks.Error( szMessage );
878 return -1;
879 }
880
881 nOldRecordLength = psDBF->nRecordLength;
882 nOldHeaderLength = psDBF->nHeaderLength;
883
884/* -------------------------------------------------------------------- */
885/* SfRealloc all the arrays larger to hold the additional field */
886/* information. */
887/* -------------------------------------------------------------------- */
888 psDBF->nFields++;
889
890 psDBF->panFieldOffset = STATIC_CAST(int *,
891 SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ));
892
893 psDBF->panFieldSize = STATIC_CAST(int *,
894 SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ));
895
896 psDBF->panFieldDecimals = STATIC_CAST(int *,
897 SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ));
898
899 psDBF->pachFieldType = STATIC_CAST(char *,
900 SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ));
901
902/* -------------------------------------------------------------------- */
903/* Assign the new field information fields. */
904/* -------------------------------------------------------------------- */
905 psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
906 psDBF->nRecordLength += nWidth;
907 psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
908 psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
909 psDBF->pachFieldType[psDBF->nFields-1] = chType;
910
911/* -------------------------------------------------------------------- */
912/* Extend the required header information. */
913/* -------------------------------------------------------------------- */
914 psDBF->nHeaderLength += XBASE_FLDHDR_SZ;
915 psDBF->bUpdated = FALSE;
916
917 psDBF->pszHeader = STATIC_CAST(char *, SfRealloc(psDBF->pszHeader,
918 psDBF->nFields*XBASE_FLDHDR_SZ));
919
920 pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * (psDBF->nFields-1);
921
922 for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
923 pszFInfo[i] = '\0';
924
925 strncpy( pszFInfo, pszFieldName, XBASE_FLDNAME_LEN_WRITE );
926
927 pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
928
929 if( chType == 'C' )
930 {
931 pszFInfo[16] = STATIC_CAST(unsigned char, nWidth % 256);
932 pszFInfo[17] = STATIC_CAST(unsigned char, nWidth / 256);
933 }
934 else
935 {
936 pszFInfo[16] = STATIC_CAST(unsigned char, nWidth);
937 pszFInfo[17] = STATIC_CAST(unsigned char, nDecimals);
938 }
939
940/* -------------------------------------------------------------------- */
941/* Make the current record buffer appropriately larger. */
942/* -------------------------------------------------------------------- */
943 psDBF->pszCurrentRecord = STATIC_CAST(char *, SfRealloc(psDBF->pszCurrentRecord,
944 psDBF->nRecordLength));
945
946 /* we're done if dealing with new .dbf */
947 if( psDBF->bNoHeader )
948 return( psDBF->nFields - 1 );
949
950/* -------------------------------------------------------------------- */
951/* For existing .dbf file, shift records */
952/* -------------------------------------------------------------------- */
953
954 /* alloc record */
955 pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
956
957 chFieldFill = DBFGetNullCharacter(chType);
958
959 for (i = psDBF->nRecords-1; i >= 0; --i)
960 {
961 nRecordOffset = nOldRecordLength * STATIC_CAST(SAOffset, i) + nOldHeaderLength;
962
963 /* load record */
964 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
965 psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
966
967 /* set new field's value to NULL */
968 memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
969
970 nRecordOffset = psDBF->nRecordLength * STATIC_CAST(SAOffset, i) + psDBF->nHeaderLength;
971
972 /* move record to the new place*/
973 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
974 psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
975 }
976
977 if( psDBF->bWriteEndOfFileChar )
978 {
979 char ch = END_OF_FILE_CHARACTER;
980
981 nRecordOffset =
982 psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength;
983
984 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
985 psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
986 }
987
988 /* free record */
989 free(pszRecord);
990
991 /* force update of header with new header, record length and new field */
992 psDBF->bNoHeader = TRUE;
993 DBFUpdateHeader( psDBF );
994
995 psDBF->nCurrentRecord = -1;
996 psDBF->bCurrentRecordModified = FALSE;
997 psDBF->bUpdated = TRUE;
998
999 return( psDBF->nFields-1 );
1000}
static void * SfRealloc(void *pMem, int nNewSize)
Definition dbfopen.c:109
#define STATIC_CAST(type, x)
Definition dbfopen.c:96
#define TRUE
Definition dbfopen.c:73
#define FALSE
Definition dbfopen.c:72
#define END_OF_FILE_CHARACTER
Definition dbfopen.c:82
static char DBFGetNullCharacter(char chType)
Definition dbfopen.c:811
static int DBFFlushRecord(DBFHandle psDBF)
Definition dbfopen.c:195
void SHPAPI_CALL DBFUpdateHeader(DBFHandle psDBF)
Definition dbfopen.c:304
void * malloc(YYSIZE_T)
void free(void *)
#define XBASE_FLDNAME_LEN_WRITE
Definition shapefil.h:652
#define XBASE_FLDHDR_SZ
Definition shapefil.h:648
#define XBASE_FLD_MAX_WIDTH
Definition shapefil.h:654
unsigned long SAOffset
Definition shapefil.h:286

References DBFInfo::bCurrentRecordModified, DBFInfo::bNoHeader, DBFInfo::bUpdated, DBFInfo::bWriteEndOfFileChar, DBFFlushRecord(), DBFGetNullCharacter(), DBFUpdateHeader(), END_OF_FILE_CHARACTER, SAHooks::Error, FALSE, DBFInfo::fp, SAHooks::FRead, free(), SAHooks::FSeek, SAHooks::FWrite, malloc(), DBFInfo::nCurrentRecord, DBFInfo::nFields, DBFInfo::nHeaderLength, DBFInfo::nRecordLength, DBFInfo::nRecords, DBFInfo::pachFieldType, DBFInfo::panFieldDecimals, DBFInfo::panFieldOffset, DBFInfo::panFieldSize, DBFInfo::pszCurrentRecord, DBFInfo::pszHeader, SfRealloc(), DBFInfo::sHooks, STATIC_CAST, TRUE, XBASE_FLD_MAX_WIDTH, XBASE_FLDHDR_SZ, and XBASE_FLDNAME_LEN_WRITE.

Referenced by DBFAddField().

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