⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbfopen.c

📁 用于读取TAB、MIF、SHP文件的类
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * $Id: dbfopen.c,v 1.70 2006/06/17 17:47:05 fwarmerdam Exp $ * * Project:  Shapelib * Purpose:  Implementation of .dbf access API documented in dbf_api.html. * Author:   Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL).  This * option is discussed in more detail in shapelib.html. * * -- *  * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: dbfopen.c,v $ * Revision 1.70  2006/06/17 17:47:05  fwarmerdam * use calloc() for dbfinfo in DBFCreate * * Revision 1.69  2006/06/17 15:34:32  fwarmerdam * disallow creating fields wider than 255 * * Revision 1.68  2006/06/17 15:12:40  fwarmerdam * Fixed C++ style comments. * * Revision 1.67  2006/06/17 00:24:53  fwarmerdam * Don't treat non-zero decimals values as high order byte for length * for strings.  It causes serious corruption for some files. * http://bugzilla.remotesensing.org/show_bug.cgi?id=1202 * * Revision 1.66  2006/03/29 18:26:20  fwarmerdam * fixed bug with size of pachfieldtype in dbfcloneempty * * Revision 1.65  2006/02/15 01:14:30  fwarmerdam * added DBFAddNativeFieldType * * Revision 1.64  2006/02/09 00:29:04  fwarmerdam * Changed to put spaces into string fields that are NULL as * per http://bugzilla.maptools.org/show_bug.cgi?id=316. * * Revision 1.63  2006/01/25 15:35:43  fwarmerdam * check success on DBFFlushRecord * * Revision 1.62  2006/01/10 16:28:03  fwarmerdam * Fixed typo in CPLError. * * Revision 1.61  2006/01/10 16:26:29  fwarmerdam * Push loading record buffer into DBFLoadRecord. * Implement CPL error reporting if USE_CPL defined. * * Revision 1.60  2006/01/05 01:27:27  fwarmerdam * added dbf deletion mark/fetch * * Revision 1.59  2005/03/14 15:20:28  fwarmerdam * Fixed last change. * * Revision 1.58  2005/03/14 15:18:54  fwarmerdam * Treat very wide fields with no decimals as double.  This is * more than 32bit integer fields. * * Revision 1.57  2005/02/10 20:16:54  fwarmerdam * Make the pszStringField buffer for DBFReadAttribute() static char [256] * as per bug 306. * * Revision 1.56  2005/02/10 20:07:56  fwarmerdam * Fixed bug 305 in DBFCloneEmpty() - header length problem. * * Revision 1.55  2004/09/26 20:23:46  fwarmerdam * avoid warnings with rcsid and signed/unsigned stuff * * Revision 1.54  2004/09/15 16:26:10  fwarmerdam * Treat all blank numeric fields as null too. */#include "shapefil.h"#include <math.h>#include <stdlib.h>#include <ctype.h>#include <string.h>SHP_CVSID("$Id: dbfopen.c,v 1.70 2006/06/17 17:47:05 fwarmerdam Exp $")#ifndef FALSE#  define FALSE		0#  define TRUE		1#endif/************************************************************************//*                             SfRealloc()                              *//*                                                                      *//*      A realloc cover function that will access a NULL pointer as     *//*      a valid input.                                                  *//************************************************************************/static void * SfRealloc( void * pMem, int nNewSize ){    if( pMem == NULL )        return( (void *) malloc(nNewSize) );    else        return( (void *) realloc(pMem,nNewSize) );}/************************************************************************//*                           DBFWriteHeader()                           *//*                                                                      *//*      This is called to write out the file header, and field          *//*      descriptions before writing any actual data records.  This      *//*      also computes all the DBFDataSet field offset/size/decimals     *//*      and so forth values.                                            *//************************************************************************/static void DBFWriteHeader(DBFHandle psDBF){    unsigned char	abyHeader[XBASE_FLDHDR_SZ];    int		i;    if( !psDBF->bNoHeader )        return;    psDBF->bNoHeader = FALSE;/* -------------------------------------------------------------------- *//*	Initialize the file header information.				*//* -------------------------------------------------------------------- */    for( i = 0; i < XBASE_FLDHDR_SZ; i++ )        abyHeader[i] = 0;    abyHeader[0] = 0x03;		/* memo field? - just copying 	*/    /* write out a dummy date */    abyHeader[1] = 95;			/* YY */    abyHeader[2] = 7;			/* MM */    abyHeader[3] = 26;			/* DD */    /* record count preset at zero */    abyHeader[8] = (unsigned char) (psDBF->nHeaderLength % 256);    abyHeader[9] = (unsigned char) (psDBF->nHeaderLength / 256);        abyHeader[10] = (unsigned char) (psDBF->nRecordLength % 256);    abyHeader[11] = (unsigned char) (psDBF->nRecordLength / 256);/* -------------------------------------------------------------------- *//*      Write the initial 32 byte file header, and all the field        *//*      descriptions.                                     		*//* -------------------------------------------------------------------- */    fseek( psDBF->fp, 0, 0 );    fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp );    fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp );/* -------------------------------------------------------------------- *//*      Write out the newline character if there is room for it.        *//* -------------------------------------------------------------------- */    if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 )    {        char	cNewline;        cNewline = 0x0d;        fwrite( &cNewline, 1, 1, psDBF->fp );    }}/************************************************************************//*                           DBFFlushRecord()                           *//*                                                                      *//*      Write out the current record if there is one.                   *//************************************************************************/static int DBFFlushRecord( DBFHandle psDBF ){    int		nRecordOffset;    if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 )    {	psDBF->bCurrentRecordModified = FALSE;	nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord 	                                             + psDBF->nHeaderLength;	if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0             || fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength,                        1, psDBF->fp ) != 1 )        {#ifdef USE_CPL            CPLError( CE_Failure, CPLE_FileIO,                       "Failure writing DBF record %d.",                       psDBF->nCurrentRecord );#else                       fprintf( stderr, "Failure writing DBF record %d.",                      psDBF->nCurrentRecord );#endif            return FALSE;        }    }    return TRUE;}/************************************************************************//*                           DBFLoadRecord()                            *//************************************************************************/static int DBFLoadRecord( DBFHandle psDBF, int iRecord ){    if( psDBF->nCurrentRecord != iRecord )    {        int nRecordOffset;	if( !DBFFlushRecord( psDBF ) )            return FALSE;	nRecordOffset = psDBF->nRecordLength * iRecord + psDBF->nHeaderLength;	if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 )        {#ifdef USE_CPL            CPLError( CE_Failure, CPLE_FileIO,                      "fseek(%d) failed on DBF file.\n",                      nRecordOffset );#else            fprintf( stderr, "fseek(%d) failed on DBF file.\n",                     nRecordOffset );#endif            return FALSE;        }	if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength,                    1, psDBF->fp ) != 1 )        {#ifdef USE_CPL            CPLError( CE_Failure, CPLE_FileIO,                       "fread(%d) failed on DBF file.\n",                      psDBF->nRecordLength );#else            fprintf( stderr, "fread(%d) failed on DBF file.\n",                     psDBF->nRecordLength );#endif            return FALSE;        }	psDBF->nCurrentRecord = iRecord;    }    return TRUE;}/************************************************************************//*                          DBFUpdateHeader()                           *//************************************************************************/void SHPAPI_CALLDBFUpdateHeader( DBFHandle psDBF ){    unsigned char		abyFileHeader[32];    if( psDBF->bNoHeader )        DBFWriteHeader( psDBF );    DBFFlushRecord( psDBF );    fseek( psDBF->fp, 0, 0 );    fread( abyFileHeader, 32, 1, psDBF->fp );        abyFileHeader[4] = (unsigned char) (psDBF->nRecords % 256);    abyFileHeader[5] = (unsigned char) ((psDBF->nRecords/256) % 256);    abyFileHeader[6] = (unsigned char) ((psDBF->nRecords/(256*256)) % 256);    abyFileHeader[7] = (unsigned char) ((psDBF->nRecords/(256*256*256)) % 256);        fseek( psDBF->fp, 0, 0 );    fwrite( abyFileHeader, 32, 1, psDBF->fp );    fflush( psDBF->fp );}/************************************************************************//*                              DBFOpen()                               *//*                                                                      *//*      Open a .dbf file.                                               *//************************************************************************/   DBFHandle SHPAPI_CALLDBFOpen( const char * pszFilename, const char * pszAccess ){    DBFHandle		psDBF;    unsigned char		*pabyBuf;    int			nFields, nHeadLen, iField, i;    char		*pszBasename, *pszFullname;/* -------------------------------------------------------------------- *//*      We only allow the access strings "rb" and "r+".                  *//* -------------------------------------------------------------------- */    if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0         && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0        && strcmp(pszAccess,"r+b") != 0 )        return( NULL );    if( strcmp(pszAccess,"r") == 0 )        pszAccess = "rb";     if( strcmp(pszAccess,"r+") == 0 )        pszAccess = "rb+";/* -------------------------------------------------------------------- *//*	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 );            psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) );    psDBF->fp = fopen( pszFullname, pszAccess );    if( psDBF->fp == NULL )    {        sprintf( pszFullname, "%s.DBF", pszBasename );        psDBF->fp = fopen(pszFullname, pszAccess );    }        free( pszBasename );    free( pszFullname );        if( psDBF->fp == NULL )    {        free( psDBF );        return( NULL );    }    psDBF->bNoHeader = FALSE;    psDBF->nCurrentRecord = -1;    psDBF->bCurrentRecordModified = FALSE;/* -------------------------------------------------------------------- *//*  Read Table Header info                                              *//* -------------------------------------------------------------------- */    pabyBuf = (unsigned char *) malloc(500);    if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 )    {        fclose( psDBF->fp );        free( pabyBuf );        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 = pabyBuf[10] + pabyBuf[11]*256;        psDBF->nFields = nFields = (nHeadLen - 32) / 32;    psDBF->pszCurrentRecord = (char *) malloc(psDBF->nRecordLength);/* -------------------------------------------------------------------- *//*  Read in Field Definitions                                           */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -