?? avc_rawbin.c
字號:
/********************************************************************** * $Id: avc_rawbin.c,v 1.13 2005/06/03 03:49:59 daniel Exp $ * * Name: avc_rawbin.c * Project: Arc/Info vector coverage (AVC) BIN->E00 conversion library * Language: ANSI C * Purpose: Raw Binary file access functions. * Author: Daniel Morissette, dmorissette@dmsolutions.ca * ********************************************************************** * Copyright (c) 1999-2005, Daniel Morissette * * 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: avc_rawbin.c,v $ * Revision 1.13 2005/06/03 03:49:59 daniel * Update email address, website url, and copyright dates * * Revision 1.12 2004/08/19 23:41:04 warmerda * fixed pointer aliasing optimization bug * * Revision 1.11 2000/09/22 19:45:21 daniel * Switch to MIT-style license * * Revision 1.10 2000/05/29 15:36:07 daniel * Fixed compile warning * * Revision 1.9 2000/05/29 15:31:31 daniel * Added Japanese DBCS support * * Revision 1.8 2000/01/10 02:59:11 daniel * Fixed problem in AVCRawBinOpen() when file not found * * Revision 1.7 1999/12/24 07:18:34 daniel * Added PC Arc/Info coverages support * * Revision 1.6 1999/08/29 15:05:43 daniel * Added source filename in "Attempt to read past EOF" error message * * Revision 1.5 1999/06/08 22:09:03 daniel * Allow opening file with "r+" (but no real random access support yet) * * Revision 1.4 1999/05/11 02:10:51 daniel * Added write support * * Revision 1.3 1999/03/03 19:55:21 daniel * Fixed syntax error in the CPL_MSB version of AVCRawBinReadInt32() * * Revision 1.2 1999/02/25 04:20:08 daniel * Modified AVCRawBinEOF() to detect EOF even if AVCRawBinFSeek() was used. * * Revision 1.1 1999/01/29 16:28:52 daniel * Initial revision * **********************************************************************/#include "avc.h"#include "avc_mbyte.h"/*--------------------------------------------------------------------- * Define a static flag and set it with the byte ordering on this machine * we will then compare with this value to decide if we nned to swap * bytes or not. * * CPL_MSB or CPL_LSB should be set in the makefile... the default is * CPL_LSB. *--------------------------------------------------------------------*/#ifndef CPL_LSBstatic AVCByteOrder geSystemByteOrder = AVCBigEndian;#elsestatic AVCByteOrder geSystemByteOrder = AVCLittleEndian;#endif/*===================================================================== * Stuff related to buffered reading of raw binary files *====================================================================*//********************************************************************** * AVCRawBinOpen() * * Open a binary file for reading with buffering, or writing. * * Returns a valid AVCRawBinFile structure, or NULL if the file could * not be opened or created. * * AVCRawBinClose() will eventually have to be called to release the * resources used by the AVCRawBinFile structure. **********************************************************************/AVCRawBinFile *AVCRawBinOpen(const char *pszFname, const char *pszAccess, AVCByteOrder eFileByteOrder, AVCDBCSInfo *psDBCSInfo){ AVCRawBinFile *psFile; psFile = (AVCRawBinFile*)CPLCalloc(1, sizeof(AVCRawBinFile)); /*----------------------------------------------------------------- * Validate access mode and open/create file. * For now we support only: "r" for read-only or "w" for write-only * or "a" for append. * * A case for "r+" is included here, but random access is not * properly supported yet... so this option should be used with care. *----------------------------------------------------------------*/ if (EQUALN(pszAccess, "r+", 2)) { psFile->eAccess = AVCReadWrite; psFile->fp = VSIFOpen(pszFname, "r+b"); } else if (EQUALN(pszAccess, "r", 1)) { psFile->eAccess = AVCRead; psFile->fp = VSIFOpen(pszFname, "rb"); } else if (EQUALN(pszAccess, "w", 1)) { psFile->eAccess = AVCWrite; psFile->fp = VSIFOpen(pszFname, "wb"); } else if (EQUALN(pszAccess, "a", 1)) { psFile->eAccess = AVCWrite; psFile->fp = VSIFOpen(pszFname, "ab"); } else { CPLError(CE_Failure, CPLE_IllegalArg, "Acces mode \"%s\" not supported.", pszAccess); CPLFree(psFile); return NULL; } /*----------------------------------------------------------------- * Check that file was opened succesfully, and init struct. *----------------------------------------------------------------*/ if (psFile->fp == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "Failed to open file %s", pszFname); CPLFree(psFile); return NULL; } /*----------------------------------------------------------------- * OK... Init psFile struct *----------------------------------------------------------------*/ psFile->pszFname = CPLStrdup(pszFname); psFile->eByteOrder = eFileByteOrder; psFile->psDBCSInfo = psDBCSInfo; /* Handle on dataset DBCS info */ /*----------------------------------------------------------------- * One can set nFileDataSize based on some header fields to force * EOF beyond a given point in the file. Useful for cases like * PC Arc/Info where the physical file size is always a multiple of * 256 bytes padded with some junk at the end. *----------------------------------------------------------------*/ psFile->nFileDataSize = -1; return psFile;}/********************************************************************** * AVCRawBinClose() * * Close a binary file previously opened with AVCRawBinOpen() and release * any memory used by the handle. **********************************************************************/void AVCRawBinClose(AVCRawBinFile *psFile){ if (psFile) { if (psFile->fp) VSIFClose(psFile->fp); CPLFree(psFile->pszFname); CPLFree(psFile); }}/********************************************************************** * AVCRawBinSetFileDataSize() * * One can set nFileDataSize based on some header fields to force * EOF beyond a given point in the file. Useful for cases like * PC Arc/Info where the physical file size is always a multiple of * 256 bytes padded with some junk at the end. * * The default value is -1 which just looks for the real EOF. **********************************************************************/void AVCRawBinSetFileDataSize(AVCRawBinFile *psFile, int nFileDataSize){ if (psFile) { psFile->nFileDataSize = nFileDataSize; }}/********************************************************************** * AVCRawBinReadBytes() * * Copy the number of bytes from the input file to the specified * memory location. **********************************************************************/static GBool bDisableReadBytesEOFError = FALSE;void AVCRawBinReadBytes(AVCRawBinFile *psFile, int nBytesToRead, GByte *pBuf){ /* Make sure file is opened with Read access */ if (psFile == NULL || (psFile->eAccess != AVCRead && psFile->eAccess != AVCReadWrite)) { CPLError(CE_Failure, CPLE_FileIO, "AVCRawBinReadBytes(): call not compatible with access mode."); return; } /* Quick method: check to see if we can satisfy the request with a * simple memcpy... most calls should take this path. */ if (psFile->nCurPos + nBytesToRead <= psFile->nCurSize) { memcpy(pBuf, psFile->abyBuf+psFile->nCurPos, nBytesToRead); psFile->nCurPos += nBytesToRead; return; } /* This is the long method... it supports reading data that * overlaps the input buffer boundaries. */ while(nBytesToRead > 0) { /* If we reached the end of our memory buffer then read another * chunk from the file */ CPLAssert(psFile->nCurPos <= psFile->nCurSize); if (psFile->nCurPos == psFile->nCurSize) { psFile->nOffset += psFile->nCurSize; psFile->nCurSize = VSIFRead(psFile->abyBuf, sizeof(GByte), AVCRAWBIN_READBUFSIZE, psFile->fp); psFile->nCurPos = 0; } if (psFile->nCurSize == 0) { /* Attempt to read past EOF... generate an error. * * Note: AVCRawBinEOF() can set bDisableReadBytesEOFError=TRUE * to disable the error message whils it is testing * for EOF. */ if (bDisableReadBytesEOFError == FALSE) CPLError(CE_Failure, CPLE_FileIO, "Attempt to read past EOF in %s.", psFile->pszFname); return; } /* If the requested bytes are not all in the current buffer then * just read the part that's in memory for now... the loop will * take care of the rest. */ if (psFile->nCurPos + nBytesToRead > psFile->nCurSize) { int nBytes; nBytes = psFile->nCurSize-psFile->nCurPos; memcpy(pBuf, psFile->abyBuf+psFile->nCurPos, nBytes); psFile->nCurPos += nBytes; pBuf += nBytes; nBytesToRead -= nBytes; } else { /* All the requested bytes are now in the buffer... * simply copy them and return. */ memcpy(pBuf, psFile->abyBuf+psFile->nCurPos, nBytesToRead); psFile->nCurPos += nBytesToRead; nBytesToRead = 0; /* Terminate the loop */ } }}/********************************************************************** * AVCRawBinReadString() * * Same as AVCRawBinReadBytes() except that the string is run through * the DBCS conversion function. * * pBuf should be allocated with a size of at least nBytesToRead+1 bytes. **********************************************************************/void AVCRawBinReadString(AVCRawBinFile *psFile, int nBytesToRead, GByte *pBuf){ const GByte *pszConvBuf; AVCRawBinReadBytes(psFile, nBytesToRead, pBuf); pBuf[nBytesToRead] = '\0'; pszConvBuf = AVCE00ConvertFromArcDBCS(psFile->psDBCSInfo, pBuf, nBytesToRead); if (pszConvBuf != pBuf) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -