iso8211.h

00001 /******************************************************************************
00002  * $Id: iso8211.h,v 1.20 2005/12/08 20:22:24 fwarmerdam Exp $
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  * $Log: iso8211.h,v $
00031  * Revision 1.20  2005/12/08 20:22:24  fwarmerdam
00032  * use CPL_ODLL to optionally export ISO8211lib api
00033  *
00034  * Revision 1.19  2004/01/06 18:59:18  warmerda
00035  * make enum identifiers more unique
00036  *
00037  * Revision 1.18  2004/01/06 18:53:41  warmerda
00038  * made data_type_code and data_struct_code global for HP C++ builds
00039  *
00040  * Revision 1.17  2003/09/03 20:36:26  warmerda
00041  * added subfield writing support
00042  *
00043  * Revision 1.16  2003/08/21 21:21:44  warmerda
00044  * expose the binary format type for a subfield defn
00045  *
00046  * Revision 1.15  2003/07/03 15:38:46  warmerda
00047  * some write capabilities added
00048  *
00049  * Revision 1.14  2001/08/29 17:47:33  warmerda
00050  * added GetInstanceData
00051  *
00052  * Revision 1.13  2001/08/24 19:41:19  warmerda
00053  * fixed cloning problems
00054  *
00055  * Revision 1.12  2001/08/24 16:30:55  warmerda
00056  * added DDFRecord update in place methods for S57 updating
00057  *
00058  * Revision 1.11  2000/09/19 14:08:51  warmerda
00059  * keep and report _extendedCharSet
00060  *
00061  * Revision 1.10  2000/06/16 18:02:08  warmerda
00062  * added SetRepeatingFlag hack support
00063  *
00064  * Revision 1.9  2000/01/31 18:03:39  warmerda
00065  * completely rewrote format expansion to make more general
00066  *
00067  * Revision 1.8  1999/11/18 19:03:04  warmerda
00068  * expanded tabs
00069  *
00070  * Revision 1.7  1999/11/18 19:02:38  warmerda
00071  * added failquietly to open
00072  *
00073  * Revision 1.6  1999/09/20 19:29:30  warmerda
00074  * make forgiving of UNIT/FIELD terminator mixup in Tiger SDTS files
00075  *
00076  * Revision 1.5  1999/08/13 03:26:29  warmerda
00077  * added Rewind()
00078  *
00079  * Revision 1.4  1999/05/07 14:11:22  warmerda
00080  * added subfield value fetches on record, and other odds and ends.
00081  *
00082  * Revision 1.3  1999/05/06 14:23:32  warmerda
00083  * added DDFBinaryString
00084  *
00085  * Revision 1.2  1999/04/27 22:09:50  warmerda
00086  * updated docs
00087  *
00088  * Revision 1.1  1999/04/27 18:45:09  warmerda
00089  * New
00090  *
00091  */
00092 
00093 #ifndef _ISO8211_H_INCLUDED
00094 #define _ISO8211_H_INCLUDED
00095 
00096 #include "cpl_port.h"
00097 
00101 typedef enum {
00102     DDFInt,
00103     DDFFloat,
00104     DDFString,
00105     DDFBinaryString
00106 } DDFDataType;
00107   
00108 /************************************************************************/
00109 /*      These should really be private to the library ... they are      */
00110 /*      mostly conveniences.                                            */
00111 /************************************************************************/
00112 
00113 long CPL_ODLL DDFScanInt( const char *pszString, int nMaxChars );
00114 int  CPL_ODLL DDFScanVariable( const char * pszString, int nMaxChars, int nDelimChar );
00115 char CPL_ODLL *DDFFetchVariable( const char *pszString, int nMaxChars,
00116                         int nDelimChar1, int nDelimChar2,
00117                         int *pnConsumedChars );
00118 
00119 #define DDF_FIELD_TERMINATOR    30
00120 #define DDF_UNIT_TERMINATOR     31
00121 
00122 /************************************************************************/
00123 /*                           Predeclarations                            */
00124 /************************************************************************/
00125 
00126 class DDFFieldDefn;
00127 class DDFSubfieldDefn;
00128 class DDFRecord;
00129 class DDFField;
00130 
00131 /************************************************************************/
00132 /*                              DDFModule                               */
00133 /************************************************************************/
00134 
00142 class CPL_ODLL DDFModule
00143 {
00144   public:
00145                 DDFModule();
00146                 ~DDFModule();
00147                 
00148     int         Open( const char * pszFilename, int bFailQuietly = FALSE );
00149     int         Create( const char *pszFilename );
00150     void        Close();
00151 
00152     int         Initialize( char chInterchangeLevel = '3',
00153                             char chLeaderIden = 'L', 
00154                             char chCodeExtensionIndicator = 'E',
00155                             char chVersionNumber = '1',
00156                             char chAppIndicator = ' ',
00157                             const char *pszExtendedCharSet = " ! ",
00158                             int nSizeFieldLength = 3,
00159                             int nSizeFieldPos = 4,
00160                             int nSizeFieldTag = 4 );
00161 
00162     void        Dump( FILE * fp );
00163 
00164     DDFRecord   *ReadRecord( void );
00165     void        Rewind( long nOffset = -1 );
00166 
00167     DDFFieldDefn *FindFieldDefn( const char * );
00168 
00171     int         GetFieldCount() { return nFieldDefnCount; }
00172     DDFFieldDefn *GetField(int);
00173     void        AddField( DDFFieldDefn *poNewFDefn );
00174     
00175     // This is really just for internal use.
00176     int         GetFieldControlLength() { return _fieldControlLength; }
00177     void        AddCloneRecord( DDFRecord * );
00178     void        RemoveCloneRecord( DDFRecord * );
00179     
00180     // This is just for DDFRecord.
00181     FILE        *GetFP() { return fpDDF; }
00182     
00183   private:
00184     FILE        *fpDDF;
00185     int         bReadOnly;
00186     long        nFirstRecordOffset;
00187 
00188     char        _interchangeLevel;
00189     char        _inlineCodeExtensionIndicator;
00190     char        _versionNumber;
00191     char        _appIndicator;
00192     int         _fieldControlLength;
00193     char        _extendedCharSet[4];
00194 
00195     long _recLength;
00196     char _leaderIden;
00197     long _fieldAreaStart;
00198     long _sizeFieldLength;
00199     long _sizeFieldPos;
00200     long _sizeFieldTag;
00201 
00202     // One DirEntry per field.  
00203     int         nFieldDefnCount;
00204     DDFFieldDefn **papoFieldDefns;
00205 
00206     DDFRecord   *poRecord;
00207 
00208     int         nCloneCount;
00209     int         nMaxCloneCount;
00210     DDFRecord   **papoClones;
00211 };
00212 
00213 /************************************************************************/
00214 /*                             DDFFieldDefn                             */
00215 /************************************************************************/
00216 
00217   typedef enum { dsc_elementary, dsc_vector, dsc_array, dsc_concatenated } DDF_data_struct_code;
00218   typedef enum { dtc_char_string, 
00219                  dtc_implicit_point, 
00220                  dtc_explicit_point, 
00221                  dtc_explicit_point_scaled, 
00222                  dtc_char_bit_string, 
00223                  dtc_bit_string, 
00224                  dtc_mixed_data_type } DDF_data_type_code;
00225 
00233 class CPL_ODLL DDFFieldDefn
00234 {
00235   public:
00236                 DDFFieldDefn();
00237                 ~DDFFieldDefn();
00238 
00239     int         Create( const char *pszTag, const char *pszFieldName,
00240                         const char *pszDescription,
00241                         DDF_data_struct_code eDataStructCode,
00242                         DDF_data_type_code   eDataTypeCode,
00243                         const char *pszFormat = NULL );
00244     void        AddSubfield( DDFSubfieldDefn *poNewSFDefn,
00245                              int bDontAddToFormat = FALSE );
00246     void        AddSubfield( const char *pszName, const char *pszFormat );
00247     int         GenerateDDREntry( char **ppachData, int *pnLength ); 
00248                             
00249     int         Initialize( DDFModule * poModule, const char *pszTag,
00250                             int nSize, const char * pachRecord );
00251     
00252     void        Dump( FILE * fp );
00253 
00257     const char  *GetName() { return pszTag; }
00258 
00262     const char  *GetDescription() { return _fieldName; }
00263 
00265     int         GetSubfieldCount() { return nSubfieldCount; }
00266     
00267     DDFSubfieldDefn *GetSubfield( int i );
00268     DDFSubfieldDefn *FindSubfieldDefn( const char * );
00269 
00277     int         GetFixedWidth() { return nFixedWidth; }
00278 
00284     int         IsRepeating() { return bRepeatingSubfields; }
00285 
00286     static char       *ExpandFormat( const char * );
00287 
00289     void SetRepeatingFlag( int n ) { bRepeatingSubfields = n; }
00290 
00291     char        *GetDefaultValue( int *pnSize );
00292     
00293   private:
00294 
00295     static char       *ExtractSubstring( const char * );
00296 
00297     DDFModule * poModule;
00298     char *      pszTag;
00299 
00300     char *      _fieldName;
00301     char *      _arrayDescr;
00302     char *      _formatControls;
00303 
00304     int         bRepeatingSubfields;
00305     int         nFixedWidth;    // zero if variable. 
00306 
00307     int         BuildSubfields();
00308     int         ApplyFormats();
00309 
00310     DDF_data_struct_code _data_struct_code;
00311 
00312     DDF_data_type_code   _data_type_code;
00313 
00314     int         nSubfieldCount;
00315     DDFSubfieldDefn **papoSubfields;
00316 };
00317 
00318 /************************************************************************/
00319 /*                           DDFSubfieldDefn                            */
00320 /*                                                                      */
00321 /*      Information from the DDR record for one subfield of a           */
00322 /*      particular field.                                               */
00323 /************************************************************************/
00324 
00332 class CPL_ODLL DDFSubfieldDefn
00333 {
00334 public:
00335 
00336                 DDFSubfieldDefn();
00337                 ~DDFSubfieldDefn();
00338 
00339     void        SetName( const char * pszName );
00340 
00342     const char  *GetName() { return pszName; }
00343     
00345     const char  *GetFormat() { return pszFormatString; }
00346     int         SetFormat( const char * pszFormat );
00347 
00356     DDFDataType GetType() { return eType; }
00357 
00358     double      ExtractFloatData( const char *pachData, int nMaxBytes,
00359                                   int * pnConsumedBytes );
00360     int         ExtractIntData( const char *pachData, int nMaxBytes,
00361                                 int * pnConsumedBytes );
00362     const char  *ExtractStringData( const char *pachData, int nMaxBytes,
00363                                     int * pnConsumedBytes );
00364     int         GetDataLength( const char *, int, int * );
00365     void        DumpData( const char *pachData, int nMaxBytes, FILE * fp );
00366 
00367     int         FormatStringValue( char *pachData, int nBytesAvailable, 
00368                                    int *pnBytesUsed, const char *pszValue, 
00369                                    int nValueLength = -1 );
00370 
00371     int         FormatIntValue( char *pachData, int nBytesAvailable, 
00372                                 int *pnBytesUsed, int nNewValue );
00373 
00374     int         FormatFloatValue( char *pachData, int nBytesAvailable, 
00375                                   int *pnBytesUsed, double dfNewValue );
00376 
00378     int         GetWidth() { return nFormatWidth; } // zero for variable.
00379 
00380     int         GetDefaultValue( char *pachData, int nBytesAvailable, 
00381                                  int *pnBytesUsed );
00382     
00383     void        Dump( FILE * fp );
00384 
00389 typedef enum {
00390     NotBinary=0,
00391     UInt=1,
00392     SInt=2,
00393     FPReal=3,
00394     FloatReal=4,
00395     FloatComplex=5
00396 } DDFBinaryFormat;
00397 
00398     DDFBinaryFormat GetBinaryFormat(void) const { return eBinaryFormat; }
00399     
00400 
00401 private:
00402 
00403   char      *pszName;   // a.k.a. subfield mnemonic
00404   char      *pszFormatString; 
00405 
00406   DDFDataType           eType;
00407   DDFBinaryFormat       eBinaryFormat;
00408 
00409 /* -------------------------------------------------------------------- */
00410 /*      bIsVariable determines whether we using the                     */
00411 /*      chFormatDelimeter (TRUE), or the fixed width (FALSE).           */
00412 /* -------------------------------------------------------------------- */
00413   int        bIsVariable;
00414   
00415   char       chFormatDelimeter;
00416   int        nFormatWidth;
00417 
00418 /* -------------------------------------------------------------------- */
00419 /*      Fetched string cache.  This is where we hold the values         */
00420 /*      returned from ExtractStringData().                              */
00421 /* -------------------------------------------------------------------- */
00422   int        nMaxBufChars;
00423   char       *pachBuffer;
00424 };
00425 
00426 /************************************************************************/
00427 /*                              DDFRecord                               */
00428 /*                                                                      */
00429 /*      Class that contains one DR record from a file.  We read into    */
00430 /*      the same record object repeatedly to ensure that repeated       */
00431 /*      leaders can be easily preserved.                                */
00432 /************************************************************************/
00433 
00439 class CPL_ODLL DDFRecord
00440 {
00441   public:
00442                 DDFRecord( DDFModule * );
00443                 ~DDFRecord();
00444 
00445     DDFRecord  *Clone();
00446     DDFRecord  *CloneOn( DDFModule * );
00447     
00448     void        Dump( FILE * );
00449 
00451     int         GetFieldCount() { return nFieldCount; }
00452 
00453     DDFField    *FindField( const char *, int = 0 );
00454     DDFField    *GetField( int );
00455 
00456     int         GetIntSubfield( const char *, int, const char *, int,
00457                                 int * = NULL );
00458     double      GetFloatSubfield( const char *, int, const char *, int,
00459                                   int * = NULL );
00460     const char *GetStringSubfield( const char *, int, const char *, int,
00461                                    int * = NULL );
00462 
00463     int         SetIntSubfield( const char *pszField, int iFieldIndex, 
00464                                 const char *pszSubfield, int iSubfieldIndex,
00465                                 int nValue );
00466     int         SetStringSubfield( const char *pszField, int iFieldIndex, 
00467                                    const char *pszSubfield, int iSubfieldIndex,
00468                                    const char *pszValue, int nValueLength=-1 );
00469     int         SetFloatSubfield( const char *pszField, int iFieldIndex, 
00470                                   const char *pszSubfield, int iSubfieldIndex,
00471                                   double dfNewValue );
00472 
00474     int         GetDataSize() { return nDataSize; }
00475 
00481     const char  *GetData() { return pachData; }
00482 
00487     DDFModule * GetModule() { return poModule; }
00488 
00489     int ResizeField( DDFField *poField, int nNewDataSize );
00490     int DeleteField( DDFField *poField );
00491     DDFField* AddField( DDFFieldDefn * );
00492 
00493     int CreateDefaultFieldInstance( DDFField *poField, int iIndexWithinField );
00494 
00495     int SetFieldRaw( DDFField *poField, int iIndexWithinField, 
00496                      const char *pachRawData, int nRawDataSize );
00497     int UpdateFieldRaw( DDFField *poField, int iIndexWithinField, 
00498                         int nStartOffset, int nOldSize,
00499                         const char *pachRawData, int nRawDataSize );
00500 
00501     int         Write();
00502     
00503     // This is really just for the DDFModule class.
00504     int         Read();
00505     void        Clear();
00506     int         ResetDirectory();
00507     
00508   private:
00509 
00510     int         ReadHeader();
00511     
00512     DDFModule   *poModule;
00513 
00514     int         nReuseHeader;   
00515 
00516     int         nFieldOffset;   // field data area, not dir entries.
00517 
00518     int         _sizeFieldTag;
00519     int         _sizeFieldPos;
00520     int         _sizeFieldLength;
00521 
00522     int         nDataSize;      // Whole record except leader with header
00523     char        *pachData;
00524 
00525     int         nFieldCount;
00526     DDFField    *paoFields;
00527 
00528     int         bIsClone;
00529 };
00530 
00531 /************************************************************************/
00532 /*                               DDFField                               */
00533 /*                                                                      */
00534 /*      This object represents one field in a DDFRecord.                */
00535 /************************************************************************/
00536 
00546 class CPL_ODLL DDFField
00547 {
00548   public:
00549     void                Initialize( DDFFieldDefn *, const char *pszData,
00550                                     int nSize );
00551 
00552     void                Dump( FILE * fp );
00553 
00554     const char         *GetSubfieldData( DDFSubfieldDefn *,
00555                                          int * = NULL, int = 0 );
00556 
00557     const char         *GetInstanceData( int nInstance, int *pnSize );
00558 
00563     const char         *GetData() { return pachData; }
00564 
00566     int                 GetDataSize() { return nDataSize; }
00567 
00568     int                 GetRepeatCount();
00569 
00571     DDFFieldDefn        *GetFieldDefn() { return poDefn; }
00572     
00573   private:
00574     DDFFieldDefn        *poDefn;
00575 
00576     int                 nDataSize;
00577 
00578     const char          *pachData;
00579 };
00580 
00581 
00582 #endif /* ndef _ISO8211_H_INCLUDED */

Generated on Tue Jul 4 10:06:07 2006 for ISO8211Lib by  doxygen 1.4.6