PostGIS 3.7.0dev-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 844 of file dbfopen.c.

847{
848 char *pszFInfo;
849 int i;
850 int nOldRecordLength, nOldHeaderLength;
851 char *pszRecord;
852 char chFieldFill;
853 SAOffset nRecordOffset;
854
855 /* make sure that everything is written in .dbf */
856 if( !DBFFlushRecord( psDBF ) )
857 return -1;
858
859 if( psDBF->nHeaderLength + XBASE_FLDHDR_SZ > 65535 )
860 {
861 char szMessage[128];
862 snprintf( szMessage, sizeof(szMessage),
863 "Cannot add field %s. Header length limit reached "
864 "(max 65535 bytes, 2046 fields).",
865 pszFieldName );
866 psDBF->sHooks.Error( szMessage );
867 return -1;
868 }
869
870/* -------------------------------------------------------------------- */
871/* Do some checking to ensure we can add records to this file. */
872/* -------------------------------------------------------------------- */
873 if( nWidth < 1 )
874 return -1;
875
876 if( nWidth > XBASE_FLD_MAX_WIDTH )
877 nWidth = XBASE_FLD_MAX_WIDTH;
878
879 if( psDBF->nRecordLength + nWidth > 65535 )
880 {
881 char szMessage[128];
882 snprintf( szMessage, sizeof(szMessage),
883 "Cannot add field %s. Record length limit reached "
884 "(max 65535 bytes).",
885 pszFieldName );
886 psDBF->sHooks.Error( szMessage );
887 return -1;
888 }
889
890 nOldRecordLength = psDBF->nRecordLength;
891 nOldHeaderLength = psDBF->nHeaderLength;
892
893/* -------------------------------------------------------------------- */
894/* SfRealloc all the arrays larger to hold the additional field */
895/* information. */
896/* -------------------------------------------------------------------- */
897 psDBF->nFields++;
898
899 psDBF->panFieldOffset = STATIC_CAST(int *,
900 SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ));
901
902 psDBF->panFieldSize = STATIC_CAST(int *,
903 SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ));
904
905 psDBF->panFieldDecimals = STATIC_CAST(int *,
906 SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ));
907
908 psDBF->pachFieldType = STATIC_CAST(char *,
909 SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ));
910
911/* -------------------------------------------------------------------- */
912/* Assign the new field information fields. */
913/* -------------------------------------------------------------------- */
914 psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength;
915 psDBF->nRecordLength += nWidth;
916 psDBF->panFieldSize[psDBF->nFields-1] = nWidth;
917 psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals;
918 psDBF->pachFieldType[psDBF->nFields-1] = chType;
919
920/* -------------------------------------------------------------------- */
921/* Extend the required header information. */
922/* -------------------------------------------------------------------- */
924 psDBF->bUpdated = FALSE;
925
926 psDBF->pszHeader = STATIC_CAST(char *, SfRealloc(psDBF->pszHeader,
927 psDBF->nFields*XBASE_FLDHDR_SZ));
928
929 pszFInfo = psDBF->pszHeader + XBASE_FLDHDR_SZ * (psDBF->nFields-1);
930
931 for( i = 0; i < XBASE_FLDHDR_SZ; i++ )
932 pszFInfo[i] = '\0';
933
934 strncpy( pszFInfo, pszFieldName, XBASE_FLDNAME_LEN_WRITE );
935
936 pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1];
937
938 if( chType == 'C' )
939 {
940 pszFInfo[16] = STATIC_CAST(unsigned char, nWidth % 256);
941 pszFInfo[17] = STATIC_CAST(unsigned char, nWidth / 256);
942 }
943 else
944 {
945 pszFInfo[16] = STATIC_CAST(unsigned char, nWidth);
946 pszFInfo[17] = STATIC_CAST(unsigned char, nDecimals);
947 }
948
949/* -------------------------------------------------------------------- */
950/* Make the current record buffer appropriately larger. */
951/* -------------------------------------------------------------------- */
953 psDBF->nRecordLength));
954
955 /* we're done if dealing with new .dbf */
956 if( psDBF->bNoHeader )
957 return( psDBF->nFields - 1 );
958
959/* -------------------------------------------------------------------- */
960/* For existing .dbf file, shift records */
961/* -------------------------------------------------------------------- */
962
963 /* alloc record */
964 pszRecord = STATIC_CAST(char *, malloc(sizeof(char) * psDBF->nRecordLength));
965
966 chFieldFill = DBFGetNullCharacter(chType);
967
968 for (i = psDBF->nRecords-1; i >= 0; --i)
969 {
970 nRecordOffset = nOldRecordLength * STATIC_CAST(SAOffset, i) + nOldHeaderLength;
971
972 /* load record */
973 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
974 psDBF->sHooks.FRead( pszRecord, nOldRecordLength, 1, psDBF->fp );
975
976 /* set new field's value to NULL */
977 memset(pszRecord + nOldRecordLength, chFieldFill, nWidth);
978
979 nRecordOffset = psDBF->nRecordLength * STATIC_CAST(SAOffset, i) + psDBF->nHeaderLength;
980
981 /* move record to the new place*/
982 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
983 psDBF->sHooks.FWrite( pszRecord, psDBF->nRecordLength, 1, psDBF->fp );
984 }
985
986 if( psDBF->bWriteEndOfFileChar )
987 {
988 char ch = END_OF_FILE_CHARACTER;
989
990 nRecordOffset =
991 psDBF->nRecordLength * STATIC_CAST(SAOffset,psDBF->nRecords) + psDBF->nHeaderLength;
992
993 psDBF->sHooks.FSeek( psDBF->fp, nRecordOffset, 0 );
994 psDBF->sHooks.FWrite( &ch, 1, 1, psDBF->fp );
995 }
996
997 /* free record */
998 free(pszRecord);
999
1000 /* force update of header with new header, record length and new field */
1001 psDBF->bNoHeader = TRUE;
1002 DBFUpdateHeader( psDBF );
1003
1004 psDBF->nCurrentRecord = -1;
1006 psDBF->bUpdated = TRUE;
1007
1008 return( psDBF->nFields-1 );
1009}
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:820
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
int bWriteEndOfFileChar
Definition shapefil.h:631
int nRecordLength
Definition shapefil.h:596
int * panFieldOffset
Definition shapefil.h:601
int * panFieldDecimals
Definition shapefil.h:603
int nFields
Definition shapefil.h:600
int bUpdated
Definition shapefil.h:616
int nHeaderLength
Definition shapefil.h:597
int * panFieldSize
Definition shapefil.h:602
char * pszCurrentRecord
Definition shapefil.h:610
int bCurrentRecordModified
Definition shapefil.h:609
char * pszHeader
Definition shapefil.h:606
SAFile fp
Definition shapefil.h:592
char * pachFieldType
Definition shapefil.h:604
SAHooks sHooks
Definition shapefil.h:590
int bNoHeader
Definition shapefil.h:615
int nRecords
Definition shapefil.h:594
int nCurrentRecord
Definition shapefil.h:608
void(* Error)(const char *message)
Definition shapefil.h:299
SAOffset(* FWrite)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition shapefil.h:292
SAOffset(* FRead)(void *p, SAOffset size, SAOffset nmemb, SAFile file)
Definition shapefil.h:291
SAOffset(* FSeek)(SAFile file, SAOffset offset, int whence)
Definition shapefil.h:293

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: