ISO8211Lib
iso8211.h
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 */

Generated for GDAL by doxygen 1.7.4.