📄 dbfopen.c
字号:
/* -------------------------------------------------------------------- */ pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen); psDBF->pszHeader = (char *) pabyBuf; fseek( psDBF->fp, 32, 0 ); if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 ) { fclose( psDBF->fp ); free( pabyBuf ); free( psDBF ); return NULL; } psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields); psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields); psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields); psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields); for( iField = 0; iField < nFields; iField++ ) { unsigned char *pabyFInfo; pabyFInfo = pabyBuf+iField*32; if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' ) { psDBF->panFieldSize[iField] = pabyFInfo[16]; psDBF->panFieldDecimals[iField] = pabyFInfo[17]; } else { psDBF->panFieldSize[iField] = pabyFInfo[16]; psDBF->panFieldDecimals[iField] = 0;/*** The following seemed to be used sometimes to handle files with long** string fields, but in other cases (such as bug 1202) the decimals field** just seems to indicate some sort of preferred formatting, not very** wide fields. So I have disabled this code. FrankW. psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256; psDBF->panFieldDecimals[iField] = 0;*/ } psDBF->pachFieldType[iField] = (char) pabyFInfo[11]; if( iField == 0 ) psDBF->panFieldOffset[iField] = 1; else psDBF->panFieldOffset[iField] = psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1]; } return( psDBF );}/************************************************************************//* DBFClose() *//************************************************************************/void SHPAPI_CALLDBFClose(DBFHandle psDBF){/* -------------------------------------------------------------------- *//* Write out header if not already written. *//* -------------------------------------------------------------------- */ if( psDBF->bNoHeader ) DBFWriteHeader( psDBF ); DBFFlushRecord( psDBF );/* -------------------------------------------------------------------- *//* Update last access date, and number of records if we have *//* write access. *//* -------------------------------------------------------------------- */ if( psDBF->bUpdated ) DBFUpdateHeader( psDBF );/* -------------------------------------------------------------------- *//* Close, and free resources. *//* -------------------------------------------------------------------- */ fclose( psDBF->fp ); if( psDBF->panFieldOffset != NULL ) { free( psDBF->panFieldOffset ); free( psDBF->panFieldSize ); free( psDBF->panFieldDecimals ); free( psDBF->pachFieldType ); } if( psDBF->pszWorkField != NULL ) free( psDBF->pszWorkField ); free( psDBF->pszHeader ); free( psDBF->pszCurrentRecord ); free( psDBF );}/************************************************************************//* DBFCreate() *//* *//* Create a new .dbf file. *//************************************************************************/DBFHandle SHPAPI_CALLDBFCreate( const char * pszFilename ){ DBFHandle psDBF; FILE *fp; char *pszFullname, *pszBasename; int i;/* -------------------------------------------------------------------- *//* Compute the base (layer) name. If there is any extension *//* on the passed in filename we will strip it off. *//* -------------------------------------------------------------------- */ pszBasename = (char *) malloc(strlen(pszFilename)+5); strcpy( pszBasename, pszFilename ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; pszFullname = (char *) malloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s.dbf", pszBasename ); free( pszBasename );/* -------------------------------------------------------------------- *//* Create the file. *//* -------------------------------------------------------------------- */ fp = fopen( pszFullname, "wb" ); if( fp == NULL ) return( NULL ); fputc( 0, fp ); fclose( fp ); fp = fopen( pszFullname, "rb+" ); if( fp == NULL ) return( NULL ); free( pszFullname );/* -------------------------------------------------------------------- *//* Create the info structure. *//* -------------------------------------------------------------------- */ psDBF = (DBFHandle) calloc(1,sizeof(DBFInfo)); psDBF->fp = fp; psDBF->nRecords = 0; psDBF->nFields = 0; psDBF->nRecordLength = 1; psDBF->nHeaderLength = 33; psDBF->panFieldOffset = NULL; psDBF->panFieldSize = NULL; psDBF->panFieldDecimals = NULL; psDBF->pachFieldType = NULL; psDBF->pszHeader = NULL; psDBF->nCurrentRecord = -1; psDBF->bCurrentRecordModified = FALSE; psDBF->pszCurrentRecord = NULL; psDBF->bNoHeader = TRUE; return( psDBF );}/************************************************************************//* DBFAddField() *//* *//* Add a field to a newly created .dbf file before any records *//* are written. *//************************************************************************/int SHPAPI_CALLDBFAddField(DBFHandle psDBF, const char * pszFieldName, DBFFieldType eType, int nWidth, int nDecimals ){ char chNativeType = 'C'; if( eType == FTLogical ) chNativeType = 'L'; else if( eType == FTString ) chNativeType = 'C';
else if( eType == FTDate )
chNativeType = 'D'; else chNativeType = 'N'; return DBFAddNativeFieldType( psDBF, pszFieldName, chNativeType, nWidth, nDecimals );}/************************************************************************//* DBFAddField() *//* *//* Add a field to a newly created .dbf file before any records *//* are written. *//************************************************************************/int SHPAPI_CALLDBFAddNativeFieldType(DBFHandle psDBF, const char * pszFieldName, char chType, int nWidth, int nDecimals ){ char *pszFInfo; int i;/* -------------------------------------------------------------------- *//* Do some checking to ensure we can add records to this file. *//* -------------------------------------------------------------------- */ if( psDBF->nRecords > 0 ) return( -1 ); if( !psDBF->bNoHeader ) return( -1 ); if( nWidth < 1 ) return -1; if( nWidth > 255 ) nWidth = 255;/* -------------------------------------------------------------------- *//* SfRealloc all the arrays larger to hold the additional field *//* information. *//* -------------------------------------------------------------------- */ psDBF->nFields++; psDBF->panFieldOffset = (int *) SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); psDBF->panFieldSize = (int *) SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); psDBF->panFieldDecimals = (int *) SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); psDBF->pachFieldType = (char *) SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields );/* -------------------------------------------------------------------- *//* Assign the new field information fields. *//* -------------------------------------------------------------------- */ psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength; psDBF->nRecordLength += nWidth; psDBF->panFieldSize[psDBF->nFields-1] = nWidth; psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals; psDBF->pachFieldType[psDBF->nFields-1] = chType;/* -------------------------------------------------------------------- *//* Extend the required header information. *//* -------------------------------------------------------------------- */ psDBF->nHeaderLength += 32; psDBF->bUpdated = FALSE; psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32); pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1); for( i = 0; i < 32; i++ ) pszFInfo[i] = '\0'; if( (int) strlen(pszFieldName) < 10 ) strncpy( pszFInfo, pszFieldName, strlen(pszFieldName)); else strncpy( pszFInfo, pszFieldName, 10); pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1]; if( chType == 'C' ) { pszFInfo[16] = (unsigned char) (nWidth % 256); pszFInfo[17] = (unsigned char) (nWidth / 256); } else { pszFInfo[16] = (unsigned char) nWidth; pszFInfo[17] = (unsigned char) nDecimals; } /* -------------------------------------------------------------------- *//* Make the current record buffer appropriately larger. *//* -------------------------------------------------------------------- */ psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord, psDBF->nRecordLength); return( psDBF->nFields-1 );}/************************************************************************//* DBFReadAttribute() *//* *//* Read one of the attribute fields of a record. *//************************************************************************/static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, char chReqType ){ unsigned char *pabyRec; void *pReturnField = NULL; static double dDoubleField;/* -------------------------------------------------------------------- *//* Verify selection. *//* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psDBF->nRecords ) return( NULL ); if( iField < 0 || iField >= psDBF->nFields ) return( NULL );/* -------------------------------------------------------------------- *//* Have we read the record? *//* -------------------------------------------------------------------- */ if( !DBFLoadRecord( psDBF, hEntity ) ) return NULL; pabyRec = (unsigned char *) psDBF->pszCurrentRecord;/* -------------------------------------------------------------------- *//* Ensure we have room to extract the target field. *//* -------------------------------------------------------------------- */ if( psDBF->panFieldSize[iField] >= psDBF->nWorkFieldLength ) { psDBF->nWorkFieldLength = psDBF->panFieldSize[iField] + 100; if( psDBF->pszWorkField == NULL ) psDBF->pszWorkField = (char *) malloc(psDBF->nWorkFieldLength); else psDBF->pszWorkField = (char *) realloc(psDBF->pszWorkField, psDBF->nWorkFieldLength); }/* -------------------------------------------------------------------- *//* Extract the requested field. *//* -------------------------------------------------------------------- */ strncpy( psDBF->pszWorkField, ((const char *) pabyRec) + psDBF->panFieldOffset[iField], psDBF->panFieldSize[iField] ); psDBF->pszWorkField[psDBF->panFieldSize[iField]] = '\0'; pReturnField = psDBF->pszWorkField;/* -------------------------------------------------------------------- *//* Decode the field. *//* -------------------------------------------------------------------- */ if( chReqType == 'N' ) { dDoubleField = atof(psDBF->pszWorkField); pReturnField = &dDoubleField; }/* -------------------------------------------------------------------- *//* Should we trim white space off the string attribute value? *//* -------------------------------------------------------------------- */#ifdef TRIM_DBF_WHITESPACE else { char *pchSrc, *pchDst; pchDst = pchSrc = psDBF->pszWorkField; while( *pchSrc == ' ' ) pchSrc++; while( *pchSrc != '\0' ) *(pchDst++) = *(pchSrc++); *pchDst = '\0'; while( pchDst != psDBF->pszWorkField && *(--pchDst) == ' ' ) *pchDst = '\0'; }#endif return( pReturnField );}/************************************************************************//* DBFReadIntAttribute() *//* *//* Read an integer attribute. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -