📄 dbfopen.cpp
字号:
free( psDBF );
return NULL;
}
psDBF->nRecords =
pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256;
psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256;
psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256;
psDBF->nFields = nFields = (nHeadLen - 32) / 32;
psDBF->pszCurrentRecord = (char *) malloc(nRecLen);
/* -------------------------------------------------------------------- */
/* Read in Field Definitions */
/* -------------------------------------------------------------------- */
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] + 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_CALL
DBFClose(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];
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 SHPAPI_CALL
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 SHPAPI_CALL
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 );
if( nWidth < 1 )
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
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;
/* -------------------------------------------------------------------- */
/* 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;
/* -------------------------------------------------------------------- */
/* 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,
((const char *) pabyRec) + psDBF->panFieldOffset[iField],
psDBF->panFieldSize[iField] );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -