📄 ddfrecord.cpp
字号:
/****************************************************************************** * $Id: ddfrecord.cpp,v 1.1.1.1 2004/12/29 07:54:55 jay-be-em Exp $ * * Project: ISO 8211 Access * Purpose: Implements the DDFRecord class. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * 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: ddfrecord.cpp,v $ * Revision 1.1.1.1 2004/12/29 07:54:55 jay-be-em * Initial import * * Revision 1.24 2004/02/18 14:09:42 warmerda * doc fixups * * Revision 1.23 2003/12/08 20:32:48 warmerda * Added some improved error checking in DDFRecord() on the leader values. * Try reading extra bytes to find field terminator if the last byte in * a record isn't the field terminator. * * Revision 1.22 2003/12/02 16:50:21 warmerda * fixed problems with writing some kinds of records * * Revision 1.21 2003/11/12 21:21:55 warmerda * fixed to include field terminators when creating fields * * Revision 1.20 2003/09/17 21:11:07 warmerda * try to create new default field instance when needed * * Revision 1.19 2003/09/15 20:46:53 warmerda * supressed some warnings in SetFieldRaw if field empty * * Revision 1.18 2003/09/11 19:56:35 warmerda * avoid warnings * * Revision 1.17 2003/09/03 20:36:26 warmerda * added subfield writing support * * Revision 1.16 2003/07/03 15:38:46 warmerda * some write capabilities added * * Revision 1.15 2002/08/08 12:39:18 warmerda * Added support for variable length records as per bugzilla bug 181. * * Revision 1.14 2001/08/30 21:08:19 warmerda * expand tabs * * Revision 1.13 2001/08/27 19:09:00 warmerda * added GetInstanceData() method on DDFField * * Revision 1.12 2001/08/24 19:41:19 warmerda * fixed cloning problems * * Revision 1.11 2001/08/24 16:30:55 warmerda * added DDFRecord update in place methods for S57 updating * * Revision 1.10 2001/07/18 04:51:57 warmerda * added CPL_CVSID * * Revision 1.9 2000/02/15 17:55:53 warmerda * Improved error message for corrupt DDF files. * * Revision 1.8 1999/11/18 19:03:04 warmerda * expanded tabs * * Revision 1.7 1999/09/03 14:14:39 warmerda * fix cloning * * Revision 1.6 1999/09/02 03:10:01 warmerda * fixed subtle problem with rewinding modules with reusable headers * * Revision 1.5 1999/05/08 20:16:20 warmerda * added some record validity testing * * Revision 1.4 1999/05/07 14:12:24 warmerda * added record cloning, and subfield value fetches * * Revision 1.3 1999/05/06 14:48:28 warmerda * Fixed EOF handling in files with reused headers * * Revision 1.2 1999/05/06 14:24:29 warmerda * minor optimization, don't emit an error on EOF * * Revision 1.1 1999/04/27 18:45:05 warmerda * New * */#include "iso8211.h"#include "cpl_conv.h"CPL_CVSID("$Id: ddfrecord.cpp,v 1.1.1.1 2004/12/29 07:54:55 jay-be-em Exp $");static const size_t nLeaderSize = 24;/************************************************************************//* DDFRecord() *//************************************************************************/DDFRecord::DDFRecord( DDFModule * poModuleIn ){ poModule = poModuleIn; nReuseHeader = FALSE; nFieldOffset = 0; nDataSize = 0; pachData = NULL; nFieldCount = 0; paoFields = NULL; bIsClone = FALSE; _sizeFieldTag = 4; _sizeFieldPos = 0; _sizeFieldLength = 0;}/************************************************************************//* ~DDFRecord() *//************************************************************************/DDFRecord::~DDFRecord(){ Clear(); if( bIsClone ) poModule->RemoveCloneRecord( this );}/************************************************************************//* Dump() *//************************************************************************//** * Write out record contents to debugging file. * * A variety of information about this record, and all it's fields and * subfields is written to the given debugging file handle. Note that * field definition information (ala DDFFieldDefn) isn't written. * * @param fp The standard io file handle to write to. ie. stderr */void DDFRecord::Dump( FILE * fp ){ fprintf( fp, "DDFRecord:\n" ); fprintf( fp, " nReuseHeader = %d\n", nReuseHeader ); fprintf( fp, " nDataSize = %d\n", nDataSize ); fprintf( fp, " _sizeFieldLength=%d, _sizeFieldPos=%d, _sizeFieldTag=%d\n", _sizeFieldLength, _sizeFieldPos, _sizeFieldTag ); for( int i = 0; i < nFieldCount; i++ ) { paoFields[i].Dump( fp ); }}/************************************************************************//* Read() *//* *//* Read a record of data from the file, and parse the header to *//* build a field list for the record (or reuse the existing one *//* if reusing headers). It is expected that the file pointer *//* will be positioned at the beginning of a data record. It is *//* the DDFModule's responsibility to do so. *//* *//* This method should only be called by the DDFModule class. *//************************************************************************/int DDFRecord::Read(){/* -------------------------------------------------------------------- *//* Redefine the record on the basis of the header if needed. *//* As a side effect this will read the data for the record as well.*//* -------------------------------------------------------------------- */ if( !nReuseHeader ) { return( ReadHeader() ); }/* -------------------------------------------------------------------- *//* Otherwise we read just the data and carefully overlay it on *//* the previous records data without disturbing the rest of the *//* record. *//* -------------------------------------------------------------------- */ size_t nReadBytes; nReadBytes = VSIFRead( pachData + nFieldOffset, 1, nDataSize - nFieldOffset, poModule->GetFP() ); if( nReadBytes != (size_t) (nDataSize - nFieldOffset) && nReadBytes == 0 && VSIFEof( poModule->GetFP() ) ) { return FALSE; } else if( nReadBytes != (size_t) (nDataSize - nFieldOffset) ) { CPLError( CE_Failure, CPLE_FileIO, "Data record is short on DDF file.\n" ); return FALSE; } // notdef: eventually we may have to do something at this point to // notify the DDFField's that their data values have changed. return TRUE;}/************************************************************************//* Write() *//************************************************************************//** * Write record out to module. * * This method writes the current record to the module to which it is * attached. Normally this would be at the end of the file, and only used * for modules newly created with DDFModule::Create(). Rewriting existing * records is not supported at this time. Calling Write() multiple times * on a DDFRecord will result it multiple copies being written at the end of * the module. * * @return TRUE on success or FALSE on failure. */int DDFRecord::Write(){ if( !ResetDirectory() ) return FALSE; /* -------------------------------------------------------------------- *//* Prepare leader. *//* -------------------------------------------------------------------- */ char szLeader[nLeaderSize+1]; memset( szLeader, ' ', nLeaderSize ); sprintf( szLeader+0, "%05d", nDataSize + nLeaderSize ); szLeader[5] = ' '; szLeader[6] = 'D'; sprintf( szLeader + 12, "%05d", nFieldOffset + nLeaderSize ); szLeader[17] = ' '; szLeader[20] = (char) ('0' + _sizeFieldLength); szLeader[21] = (char) ('0' + _sizeFieldPos); szLeader[22] = '0'; szLeader[23] = (char) ('0' + _sizeFieldTag); /* notdef: lots of stuff missing *//* -------------------------------------------------------------------- *//* Write the leader. *//* -------------------------------------------------------------------- */ VSIFWrite( szLeader, nLeaderSize, 1, poModule->GetFP() );/* -------------------------------------------------------------------- *//* Write the remainder of the record. *//* -------------------------------------------------------------------- */ VSIFWrite( pachData, nDataSize, 1, poModule->GetFP() ); return TRUE;}/************************************************************************//* Clear() *//* *//* Clear any information associated with the last header in *//* preparation for reading a new header. *//************************************************************************/void DDFRecord::Clear(){ if( paoFields != NULL ) delete[] paoFields; paoFields = NULL; nFieldCount = 0; if( pachData != NULL ) CPLFree( pachData ); pachData = NULL; nDataSize = 0; nReuseHeader = FALSE;}/************************************************************************//* ReadHeader() *//* *//* This perform the header reading and parsing job for the *//* Read() method. It reads the header, and builds a field *//* list. *//************************************************************************/int DDFRecord::ReadHeader(){/* -------------------------------------------------------------------- *//* Clear any existing information. *//* -------------------------------------------------------------------- */ Clear();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -