📄 dbfopen.c
字号:
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' || pabyFInfo[11] == 'D') { psDBF->panFieldSize[iField] = pabyFInfo[16]; psDBF->panFieldDecimals[iField] = pabyFInfo[17]; } else { 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 ) { unsigned char abyFileHeader[32]; struct tm *localTime;
time_t aclock;
fseek( psDBF->fp, 0, 0 ); fread( abyFileHeader, 32, 1, psDBF->fp );
time( &aclock );
localTime = localtime( &aclock );
abyFileHeader[1] = (unsigned char)(localTime->tm_year % 100); abyFileHeader[2] = (unsigned char)(localTime->tm_mon+1); abyFileHeader[3] = (unsigned char)(localTime->tm_mday); 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 );}/************************************************************************//* 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) 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 SHPAPI_CALLDBFAddField(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 ); if( nWidth < 1 || nWidth > 255 ) 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 == FTLogical ) psDBF->pachFieldType[psDBF->nFields-1] = 'L'; else if( eType == FTString ) psDBF->pachFieldType[psDBF->nFields-1] = 'C'; else if( eType == FTDate ) psDBF->pachFieldType[psDBF->nFields-1] = 'D'; 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( (int) 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; unsigned char *pabyRec; void *pReturnField = NULL; static double dDoubleField; static char fieldValue[256]; // max size for individual xbase field value is 255 chars/* -------------------------------------------------------------------- *//* Verify selection. *//* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psDBF->nRecords ) return( NULL ); if( iField < 0 || iField >= psDBF->nFields ) return( NULL );/* -------------------------------------------------------------------- *//* Have we read the record? *//* -------------------------------------------------------------------- */ if( psDBF->nCurrentRecord != hEntity ) { DBFFlushRecord( psDBF ); nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 ) { fprintf( stderr, "fseek(%d) failed on DBF file.\n", nRecordOffset ); return NULL; } if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ) != 1 ) { fprintf( stderr, "fread(%d) failed on DBF file.\n", psDBF->nRecordLength ); return NULL; } psDBF->nCurrentRecord = hEntity; } pabyRec = (unsigned char *) psDBF->pszCurrentRecord;/* -------------------------------------------------------------------- *//* Extract the requested field. *//* -------------------------------------------------------------------- */ strncpy( fieldValue, ((const char *) pabyRec) + psDBF->panFieldOffset[iField], psDBF->panFieldSize[iField] ); fieldValue[psDBF->panFieldSize[iField]] = '\0'; pReturnField = fieldValue;/* -------------------------------------------------------------------- *//* Decode the field. *//* -------------------------------------------------------------------- */ if( chReqType == 'N' || chReqType == 'D' ) { dDoubleField = atof(fieldValue); pReturnField = &dDoubleField; }/* -------------------------------------------------------------------- *//* Should we trim white space off the string attribute value? *//* -------------------------------------------------------------------- */#ifdef TRIM_DBF_WHITESPACE else { char *pchSrc, *pchDst;
pchSrc = fieldValue;
// scan past leading space/tab characters
while( isspace((int)(unsigned char)*pchSrc) )
pchSrc++;
// scan to null-terminating char
pchDst = pchSrc;
while( *pchDst != '\0' )
pchDst++;
// reverse scan past trailing space/tab characters
while( pchDst != pchSrc && isspace((int)(unsigned char)*(--pchDst)) )
*pchDst = '\0';
pReturnField = pchSrc; }#endif return( pReturnField );}/************************************************************************//* DBFReadIntAttribute() *//* *//* Read an integer attribute. *//************************************************************************/int SHPAPI_CALL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -