📄 dbfopen.c
字号:
/* write access. *//* -------------------------------------------------------------------- */ if( psDBF->bUpdated ) { uchar abyFileHeader[32]; fseek( psDBF->fp, 0, 0 ); fread( abyFileHeader, 32, 1, psDBF->fp ); abyFileHeader[1] = 95; /* YY */ abyFileHeader[2] = 7; /* MM */ abyFileHeader[3] = 26; /* DD */ abyFileHeader[4] = psDBF->nRecords % 256; abyFileHeader[5] = (psDBF->nRecords/256) % 256; abyFileHeader[6] = (psDBF->nRecords/(256*256)) % 256; abyFileHeader[7] = (psDBF->nRecords/(256*256*256)) % 256; fseek( psDBF->fp, 0, 0 ); fwrite( abyFileHeader, 32, 1, psDBF->fp ); }/* -------------------------------------------------------------------- *//* Close, and free resources. *//* -------------------------------------------------------------------- */ fclose( psDBF->fp ); if( psDBF->panFieldOffset != NULL ) { free( psDBF->panFieldOffset ); free( psDBF->panFieldSize ); free( psDBF->panFieldDecimals ); free( psDBF->pachFieldType ); } free( psDBF->pszHeader ); free( psDBF->pszCurrentRecord ); free( psDBF ); if( pszStringField != NULL ) { free( pszStringField ); pszStringField = NULL; nStringFieldLen = 0; }}/************************************************************************//* DBFCreate() *//* *//* Create a new .dbf file. *//************************************************************************/DBFHandle DBFCreate( 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) malloc(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 DBFAddField(DBFHandle psDBF, const char * pszFieldName, DBFFieldType eType, 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( eType != FTDouble && nDecimals != 0 ) return( -1 );/* -------------------------------------------------------------------- *//* 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; if( eType == FTString ) psDBF->pachFieldType[psDBF->nFields-1] = 'C'; else psDBF->pachFieldType[psDBF->nFields-1] = 'N';/* -------------------------------------------------------------------- *//* 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( strlen(pszFieldName) < 10 ) strncpy( pszFInfo, pszFieldName, strlen(pszFieldName)); else strncpy( pszFInfo, pszFieldName, 10); pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1]; if( eType == FTString ) { pszFInfo[16] = nWidth % 256; pszFInfo[17] = nWidth / 256; } else { pszFInfo[16] = nWidth; pszFInfo[17] = 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 ){ int nRecordOffset; uchar *pabyRec; void *pReturnField = NULL; static double dDoubleField;/* -------------------------------------------------------------------- *//* Have we read the record? *//* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psDBF->nRecords ) return( NULL ); if( psDBF->nCurrentRecord != hEntity ) { DBFFlushRecord( psDBF ); nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; fseek( psDBF->fp, nRecordOffset, 0 ); fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); psDBF->nCurrentRecord = hEntity; } pabyRec = (uchar *) psDBF->pszCurrentRecord;/* -------------------------------------------------------------------- *//* Ensure our field buffer is large enough to hold this buffer. *//* -------------------------------------------------------------------- */ if( psDBF->panFieldSize[iField]+1 > nStringFieldLen ) { nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10; pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen); }/* -------------------------------------------------------------------- *//* Extract the requested field. *//* -------------------------------------------------------------------- */ strncpy( pszStringField, pabyRec+psDBF->panFieldOffset[iField], psDBF->panFieldSize[iField] ); pszStringField[psDBF->panFieldSize[iField]] = '\0'; pReturnField = pszStringField;/* -------------------------------------------------------------------- *//* Decode the field. *//* -------------------------------------------------------------------- */ if( chReqType == 'N' ) { dDoubleField = atof(pszStringField); pReturnField = &dDoubleField; }/* -------------------------------------------------------------------- *//* Should we trim white space off the string attribute value? *//* -------------------------------------------------------------------- */#ifdef TRIM_DBF_WHITESPACE else { char *pchSrc, *pchDst; pchDst = pchSrc = pszStringField; while( *pchSrc == ' ' ) pchSrc++; while( *pchSrc != '\0' ) *(pchDst++) = *(pchSrc++); *pchDst = '\0'; while( *(--pchDst) == ' ' && pchDst != pszStringField ) *pchDst = '\0'; }#endif return( pReturnField );}/************************************************************************//* DBFReadIntAttribute() *//* *//* Read an integer attribute. *//************************************************************************/int DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField ){ double *pdValue; pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); return( (int) *pdValue );}/************************************************************************//* DBFReadDoubleAttribute() *//* *//* Read a double attribute. *//************************************************************************/double DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField ){ double *pdValue; pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); return( *pdValue );}/************************************************************************//* DBFReadStringAttribute() *//* *//* Read a string attribute. *//************************************************************************/const char *DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField ){ return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) );}/************************************************************************//* DBFGetFieldCount() *//* *//* Return the number of fields in this table. *//************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -