ISO8211Lib
|
00001 /****************************************************************************** 00002 * $Id: iso8211.h 20996 2010-10-28 18:38:15Z rouault $ 00003 * 00004 * Project: ISO 8211 Access 00005 * Purpose: Main declarations for ISO 8211. 00006 * Author: Frank Warmerdam, warmerdam@pobox.com 00007 * 00008 ****************************************************************************** 00009 * Copyright (c) 1999, Frank Warmerdam <warmerdam@pobox.com> 00010 * 00011 * Permission is hereby granted, free of charge, to any person obtaining a 00012 * copy of this software and associated documentation files (the "Software"), 00013 * to deal in the Software without restriction, including without limitation 00014 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00015 * and/or sell copies of the Software, and to permit persons to whom the 00016 * Software is furnished to do so, subject to the following conditions: 00017 * 00018 * The above copyright notice and this permission notice shall be included 00019 * in all copies or substantial portions of the Software. 00020 * 00021 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00022 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00023 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00024 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00025 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00026 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00027 * DEALINGS IN THE SOFTWARE. 00028 ****************************************************************************/ 00029 00030 #ifndef _ISO8211_H_INCLUDED 00031 #define _ISO8211_H_INCLUDED 00032 00033 #include "cpl_port.h" 00034 #include "cpl_vsi.h" 00035 00039 typedef enum { 00040 DDFInt, 00041 DDFFloat, 00042 DDFString, 00043 DDFBinaryString 00044 } DDFDataType; 00045 00046 /************************************************************************/ 00047 /* These should really be private to the library ... they are */ 00048 /* mostly conveniences. */ 00049 /************************************************************************/ 00050 00051 long CPL_ODLL DDFScanInt( const char *pszString, int nMaxChars ); 00052 int CPL_ODLL DDFScanVariable( const char * pszString, int nMaxChars, int nDelimChar ); 00053 char CPL_ODLL *DDFFetchVariable( const char *pszString, int nMaxChars, 00054 int nDelimChar1, int nDelimChar2, 00055 int *pnConsumedChars ); 00056 00057 #define DDF_FIELD_TERMINATOR 30 00058 #define DDF_UNIT_TERMINATOR 31 00059 00060 /************************************************************************/ 00061 /* Predeclarations */ 00062 /************************************************************************/ 00063 00064 class DDFFieldDefn; 00065 class DDFSubfieldDefn; 00066 class DDFRecord; 00067 class DDFField; 00068 00069 /************************************************************************/ 00070 /* DDFModule */ 00071 /************************************************************************/ 00072 00080 class CPL_ODLL DDFModule 00081 { 00082 public: 00083 DDFModule(); 00084 ~DDFModule(); 00085 00086 int Open( const char * pszFilename, int bFailQuietly = FALSE ); 00087 int Create( const char *pszFilename ); 00088 void Close(); 00089 00090 int Initialize( char chInterchangeLevel = '3', 00091 char chLeaderIden = 'L', 00092 char chCodeExtensionIndicator = 'E', 00093 char chVersionNumber = '1', 00094 char chAppIndicator = ' ', 00095 const char *pszExtendedCharSet = " ! ", 00096 int nSizeFieldLength = 3, 00097 int nSizeFieldPos = 4, 00098 int nSizeFieldTag = 4 ); 00099 00100 void Dump( FILE * fp ); 00101 00102 DDFRecord *ReadRecord( void ); 00103 void Rewind( long nOffset = -1 ); 00104 00105 DDFFieldDefn *FindFieldDefn( const char * ); 00106 00109 int GetFieldCount() { return nFieldDefnCount; } 00110 DDFFieldDefn *GetField(int); 00111 void AddField( DDFFieldDefn *poNewFDefn ); 00112 00113 // This is really just for internal use. 00114 int GetFieldControlLength() { return _fieldControlLength; } 00115 void AddCloneRecord( DDFRecord * ); 00116 void RemoveCloneRecord( DDFRecord * ); 00117 00118 // This is just for DDFRecord. 00119 VSILFILE *GetFP() { return fpDDF; } 00120 00121 private: 00122 VSILFILE *fpDDF; 00123 int bReadOnly; 00124 long nFirstRecordOffset; 00125 00126 char _interchangeLevel; 00127 char _inlineCodeExtensionIndicator; 00128 char _versionNumber; 00129 char _appIndicator; 00130 int _fieldControlLength; 00131 char _extendedCharSet[4]; 00132 00133 long _recLength; 00134 char _leaderIden; 00135 long _fieldAreaStart; 00136 long _sizeFieldLength; 00137 long _sizeFieldPos; 00138 long _sizeFieldTag; 00139 00140 // One DirEntry per field. 00141 int nFieldDefnCount; 00142 DDFFieldDefn **papoFieldDefns; 00143 00144 DDFRecord *poRecord; 00145 00146 int nCloneCount; 00147 int nMaxCloneCount; 00148 DDFRecord **papoClones; 00149 }; 00150 00151 /************************************************************************/ 00152 /* DDFFieldDefn */ 00153 /************************************************************************/ 00154 00155 typedef enum { dsc_elementary, dsc_vector, dsc_array, dsc_concatenated } DDF_data_struct_code; 00156 typedef enum { dtc_char_string, 00157 dtc_implicit_point, 00158 dtc_explicit_point, 00159 dtc_explicit_point_scaled, 00160 dtc_char_bit_string, 00161 dtc_bit_string, 00162 dtc_mixed_data_type } DDF_data_type_code; 00163 00171 class CPL_ODLL DDFFieldDefn 00172 { 00173 public: 00174 DDFFieldDefn(); 00175 ~DDFFieldDefn(); 00176 00177 int Create( const char *pszTag, const char *pszFieldName, 00178 const char *pszDescription, 00179 DDF_data_struct_code eDataStructCode, 00180 DDF_data_type_code eDataTypeCode, 00181 const char *pszFormat = NULL ); 00182 void AddSubfield( DDFSubfieldDefn *poNewSFDefn, 00183 int bDontAddToFormat = FALSE ); 00184 void AddSubfield( const char *pszName, const char *pszFormat ); 00185 int GenerateDDREntry( char **ppachData, int *pnLength ); 00186 00187 int Initialize( DDFModule * poModule, const char *pszTag, 00188 int nSize, const char * pachRecord ); 00189 00190 void Dump( FILE * fp ); 00191 00195 const char *GetName() { return pszTag; } 00196 00200 const char *GetDescription() { return _fieldName; } 00201 00203 int GetSubfieldCount() { return nSubfieldCount; } 00204 00205 DDFSubfieldDefn *GetSubfield( int i ); 00206 DDFSubfieldDefn *FindSubfieldDefn( const char * ); 00207 00215 int GetFixedWidth() { return nFixedWidth; } 00216 00222 int IsRepeating() { return bRepeatingSubfields; } 00223 00224 static char *ExpandFormat( const char * ); 00225 00227 void SetRepeatingFlag( int n ) { bRepeatingSubfields = n; } 00228 00229 char *GetDefaultValue( int *pnSize ); 00230 00231 private: 00232 00233 static char *ExtractSubstring( const char * ); 00234 00235 DDFModule * poModule; 00236 char * pszTag; 00237 00238 char * _fieldName; 00239 char * _arrayDescr; 00240 char * _formatControls; 00241 00242 int bRepeatingSubfields; 00243 int nFixedWidth; // zero if variable. 00244 00245 int BuildSubfields(); 00246 int ApplyFormats(); 00247 00248 DDF_data_struct_code _data_struct_code; 00249 00250 DDF_data_type_code _data_type_code; 00251 00252 int nSubfieldCount; 00253 DDFSubfieldDefn **papoSubfields; 00254 }; 00255 00256 /************************************************************************/ 00257 /* DDFSubfieldDefn */ 00258 /* */ 00259 /* Information from the DDR record for one subfield of a */ 00260 /* particular field. */ 00261 /************************************************************************/ 00262 00270 class CPL_ODLL DDFSubfieldDefn 00271 { 00272 public: 00273 00274 DDFSubfieldDefn(); 00275 ~DDFSubfieldDefn(); 00276 00277 void SetName( const char * pszName ); 00278 00280 const char *GetName() { return pszName; } 00281 00283 const char *GetFormat() { return pszFormatString; } 00284 int SetFormat( const char * pszFormat ); 00285 00294 DDFDataType GetType() { return eType; } 00295 00296 double ExtractFloatData( const char *pachData, int nMaxBytes, 00297 int * pnConsumedBytes ); 00298 int ExtractIntData( const char *pachData, int nMaxBytes, 00299 int * pnConsumedBytes ); 00300 const char *ExtractStringData( const char *pachData, int nMaxBytes, 00301 int * pnConsumedBytes ); 00302 int GetDataLength( const char *, int, int * ); 00303 void DumpData( const char *pachData, int nMaxBytes, FILE * fp ); 00304 00305 int FormatStringValue( char *pachData, int nBytesAvailable, 00306 int *pnBytesUsed, const char *pszValue, 00307 int nValueLength = -1 ); 00308 00309 int FormatIntValue( char *pachData, int nBytesAvailable, 00310 int *pnBytesUsed, int nNewValue ); 00311 00312 int FormatFloatValue( char *pachData, int nBytesAvailable, 00313 int *pnBytesUsed, double dfNewValue ); 00314 00316 int GetWidth() { return nFormatWidth; } // zero for variable. 00317 00318 int GetDefaultValue( char *pachData, int nBytesAvailable, 00319 int *pnBytesUsed ); 00320 00321 void Dump( FILE * fp ); 00322 00327 typedef enum { 00328 NotBinary=0, 00329 UInt=1, 00330 SInt=2, 00331 FPReal=3, 00332 FloatReal=4, 00333 FloatComplex=5 00334 } DDFBinaryFormat; 00335 00336 DDFBinaryFormat GetBinaryFormat(void) const { return eBinaryFormat; } 00337 00338 00339 private: 00340 00341 char *pszName; // a.k.a. subfield mnemonic 00342 char *pszFormatString; 00343 00344 DDFDataType eType; 00345 DDFBinaryFormat eBinaryFormat; 00346 00347 /* -------------------------------------------------------------------- */ 00348 /* bIsVariable determines whether we using the */ 00349 /* chFormatDelimeter (TRUE), or the fixed width (FALSE). */ 00350 /* -------------------------------------------------------------------- */ 00351 int bIsVariable; 00352 00353 char chFormatDelimeter; 00354 int nFormatWidth; 00355 00356 /* -------------------------------------------------------------------- */ 00357 /* Fetched string cache. This is where we hold the values */ 00358 /* returned from ExtractStringData(). */ 00359 /* -------------------------------------------------------------------- */ 00360 int nMaxBufChars; 00361 char *pachBuffer; 00362 }; 00363 00364 /************************************************************************/ 00365 /* DDFRecord */ 00366 /* */ 00367 /* Class that contains one DR record from a file. We read into */ 00368 /* the same record object repeatedly to ensure that repeated */ 00369 /* leaders can be easily preserved. */ 00370 /************************************************************************/ 00371 00377 class CPL_ODLL DDFRecord 00378 { 00379 public: 00380 DDFRecord( DDFModule * ); 00381 ~DDFRecord(); 00382 00383 DDFRecord *Clone(); 00384 DDFRecord *CloneOn( DDFModule * ); 00385 00386 void Dump( FILE * ); 00387 00389 int GetFieldCount() { return nFieldCount; } 00390 00391 DDFField *FindField( const char *, int = 0 ); 00392 DDFField *GetField( int ); 00393 00394 int GetIntSubfield( const char *, int, const char *, int, 00395 int * = NULL ); 00396 double GetFloatSubfield( const char *, int, const char *, int, 00397 int * = NULL ); 00398 const char *GetStringSubfield( const char *, int, const char *, int, 00399 int * = NULL ); 00400 00401 int SetIntSubfield( const char *pszField, int iFieldIndex, 00402 const char *pszSubfield, int iSubfieldIndex, 00403 int nValue ); 00404 int SetStringSubfield( const char *pszField, int iFieldIndex, 00405 const char *pszSubfield, int iSubfieldIndex, 00406 const char *pszValue, int nValueLength=-1 ); 00407 int SetFloatSubfield( const char *pszField, int iFieldIndex, 00408 const char *pszSubfield, int iSubfieldIndex, 00409 double dfNewValue ); 00410 00412 int GetDataSize() { return nDataSize; } 00413 00419 const char *GetData() { return pachData; } 00420 00425 DDFModule * GetModule() { return poModule; } 00426 00427 int ResizeField( DDFField *poField, int nNewDataSize ); 00428 int DeleteField( DDFField *poField ); 00429 DDFField* AddField( DDFFieldDefn * ); 00430 00431 int CreateDefaultFieldInstance( DDFField *poField, int iIndexWithinField ); 00432 00433 int SetFieldRaw( DDFField *poField, int iIndexWithinField, 00434 const char *pachRawData, int nRawDataSize ); 00435 int UpdateFieldRaw( DDFField *poField, int iIndexWithinField, 00436 int nStartOffset, int nOldSize, 00437 const char *pachRawData, int nRawDataSize ); 00438 00439 int Write(); 00440 00441 // This is really just for the DDFModule class. 00442 int Read(); 00443 void Clear(); 00444 int ResetDirectory(); 00445 00446 private: 00447 00448 int ReadHeader(); 00449 00450 DDFModule *poModule; 00451 00452 int nReuseHeader; 00453 00454 int nFieldOffset; // field data area, not dir entries. 00455 00456 int _sizeFieldTag; 00457 int _sizeFieldPos; 00458 int _sizeFieldLength; 00459 00460 int nDataSize; // Whole record except leader with header 00461 char *pachData; 00462 00463 int nFieldCount; 00464 DDFField *paoFields; 00465 00466 int bIsClone; 00467 }; 00468 00469 /************************************************************************/ 00470 /* DDFField */ 00471 /* */ 00472 /* This object represents one field in a DDFRecord. */ 00473 /************************************************************************/ 00474 00484 class CPL_ODLL DDFField 00485 { 00486 public: 00487 void Initialize( DDFFieldDefn *, const char *pszData, 00488 int nSize ); 00489 00490 void Dump( FILE * fp ); 00491 00492 const char *GetSubfieldData( DDFSubfieldDefn *, 00493 int * = NULL, int = 0 ); 00494 00495 const char *GetInstanceData( int nInstance, int *pnSize ); 00496 00501 const char *GetData() { return pachData; } 00502 00504 int GetDataSize() { return nDataSize; } 00505 00506 int GetRepeatCount(); 00507 00509 DDFFieldDefn *GetFieldDefn() { return poDefn; } 00510 00511 private: 00512 DDFFieldDefn *poDefn; 00513 00514 int nDataSize; 00515 00516 const char *pachData; 00517 }; 00518 00519 00520 #endif /* ndef _ISO8211_H_INCLUDED */