?? avc_binwr.c
字號:
/* $Id: avc_binwr.c,v 1.17 2006/06/14 16:31:28 daniel Exp $ * * Name: avc_binwr.c * Project: Arc/Info vector coverage (AVC) E00->BIN conversion library * Language: ANSI C * Purpose: Binary files access functions (write mode). * Author: Daniel Morissette, dmorissette@dmsolutions.ca * ********************************************************************** * Copyright (c) 1999-2001, 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_binwr.c,v $ * Revision 1.17 2006/06/14 16:31:28 daniel * Added support for AVCCoverPC2 type (bug 1491) * * Revision 1.16 2005/06/03 03:49:58 daniel * Update email address, website url, and copyright dates * * Revision 1.15 2001/07/06 05:09:33 daniel * Removed #ifdef around fseek to fix NT4 drive problem since ANSI-C requires * an fseek() between read and write operations so this applies to Unix too. * * Revision 1.14 2001/07/06 04:25:00 daniel * Fixed a problem writing arc.dir on NT4 networked drives in an empty dir. * * Revision 1.13 2000/10/16 16:13:29 daniel * Fixed sHeader.nPrecision when writing PC TXT files * * Revision 1.12 2000/09/26 21:40:18 daniel * Fixed writing of PC Coverage TXT... they're different from V7 TXT * * Revision 1.11 2000/09/26 20:21:04 daniel * Added AVCCoverPC write * * Revision 1.10 2000/09/22 19:45:20 daniel * Switch to MIT-style license * * Revision 1.9 2000/05/29 15:31:30 daniel * Added Japanese DBCS support * * Revision 1.8 2000/01/10 02:55:12 daniel * Added call to AVCAdjustCaseSensitiveFilename() when creating tables * * Revision 1.7 1999/12/24 07:18:34 daniel * Added PC Arc/Info coverages support * * Revision 1.6 1999/08/26 17:26:09 daniel * Removed printf() messages used in Windows tests * * Revision 1.5 1999/08/23 18:18:51 daniel * Fixed memory leak and some VC++ warnings * * Revision 1.4 1999/06/08 22:08:14 daniel * Modified CreateTable() to overwrite existing arc.dir entries if necessary * * Revision 1.3 1999/06/08 18:24:32 daniel * Fixed some problems with '/' vs '\\' on Windows * * Revision 1.2 1999/05/17 16:17:36 daniel * Added RXP + TXT/TX6/TX7 write support * * Revision 1.1 1999/05/11 02:34:46 daniel * Initial revision * **********************************************************************/#include "avc.h"#include <ctype.h> /* tolower() *//*===================================================================== * Stuff related to writing the binary coverage files *====================================================================*/static void _AVCBinWriteCloseTable(AVCBinFile *psFile);static AVCBinFile *_AVCBinWriteCreateDBFTable(const char *pszPath, const char *pszCoverName, AVCTableDef *psSrcTableDef, AVCCoverType eCoverType, int nPrecision, AVCDBCSInfo *psDBCSInfo);/********************************************************************** * AVCBinWriteCreate() * * Open a coverage file for writing, write a header if applicable, and * initialize the handle to be ready to write objects to the file. * * pszPath is the coverage (or info directory) path, terminated by * a '/' or a '\\' * pszName is the name of the file to create relative to this directory. * * Note: For most file types except tables, passing pszPath="" and * including the coverage path as part of pszName instead would work. * * Returns a valid AVCBinFile handle, or NULL if the file could * not be created. * * AVCBinClose() will eventually have to be called to release the * resources used by the AVCBinFile structure. **********************************************************************/AVCBinFile *AVCBinWriteCreate(const char *pszPath, const char *pszName, AVCCoverType eCoverType, AVCFileType eType, int nPrecision, AVCDBCSInfo *psDBCSInfo){ AVCBinFile *psFile; char *pszFname = NULL, *pszExt; GBool bCreateIndex = FALSE; int nLen; /*----------------------------------------------------------------- * Make sure precision value is valid (AVC_DEFAULT_PREC is NOT valid) *----------------------------------------------------------------*/ if (nPrecision!=AVC_SINGLE_PREC && nPrecision!=AVC_DOUBLE_PREC) { CPLError(CE_Failure, CPLE_IllegalArg, "AVCBinWriteCreate(): Invalid precision parameter " "(value must be AVC_SINGLE_PREC or AVC_DOUBLE_PREC)"); return NULL; } /*----------------------------------------------------------------- * The case of INFO tables is a bit different... * tables have to be created through a separate function. *----------------------------------------------------------------*/ if (eType == AVCFileTABLE) { CPLError(CE_Failure, CPLE_AssertionFailed, "AVCBinWriteCreate(): TABLEs must be created using " "AVCBinWriteCreateTable()"); return NULL; } /*----------------------------------------------------------------- * Alloc and init the AVCBinFile struct. *----------------------------------------------------------------*/ psFile = (AVCBinFile*)CPLCalloc(1, sizeof(AVCBinFile)); psFile->eFileType = eType; psFile->nPrecision = nPrecision; psFile->pszFilename = (char*)CPLMalloc((strlen(pszPath)+strlen(pszName)+1)* sizeof(char)); sprintf(psFile->pszFilename, "%s%s", pszPath, pszName); psFile->eCoverType = eCoverType; /*----------------------------------------------------------------- * PRJ files are text files... we won't use the AVCRawBin*() * functions for them... the file will be created and closed * inside AVCBinWritePrj(). *----------------------------------------------------------------*/ if (eType == AVCFilePRJ) { return psFile; } /*----------------------------------------------------------------- * All other file types share a very similar creation method. *----------------------------------------------------------------*/ psFile->psRawBinFile = AVCRawBinOpen(psFile->pszFilename, "w", AVC_COVER_BYTE_ORDER(psFile->eCoverType), psDBCSInfo); if (psFile->psRawBinFile == NULL) { /* Failed to open file... just return NULL since an error message * has already been issued by AVCRawBinOpen() */ CPLFree(psFile->pszFilename); CPLFree(psFile); return NULL; } /*----------------------------------------------------------------- * Create an Index file if applicable for current file type. * Yep, we'll have a problem if filenames come in as uppercase, but * this should not happen in a normal situation. * For each type there is 3 possibilities, e.g. "pal", "pal.adf", "ttt.pal" *----------------------------------------------------------------*/ pszFname = CPLStrdup(psFile->pszFilename); nLen = strlen(pszFname); if (eType == AVCFileARC && ( (nLen>=3 && EQUALN((pszExt=pszFname+nLen-3), "arc", 3)) || (nLen>=7 && EQUALN((pszExt=pszFname+nLen-7), "arc.adf", 7)) ) ) { strncpy(pszExt, "arx", 3); bCreateIndex = TRUE; } else if ((eType == AVCFilePAL || eType == AVCFileRPL) && ( (nLen>=3 && EQUALN((pszExt=pszFname+nLen-3), "pal", 3)) || (nLen>=7 && EQUALN((pszExt=pszFname+nLen-7), "pal.adf", 7)) ) ) { strncpy(pszExt, "pax", 3); bCreateIndex = TRUE; } else if (eType == AVCFileCNT && ( (nLen>=3 && EQUALN((pszExt=pszFname+nLen-3), "cnt", 3)) || (nLen>=7 && EQUALN((pszExt=pszFname+nLen-7), "cnt.adf", 7)) ) ) { strncpy(pszExt, "cnx", 3); bCreateIndex = TRUE; } else if ((eType == AVCFileTXT || eType == AVCFileTX6) && ( (nLen>=3 && EQUALN((pszExt=pszFname+nLen-3), "txt", 3)) || (nLen>=7 && EQUALN((pszExt=pszFname+nLen-7), "txt.adf", 7)) ) ) { strncpy(pszExt, "txx", 3); bCreateIndex = TRUE; } if (bCreateIndex) { psFile->psIndexFile = AVCRawBinOpen(pszFname, "w", AVC_COVER_BYTE_ORDER(psFile->eCoverType), psDBCSInfo); } CPLFree(pszFname); /*----------------------------------------------------------------- * Generate the appropriate headers for the main file and its index * if one was created. *----------------------------------------------------------------*/ if (AVCBinWriteHeader(psFile) == -1) { /* Failed! Return NULL */ AVCBinWriteClose(psFile); psFile = NULL; } return psFile;}/********************************************************************** * _AVCBinWriteHeader() * * (This function is for internal library use... external calls should * go to AVCBinWriteHeader() instead) * * Generate a 100 bytes header using the info in psHeader. * * Note: PC Coverage files have an initial 256 bytes header followed by the * regular 100 bytes header. * * This function assumes that the file pointer is currently located at * the beginning of the file. * * Returns 0 on success or -1 on error. **********************************************************************/int _AVCBinWriteHeader(AVCRawBinFile *psFile, AVCBinHeader *psHeader, AVCCoverType eCoverType){ int nStatus = 0; if (eCoverType == AVCCoverPC) { /* PC Coverage header starts with an initial 256 bytes header */ AVCRawBinWriteInt16(psFile, 0x0400); /* Signature??? */ AVCRawBinWriteInt32(psFile, psHeader->nLength); AVCRawBinWriteZeros(psFile, 250); } AVCRawBinWriteInt32(psFile, psHeader->nSignature); AVCRawBinWriteInt32(psFile, psHeader->nPrecision); AVCRawBinWriteInt32(psFile, psHeader->nRecordSize); AVCRawBinWriteZeros(psFile, 12); AVCRawBinWriteInt32(psFile, psHeader->nLength); /* Pad the rest of the header with zeros */ AVCRawBinWriteZeros(psFile, 72); if (CPLGetLastErrorNo() != 0) nStatus = -1; return nStatus;}/********************************************************************** * AVCBinWriteHeader() * * Write a header to the specified file using the values that apply to * this file's type. The function simply does nothing if it is called * for a file type that requires no header. * * Returns 0 on success or -1 on error. **********************************************************************/int AVCBinWriteHeader(AVCBinFile *psFile){ AVCBinHeader sHeader; int nStatus=0; GBool bHeader = TRUE; /*----------------------------------------------------------------- * Set the appropriate header information for this file type. *----------------------------------------------------------------*/ sHeader.nPrecision = sHeader.nRecordSize = sHeader.nLength = 0; sHeader.nSignature = 9994; switch(psFile->eFileType) { case AVCFileARC: sHeader.nPrecision = (psFile->nPrecision == AVC_DOUBLE_PREC)? -1 : 1; break; case AVCFilePAL: case AVCFileRPL: sHeader.nPrecision = (psFile->nPrecision == AVC_DOUBLE_PREC)? -11 : 11; break; case AVCFileLAB: sHeader.nSignature = 9993; sHeader.nPrecision = (psFile->nPrecision == AVC_DOUBLE_PREC)? -2 : 2; sHeader.nRecordSize = (psFile->nPrecision == AVC_DOUBLE_PREC)? 28 : 16; break; case AVCFileCNT: sHeader.nPrecision = (psFile->nPrecision == AVC_DOUBLE_PREC)? -14 : 14; break; case AVCFileTOL: /* single prec: tol.adf has no header * double prec: par.adf has a header */ if (psFile->nPrecision == AVC_DOUBLE_PREC) { sHeader.nSignature = 9993; sHeader.nPrecision = 40; sHeader.nRecordSize = 8; } else { bHeader = FALSE; } break; case AVCFileTXT: case AVCFileTX6: if (psFile->eCoverType == AVCCoverPC) sHeader.nPrecision = 1; else sHeader.nPrecision = (psFile->nPrecision==AVC_DOUBLE_PREC)? -67:67; break;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -