📄 ntfrecord.cpp
字号:
/****************************************************************************** * $Id: ntfrecord.cpp,v 1.9 2003/01/07 16:46:47 warmerda Exp $ * * Project: NTF Translator * Purpose: NTFRecord class implementation. * 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: ntfrecord.cpp,v $ * Revision 1.9 2003/01/07 16:46:47 warmerda * improve long line check * * Revision 1.8 2002/02/18 21:40:03 warmerda * Fixed error message. * * Revision 1.7 2002/02/11 17:04:45 warmerda * cleanup tabs * * Revision 1.6 2002/02/11 17:04:03 warmerda * tolerate somewhat longer lines, irish data has long lines * * Revision 1.5 2002/02/11 16:54:47 warmerda * Use internal code to read records, ensuring that "zero" bytes or other * binary garbage are survivable. Added implicit assumption that records * are no more than 80 data bytes. * * Revision 1.4 2002/02/08 20:43:06 warmerda * improved error checking and propagation * * Revision 1.3 2001/12/12 02:48:43 warmerda * ensure cplreadline buffer freed * * Revision 1.2 2001/07/18 04:55:16 warmerda * added CPL_CSVID * * Revision 1.1 1999/08/28 03:13:35 warmerda * New * */#include "ntf.h"#include "cpl_conv.h"CPL_CVSID("$Id: ntfrecord.cpp,v 1.9 2003/01/07 16:46:47 warmerda Exp $");static int nFieldBufSize = 0;static char *pszFieldBuf = NULL;#define MAX_RECORD_LEN 160/************************************************************************//* NTFRecord() *//* *//* The constructor is where the record is read. This includes *//* transparent merging of continuation lines. *//************************************************************************/NTFRecord::NTFRecord( FILE * fp ){ nType = 99; nLength = 0; pszData = NULL; if( fp == NULL ) return;/* ==================================================================== *//* Read lines untill we get to one without a continuation mark. *//* ==================================================================== */ char szLine[MAX_RECORD_LEN+3]; int nNewLength; do { nNewLength = ReadPhysicalLine( fp, szLine ); if( nNewLength == -1 || nNewLength == -2 ) break; while( nNewLength > 0 && szLine[nNewLength-1] == ' ' ) szLine[--nNewLength] = '\0'; if( szLine[nNewLength-1] != '%' ) { CPLError( CE_Failure, CPLE_AppDefined, "Corrupt NTF record, missing end '%%'." ); CPLFree( pszData ); pszData = NULL; break; } if( pszData == NULL ) { nLength = nNewLength - 2; pszData = (char *) CPLMalloc(nLength+1); memcpy( pszData, szLine, nLength ); pszData[nLength] = '\0'; } else { pszData = (char *) CPLRealloc(pszData,nLength+(nNewLength-4)+1); CPLAssert( EQUALN(szLine,"00",2) ); memcpy( pszData+nLength, szLine+2, nNewLength-4 ); nLength += nNewLength-4; pszData[nLength] = '\0'; } } while( szLine[nNewLength-2] == '1' );/* -------------------------------------------------------------------- *//* Figure out the record type. *//* -------------------------------------------------------------------- */ if( pszData != NULL ) { char szType[3]; strncpy( szType, pszData, 2 ); szType[2] = '\0'; nType = atoi(szType); }}/************************************************************************//* ~NTFRecord() *//************************************************************************/NTFRecord::~NTFRecord(){ CPLFree( pszData ); if( pszFieldBuf != NULL ) { CPLFree( pszFieldBuf ); pszFieldBuf = NULL; nFieldBufSize = 0; }}/************************************************************************//* ReadPhysicalLine() *//************************************************************************/int NTFRecord::ReadPhysicalLine( FILE *fp, char *pszLine ){ int nBytesRead = 0; int nRecordStart, nRecordEnd, i, nLength = 0;/* -------------------------------------------------------------------- *//* Read enough data that we are sure we have a whole record. *//* -------------------------------------------------------------------- */ nRecordStart = VSIFTell( fp ); nBytesRead = VSIFRead( pszLine, 1, MAX_RECORD_LEN+2, fp ); if( nBytesRead == 0 ) { if( VSIFEof( fp ) ) return -1; else { CPLError( CE_Failure, CPLE_AppDefined, "Low level read error occured while reading NTF file." ); return -2; } } /* -------------------------------------------------------------------- *//* Search for CR or LF. *//* -------------------------------------------------------------------- */ for( i = 0; i < nBytesRead; i++ ) { if( pszLine[i] == 10 || pszLine[i] == 13 ) break; }/* -------------------------------------------------------------------- *//* If we don't find EOL within 80 characters something has gone *//* badly wrong! *//* -------------------------------------------------------------------- */ if( i == MAX_RECORD_LEN+2 ) { CPLError( CE_Failure, CPLE_AppDefined, "%d byte record too long for NTF format.\n" "No line may be longer than 80 characters though up to %d tolerated.\n", nBytesRead, MAX_RECORD_LEN ); return -2; }/* -------------------------------------------------------------------- *//* Trim CR/LF. *//* -------------------------------------------------------------------- */ nLength = i; if( pszLine[i+1] == 10 || pszLine[i+1] == 13 ) nRecordEnd = nRecordStart + i + 2; else nRecordEnd = nRecordStart + i + 1; pszLine[nLength] = '\0';/* -------------------------------------------------------------------- *//* Restore read pointer to beginning of next record. *//* -------------------------------------------------------------------- */ VSIFSeek( fp, nRecordEnd, SEEK_SET ); return nLength;}/************************************************************************//* GetField() *//* *//* Note that the start position is 1 based, to match the *//* notation in the NTF document. The returned pointer is to an *//* internal buffer, but is zero terminated. *//************************************************************************/const char * NTFRecord::GetField( int nStart, int nEnd ){ int nSize = nEnd - nStart + 1;/* -------------------------------------------------------------------- *//* Reallocate working buffer larger if needed. *//* -------------------------------------------------------------------- */ if( nFieldBufSize < nSize + 1 ) { CPLFree( pszFieldBuf ); nFieldBufSize = nSize + 1; pszFieldBuf = (char *) CPLMalloc(nFieldBufSize); }/* -------------------------------------------------------------------- *//* Copy out desired data. *//* -------------------------------------------------------------------- */ if( nStart + nSize > nLength+1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to read %d to %d, beyond the end of %d byte long\n" "type `%2.2s' record.\n", nStart, nEnd, nLength, pszData ); memset( pszFieldBuf, ' ', nSize ); pszFieldBuf[nSize] = '\0'; } else { strncpy( pszFieldBuf, pszData + nStart - 1, nSize ); pszFieldBuf[nSize] = '\0'; } return pszFieldBuf;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -