SDTS_AL
|
00001 /****************************************************************************** 00002 * $Id: iso8211.h 10645 2007-01-18 02:22:39Z warmerdam $ 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 00038 typedef enum { 00039 DDFInt, 00040 DDFFloat, 00041 DDFString, 00042 DDFBinaryString 00043 } DDFDataType; 00044 00045 /************************************************************************/ 00046 /* These should really be private to the library ... they are */ 00047 /* mostly conveniences. */ 00048 /************************************************************************/ 00049 00050 long CPL_ODLL DDFScanInt( const char *pszString, int nMaxChars ); 00051 int CPL_ODLL DDFScanVariable( const char * pszString, int nMaxChars, int nDelimChar ); 00052 char CPL_ODLL *DDFFetchVariable( const char *pszString, int nMaxChars, 00053 int nDelimChar1, int nDelimChar2, 00054 int *pnConsumedChars ); 00055 00056 #define DDF_FIELD_TERMINATOR 30 00057 #define DDF_UNIT_TERMINATOR 31 00058 00059 /************************************************************************/ 00060 /* Predeclarations */ 00061 /************************************************************************/ 00062 00063 class DDFFieldDefn; 00064 class DDFSubfieldDefn; 00065 class DDFRecord; 00066 class DDFField; 00067 00068 /************************************************************************/ 00069 /* DDFModule */ 00070 /************************************************************************/ 00071 00079 class CPL_ODLL DDFModule 00080 { 00081 public: 00082 DDFModule(); 00083 ~DDFModule(); 00084 00085 int Open( const char * pszFilename, int bFailQuietly = FALSE ); 00086 int Create( const char *pszFilename ); 00087 void Close(); 00088 00089 int Initialize( char chInterchangeLevel = '3', 00090 char chLeaderIden = 'L', 00091 char chCodeExtensionIndicator = 'E', 00092 char chVersionNumber = '1', 00093 char chAppIndicator = ' ', 00094 const char *pszExtendedCharSet = " ! ", 00095 int nSizeFieldLength = 3, 00096 int nSizeFieldPos = 4, 00097 int nSizeFieldTag = 4 ); 00098 00099 void Dump( FILE * fp ); 00100 00101 DDFRecord *ReadRecord( void ); 00102 void Rewind( long nOffset = -1 ); 00103 00104 DDFFieldDefn *FindFieldDefn( const char * ); 00105 00108 int GetFieldCount() { return nFieldDefnCount; } 00109 DDFFieldDefn *GetField(int); 00110 void AddField( DDFFieldDefn *poNewFDefn ); 00111 00112 // This is really just for internal use. 00113 int GetFieldControlLength() { return _fieldControlLength; } 00114 void AddCloneRecord( DDFRecord * ); 00115 void RemoveCloneRecord( DDFRecord * ); 00116 00117 // This is just for DDFRecord. 00118 FILE *GetFP() { return fpDDF; } 00119 00120 private: 00121 FILE *fpDDF; 00122 int bReadOnly; 00123 long nFirstRecordOffset; 00124 00125 char _interchangeLevel; 00126 char _inlineCodeExtensionIndicator; 00127 char _versionNumber; 00128 char _appIndicator; 00129 int _fieldControlLength; 00130 char _extendedCharSet[4]; 00131 00132 long _recLength; 00133 char _leaderIden; 00134 long _fieldAreaStart; 00135 long _sizeFieldLength; 00136 long _sizeFieldPos; 00137 long _sizeFieldTag; 00138 00139 // One DirEntry per field. 00140 int nFieldDefnCount; 00141 DDFFieldDefn **papoFieldDefns; 00142 00143 DDFRecord *poRecord; 00144 00145 int nCloneCount; 00146 int nMaxCloneCount; 00147 DDFRecord **papoClones; 00148 }; 00149 00150 /************************************************************************/ 00151 /* DDFFieldDefn */ 00152 /************************************************************************/ 00153 00154 typedef enum { dsc_elementary, dsc_vector, dsc_array, dsc_concatenated } DDF_data_struct_code; 00155 typedef enum { dtc_char_string, 00156 dtc_implicit_point, 00157 dtc_explicit_point, 00158 dtc_explicit_point_scaled, 00159 dtc_char_bit_string, 00160 dtc_bit_string, 00161 dtc_mixed_data_type } DDF_data_type_code; 00162 00170 class CPL_ODLL DDFFieldDefn 00171 { 00172 public: 00173 DDFFieldDefn(); 00174 ~DDFFieldDefn(); 00175 00176 int Create( const char *pszTag, const char *pszFieldName, 00177 const char *pszDescription, 00178 DDF_data_struct_code eDataStructCode, 00179 DDF_data_type_code eDataTypeCode, 00180 const char *pszFormat = NULL ); 00181 void AddSubfield( DDFSubfieldDefn *poNewSFDefn, 00182 int bDontAddToFormat = FALSE ); 00183 void AddSubfield( const char *pszName, const char *pszFormat ); 00184 int GenerateDDREntry( char **ppachData, int *pnLength ); 00185 00186 int Initialize( DDFModule * poModule, const char *pszTag, 00187 int nSize, const char * pachRecord ); 00188 00189 void Dump( FILE * fp ); 00190 00194 const char *GetName() { return pszTag; } 00195 00199 const char *GetDescription() { return _fieldName; } 00200 00202 int GetSubfieldCount() { return nSubfieldCount; } 00203 00204 DDFSubfieldDefn *GetSubfield( int i ); 00205 DDFSubfieldDefn *FindSubfieldDefn( const char * ); 00206 00214 int GetFixedWidth() { return nFixedWidth; } 00215 00221 int IsRepeating() { return bRepeatingSubfields; } 00222 00223 static char *ExpandFormat( const char * ); 00224 00226 void SetRepeatingFlag( int n ) { bRepeatingSubfields = n; } 00227 00228 char *GetDefaultValue( int *pnSize ); 00229 00230 private: 00231 00232 static char *ExtractSubstring( const char * ); 00233 00234 DDFModule * poModule; 00235 char * pszTag; 00236 00237 char * _fieldName; 00238 char * _arrayDescr; 00239 char * _formatControls; 00240 00241 int bRepeatingSubfields; 00242 int nFixedWidth; // zero if variable. 00243 00244 int BuildSubfields(); 00245 int ApplyFormats(); 00246 00247 DDF_data_struct_code _data_struct_code; 00248 00249 DDF_data_type_code _data_type_code; 00250 00251 int nSubfieldCount; 00252 DDFSubfieldDefn **papoSubfields; 00253 }; 00254 00255 /************************************************************************/ 00256 /* DDFSubfieldDefn */ 00257 /* */ 00258 /* Information from the DDR record for one subfield of a */ 00259 /* particular field. */ 00260 /************************************************************************/ 00261 00269 class CPL_ODLL DDFSubfieldDefn 00270 { 00271 public: 00272 00273 DDFSubfieldDefn(); 00274 ~DDFSubfieldDefn(); 00275 00276 void SetName( const char * pszName ); 00277 00279 const char *GetName() { return pszName; } 00280 00282 const char *GetFormat() { return pszFormatString; } 00283 int SetFormat( const char * pszFormat ); 00284 00293 DDFDataType GetType() { return eType; } 00294 00295 double ExtractFloatData( const char *pachData, int nMaxBytes, 00296 int * pnConsumedBytes ); 00297 int ExtractIntData( const char *pachData, int nMaxBytes, 00298 int * pnConsumedBytes ); 00299 const char *ExtractStringData( const char *pachData, int nMaxBytes, 00300 int * pnConsumedBytes ); 00301 int GetDataLength( const char *, int, int * ); 00302 void DumpData( const char *pachData, int nMaxBytes, FILE * fp ); 00303 00304 int FormatStringValue( char *pachData, int nBytesAvailable, 00305 int *pnBytesUsed, const char *pszValue, 00306 int nValueLength = -1 ); 00307 00308 int FormatIntValue( char *pachData, int nBytesAvailable, 00309 int *pnBytesUsed, int nNewValue ); 00310 00311 int FormatFloatValue( char *pachData, int nBytesAvailable, 00312 int *pnBytesUsed, double dfNewValue ); 00313 00315 int GetWidth() { return nFormatWidth; } // zero for variable. 00316 00317 int GetDefaultValue( char *pachData, int nBytesAvailable, 00318 int *pnBytesUsed ); 00319 00320 void Dump( FILE * fp ); 00321 00326 typedef enum { 00327 NotBinary=0, 00328 UInt=1, 00329 SInt=2, 00330 FPReal=3, 00331 FloatReal=4, 00332 FloatComplex=5 00333 } DDFBinaryFormat; 00334 00335 DDFBinaryFormat GetBinaryFormat(void) const { return eBinaryFormat; } 00336 00337 00338 private: 00339 00340 char *pszName; // a.k.a. subfield mnemonic 00341 char *pszFormatString; 00342 00343 DDFDataType eType; 00344 DDFBinaryFormat eBinaryFormat; 00345 00346 /* -------------------------------------------------------------------- */ 00347 /* bIsVariable determines whether we using the */ 00348 /* chFormatDelimeter (TRUE), or the fixed width (FALSE). */ 00349 /* -------------------------------------------------------------------- */ 00350 int bIsVariable; 00351 00352 char chFormatDelimeter; 00353 int nFormatWidth; 00354 00355 /* -------------------------------------------------------------------- */ 00356 /* Fetched string cache. This is where we hold the values */ 00357 /* returned from ExtractStringData(). */ 00358 /* -------------------------------------------------------------------- */ 00359 int nMaxBufChars; 00360 char *pachBuffer; 00361 }; 00362 00363 /************************************************************************/ 00364 /* DDFRecord */ 00365 /* */ 00366 /* Class that contains one DR record from a file. We read into */ 00367 /* the same record object repeatedly to ensure that repeated */ 00368 /* leaders can be easily preserved. */ 00369 /************************************************************************/ 00370 00376 class CPL_ODLL DDFRecord 00377 { 00378 public: 00379 DDFRecord( DDFModule * ); 00380 ~DDFRecord(); 00381 00382 DDFRecord *Clone(); 00383 DDFRecord *CloneOn( DDFModule * ); 00384 00385 void Dump( FILE * ); 00386 00388 int GetFieldCount() { return nFieldCount; } 00389 00390 DDFField *FindField( const char *, int = 0 ); 00391 DDFField *GetField( int ); 00392 00393 int GetIntSubfield( const char *, int, const char *, int, 00394 int * = NULL ); 00395 double GetFloatSubfield( const char *, int, const char *, int, 00396 int * = NULL ); 00397 const char *GetStringSubfield( const char *, int, const char *, int, 00398 int * = NULL ); 00399 00400 int SetIntSubfield( const char *pszField, int iFieldIndex, 00401 const char *pszSubfield, int iSubfieldIndex, 00402 int nValue ); 00403 int SetStringSubfield( const char *pszField, int iFieldIndex, 00404 const char *pszSubfield, int iSubfieldIndex, 00405 const char *pszValue, int nValueLength=-1 ); 00406 int SetFloatSubfield( const char *pszField, int iFieldIndex, 00407 const char *pszSubfield, int iSubfieldIndex, 00408 double dfNewValue ); 00409 00411 int GetDataSize() { return nDataSize; } 00412 00418 const char *GetData() { return pachData; } 00419 00424 DDFModule * GetModule() { return poModule; } 00425 00426 int ResizeField( DDFField *poField, int nNewDataSize ); 00427 int DeleteField( DDFField *poField ); 00428 DDFField* AddField( DDFFieldDefn * ); 00429 00430 int CreateDefaultFieldInstance( DDFField *poField, int iIndexWithinField ); 00431 00432 int SetFieldRaw( DDFField *poField, int iIndexWithinField, 00433 const char *pachRawData, int nRawDataSize ); 00434 int UpdateFieldRaw( DDFField *poField, int iIndexWithinField, 00435 int nStartOffset, int nOldSize, 00436 const char *pachRawData, int nRawDataSize ); 00437 00438 int Write(); 00439 00440 // This is really just for the DDFModule class. 00441 int Read(); 00442 void Clear(); 00443 int ResetDirectory(); 00444 00445 private: 00446 00447 int ReadHeader(); 00448 00449 DDFModule *poModule; 00450 00451 int nReuseHeader; 00452 00453 int nFieldOffset; // field data area, not dir entries. 00454 00455 int _sizeFieldTag; 00456 int _sizeFieldPos; 00457 int _sizeFieldLength; 00458 00459 int nDataSize; // Whole record except leader with header 00460 char *pachData; 00461 00462 int nFieldCount; 00463 DDFField *paoFields; 00464 00465 int bIsClone; 00466 }; 00467 00468 /************************************************************************/ 00469 /* DDFField */ 00470 /* */ 00471 /* This object represents one field in a DDFRecord. */ 00472 /************************************************************************/ 00473 00483 class CPL_ODLL DDFField 00484 { 00485 public: 00486 void Initialize( DDFFieldDefn *, const char *pszData, 00487 int nSize ); 00488 00489 void Dump( FILE * fp ); 00490 00491 const char *GetSubfieldData( DDFSubfieldDefn *, 00492 int * = NULL, int = 0 ); 00493 00494 const char *GetInstanceData( int nInstance, int *pnSize ); 00495 00500 const char *GetData() { return pachData; } 00501 00503 int GetDataSize() { return nDataSize; } 00504 00505 int GetRepeatCount(); 00506 00508 DDFFieldDefn *GetFieldDefn() { return poDefn; } 00509 00510 private: 00511 DDFFieldDefn *poDefn; 00512 00513 int nDataSize; 00514 00515 const char *pachData; 00516 }; 00517 00518 00519 #endif /* ndef _ISO8211_H_INCLUDED */