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

◆ DBFAlterFieldDefn()

int SHPAPI_CALL DBFAlterFieldDefn ( DBFHandle  psDBF,
int  iField,
const char *  pszFieldName,
char  chType,
int  nWidth,
int  nDecimals 
)

Definition at line 1965 of file dbfopen.c.

1966{
1967 int i;
1968 int iRecord;
1969 int nOffset;
1970 int nOldWidth;
1971 int nOldRecordLength;
1972 int nRecordOffset;
1973 char *pszFInfo;
1974 char chOldType;
1975 int bIsNULL;
1976 char chFieldFill;
1977
1978 if (iField < 0 || iField >= psDBF->nFields)
1979 return FALSE;
1980
1981 /* make sure that everything is written in .dbf */
1982 if (!DBFFlushRecord(psDBF))
1983 return FALSE;
1984
1985 chFieldFill = DBFGetNullCharacter(chType);
1986
1987 chOldType = psDBF->pachFieldType[iField];
1988 nOffset = psDBF->panFieldOffset[iField];
1989 nOldWidth = psDBF->panFieldSize[iField];
1990 nOldRecordLength = psDBF->nRecordLength;
1991
1992 /* -------------------------------------------------------------------- */
1993 /* Do some checking to ensure we can add records to this file. */
1994 /* -------------------------------------------------------------------- */
1995 if (nWidth < 1)
1996 return -1;
1997
1998 if (nWidth > 255)
1999 nWidth = 255;
2000
2001 /* -------------------------------------------------------------------- */
2002 /* Assign the new field information fields. */
2003 /* -------------------------------------------------------------------- */
2004 psDBF->panFieldSize[iField] = nWidth;
2005 psDBF->panFieldDecimals[iField] = nDecimals;
2006 psDBF->pachFieldType[iField] = chType;
2007
2008 /* -------------------------------------------------------------------- */
2009 /* Update the header information. */
2010 /* -------------------------------------------------------------------- */
2011 pszFInfo = psDBF->pszHeader + 32 * iField;
2012
2013 for (i = 0; i < 32; i++)
2014 pszFInfo[i] = '\0';
2015
2016 snprintf(pszFInfo, 10, "%s", pszFieldName);
2017
2018 pszFInfo[11] = psDBF->pachFieldType[iField];
2019
2020 if (chType == 'C')
2021 {
2022 pszFInfo[16] = (unsigned char)(nWidth % 256);
2023 pszFInfo[17] = (unsigned char)(nWidth / 256);
2024 }
2025 else
2026 {
2027 pszFInfo[16] = (unsigned char)nWidth;
2028 pszFInfo[17] = (unsigned char)nDecimals;
2029 }
2030
2031 /* -------------------------------------------------------------------- */
2032 /* Update offsets */
2033 /* -------------------------------------------------------------------- */
2034 if (nWidth != nOldWidth)
2035 {
2036 for (i = iField + 1; i < psDBF->nFields; i++)
2037 psDBF->panFieldOffset[i] += nWidth - nOldWidth;
2038 psDBF->nRecordLength += nWidth - nOldWidth;
2039
2040 psDBF->pszCurrentRecord = (char *)SfRealloc(psDBF->pszCurrentRecord, psDBF->nRecordLength);
2041 }
2042
2043 /* we're done if we're dealing with not yet created .dbf */
2044 if (psDBF->bNoHeader && psDBF->nRecords == 0)
2045 return TRUE;
2046
2047 /* force update of header with new header and record length */
2048 psDBF->bNoHeader = TRUE;
2049 DBFUpdateHeader(psDBF);
2050
2051 if (nWidth < nOldWidth || (nWidth == nOldWidth && chType != chOldType))
2052 {
2053 char *pszRecord = (char *)malloc(sizeof(char) * nOldRecordLength);
2054 char *pszOldField = (char *)malloc(sizeof(char) * (nOldWidth + 1));
2055
2056 pszOldField[nOldWidth] = 0;
2057
2058 /* move records to their new positions */
2059 for (iRecord = 0; iRecord < psDBF->nRecords; iRecord++)
2060 {
2061 nRecordOffset = nOldRecordLength * (SAOffset)iRecord + psDBF->nHeaderLength;
2062
2063 /* load record */
2064 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2065 psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp);
2066
2067 memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
2068 bIsNULL = DBFIsValueNULL(chOldType, pszOldField);
2069
2070 if (nWidth != nOldWidth)
2071 {
2072 if ((chOldType == 'N' || chOldType == 'F') && pszOldField[0] == ' ')
2073 {
2074 /* Strip leading spaces when truncating a numeric field */
2075 memmove(pszRecord + nOffset, pszRecord + nOffset + nOldWidth - nWidth, nWidth);
2076 }
2077 if (nOffset + nOldWidth < nOldRecordLength)
2078 {
2079 memmove(pszRecord + nOffset + nWidth,
2080 pszRecord + nOffset + nOldWidth,
2081 nOldRecordLength - (nOffset + nOldWidth));
2082 }
2083 }
2084
2085 /* Convert null value to the appropriate value of the new type */
2086 if (bIsNULL)
2087 {
2088 memset(pszRecord + nOffset, chFieldFill, nWidth);
2089 }
2090
2091 nRecordOffset = psDBF->nRecordLength * (SAOffset)iRecord + psDBF->nHeaderLength;
2092
2093 /* write record */
2094 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2095 psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
2096 }
2097
2098 free(pszRecord);
2099 free(pszOldField);
2100 }
2101 else if (nWidth > nOldWidth)
2102 {
2103 char *pszRecord = (char *)malloc(sizeof(char) * psDBF->nRecordLength);
2104 char *pszOldField = (char *)malloc(sizeof(char) * (nOldWidth + 1));
2105
2106 pszOldField[nOldWidth] = 0;
2107
2108 /* move records to their new positions */
2109 for (iRecord = psDBF->nRecords - 1; iRecord >= 0; iRecord--)
2110 {
2111 nRecordOffset = nOldRecordLength * (SAOffset)iRecord + psDBF->nHeaderLength;
2112
2113 /* load record */
2114 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2115 psDBF->sHooks.FRead(pszRecord, nOldRecordLength, 1, psDBF->fp);
2116
2117 memcpy(pszOldField, pszRecord + nOffset, nOldWidth);
2118 bIsNULL = DBFIsValueNULL(chOldType, pszOldField);
2119
2120 if (nOffset + nOldWidth < nOldRecordLength)
2121 {
2122 memmove(pszRecord + nOffset + nWidth,
2123 pszRecord + nOffset + nOldWidth,
2124 nOldRecordLength - (nOffset + nOldWidth));
2125 }
2126
2127 /* Convert null value to the appropriate value of the new type */
2128 if (bIsNULL)
2129 {
2130 memset(pszRecord + nOffset, chFieldFill, nWidth);
2131 }
2132 else
2133 {
2134 if ((chOldType == 'N' || chOldType == 'F'))
2135 {
2136 /* Add leading spaces when expanding a numeric field */
2137 memmove(
2138 pszRecord + nOffset + nWidth - nOldWidth, pszRecord + nOffset, nOldWidth);
2139 memset(pszRecord + nOffset, ' ', nWidth - nOldWidth);
2140 }
2141 else
2142 {
2143 /* Add trailing spaces */
2144 memset(pszRecord + nOffset + nOldWidth, ' ', nWidth - nOldWidth);
2145 }
2146 }
2147
2148 nRecordOffset = psDBF->nRecordLength * (SAOffset)iRecord + psDBF->nHeaderLength;
2149
2150 /* write record */
2151 psDBF->sHooks.FSeek(psDBF->fp, nRecordOffset, 0);
2152 psDBF->sHooks.FWrite(pszRecord, psDBF->nRecordLength, 1, psDBF->fp);
2153 }
2154
2155 free(pszRecord);
2156 free(pszOldField);
2157 }
2158
2159 psDBF->nCurrentRecord = -1;
2160 psDBF->bCurrentRecordModified = FALSE;
2161
2162 return TRUE;
2163}
static int DBFIsValueNULL(char chType, const char *pszValue)
Definition dbfopen.c:1080
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(), DBFIsValueNULL(), DBFUpdateHeader(), FALSE, free(), malloc(), SfRealloc(), and TRUE.

Here is the call graph for this function: