Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages  

iso8211.h

00001 /******************************************************************************
00002  * $Id: iso8211.h,v 1.17 2003/09/03 20:36:26 warmerda 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.17  2003/09/03 20:36:26  warmerda
00032  * added subfield writing support
00033  *
00034  * Revision 1.16  2003/08/21 21:21:44  warmerda
00035  * expose the binary format type for a subfield defn
00036  *
00037  * Revision 1.15  2003/07/03 15:38:46  warmerda
00038  * some write capabilities added
00039  *
00040  * Revision 1.14  2001/08/29 17:47:33  warmerda
00041  * added GetInstanceData
00042  *
00043  * Revision 1.13  2001/08/24 19:41:19  warmerda
00044  * fixed cloning problems
00045  *
00046  * Revision 1.12  2001/08/24 16:30:55  warmerda
00047  * added DDFRecord update in place methods for S57 updating
00048  *
00049  * Revision 1.11  2000/09/19 14:08:51  warmerda
00050  * keep and report _extendedCharSet
00051  *
00052  * Revision 1.10  2000/06/16 18:02:08  warmerda
00053  * added SetRepeatingFlag hack support
00054  *
00055  * Revision 1.9  2000/01/31 18:03:39  warmerda
00056  * completely rewrote format expansion to make more general
00057  *
00058  * Revision 1.8  1999/11/18 19:03:04  warmerda
00059  * expanded tabs
00060  *
00061  * Revision 1.7  1999/11/18 19:02:38  warmerda
00062  * added failquietly to open
00063  *
00064  * Revision 1.6  1999/09/20 19:29:30  warmerda
00065  * make forgiving of UNIT/FIELD terminator mixup in Tiger SDTS files
00066  *
00067  * Revision 1.5  1999/08/13 03:26:29  warmerda
00068  * added Rewind()
00069  *
00070  * Revision 1.4  1999/05/07 14:11:22  warmerda
00071  * added subfield value fetches on record, and other odds and ends.
00072  *
00073  * Revision 1.3  1999/05/06 14:23:32  warmerda
00074  * added DDFBinaryString
00075  *
00076  * Revision 1.2  1999/04/27 22:09:50  warmerda
00077  * updated docs
00078  *
00079  * Revision 1.1  1999/04/27 18:45:09  warmerda
00080  * New
00081  *
00082  */
00083 
00084 #ifndef _ISO8211_H_INCLUDED
00085 #define _ISO8211_H_INCLUDED
00086 
00087 #include "cpl_port.h"
00088 
00092 typedef enum {
00093     DDFInt,
00094     DDFFloat,
00095     DDFString,
00096     DDFBinaryString
00097 } DDFDataType;
00098   
00099 /************************************************************************/
00100 /*      These should really be private to the library ... they are      */
00101 /*      mostly conveniences.                                            */
00102 /************************************************************************/
00103 
00104 long DDFScanInt( const char *pszString, int nMaxChars );
00105 int  DDFScanVariable( const char * pszString, int nMaxChars, int nDelimChar );
00106 char *DDFFetchVariable( const char *pszString, int nMaxChars,
00107                         int nDelimChar1, int nDelimChar2,
00108                         int *pnConsumedChars );
00109 
00110 #define DDF_FIELD_TERMINATOR    30
00111 #define DDF_UNIT_TERMINATOR     31
00112 
00113 /************************************************************************/
00114 /*                           Predeclarations                            */
00115 /************************************************************************/
00116 
00117 class DDFFieldDefn;
00118 class DDFSubfieldDefn;
00119 class DDFRecord;
00120 class DDFField;
00121 
00122 /************************************************************************/
00123 /*                              DDFModule                               */
00124 /************************************************************************/
00125 
00133 class DDFModule
00134 {
00135   public:
00136                 DDFModule();
00137                 ~DDFModule();
00138                 
00139     int         Open( const char * pszFilename, int bFailQuietly = FALSE );
00140     int         Create( const char *pszFilename );
00141     void        Close();
00142 
00143     int         Initialize( char chInterchangeLevel = '3',
00144                             char chLeaderIden = 'L', 
00145                             char chCodeExtensionIndicator = 'E',
00146                             char chVersionNumber = '1',
00147                             char chAppIndicator = ' ',
00148                             const char *pszExtendedCharSet = " ! ",
00149                             int nSizeFieldLength = 3,
00150                             int nSizeFieldPos = 4,
00151                             int nSizeFieldTag = 4 );
00152 
00153     void        Dump( FILE * fp );
00154 
00155     DDFRecord   *ReadRecord( void );
00156     void        Rewind( long nOffset = -1 );
00157 
00158     DDFFieldDefn *FindFieldDefn( const char * );
00159 
00162     int         GetFieldCount() { return nFieldDefnCount; }
00163     DDFFieldDefn *GetField(int);
00164     void        AddField( DDFFieldDefn *poNewFDefn );
00165     
00166     // This is really just for internal use.
00167     int         GetFieldControlLength() { return _fieldControlLength; }
00168     void        AddCloneRecord( DDFRecord * );
00169     void        RemoveCloneRecord( DDFRecord * );
00170     
00171     // This is just for DDFRecord.
00172     FILE        *GetFP() { return fpDDF; }
00173     
00174   private:
00175     FILE        *fpDDF;
00176     int         bReadOnly;
00177     long        nFirstRecordOffset;
00178 
00179     char        _interchangeLevel;
00180     char        _inlineCodeExtensionIndicator;
00181     char        _versionNumber;
00182     char        _appIndicator;
00183     int         _fieldControlLength;
00184     char        _extendedCharSet[4];
00185 
00186     long _recLength;
00187     char _leaderIden;
00188     long _fieldAreaStart;
00189     long _sizeFieldLength;
00190     long _sizeFieldPos;
00191     long _sizeFieldTag;
00192 
00193     // One DirEntry per field.  
00194     int         nFieldDefnCount;
00195     DDFFieldDefn **papoFieldDefns;
00196 
00197     DDFRecord   *poRecord;
00198 
00199     int         nCloneCount;
00200     int         nMaxCloneCount;
00201     DDFRecord   **papoClones;
00202 };
00203 
00204 /************************************************************************/
00205 /*                             DDFFieldDefn                             */
00206 /************************************************************************/
00207 
00215 class DDFFieldDefn
00216 {
00217   public:
00218                 DDFFieldDefn();
00219                 ~DDFFieldDefn();
00220 
00221   typedef enum { elementary, vector, array, concatenated } data_struct_code;
00222   typedef enum { char_string, 
00223                  implicit_point, 
00224                  explicit_point, 
00225                  explicit_point_scaled, 
00226                  char_bit_string, 
00227                  bit_string, 
00228                  mixed_data_type } data_type_code;
00229 
00230     int         Create( const char *pszTag, const char *pszFieldName,
00231                         const char *pszDescription,
00232                         DDFFieldDefn::data_struct_code eDataStructCode,
00233                         DDFFieldDefn::data_type_code   eDataTypeCode,
00234                         const char *pszFormat = NULL );
00235     void        AddSubfield( DDFSubfieldDefn *poNewSFDefn,
00236                              int bDontAddToFormat = FALSE );
00237     void        AddSubfield( const char *pszName, const char *pszFormat );
00238     int         GenerateDDREntry( char **ppachData, int *pnLength ); 
00239                             
00240     int         Initialize( DDFModule * poModule, const char *pszTag,
00241                             int nSize, const char * pachRecord );
00242     
00243     void        Dump( FILE * fp );
00244 
00248     const char  *GetName() { return pszTag; }
00249 
00253     const char  *GetDescription() { return _fieldName; }
00254 
00256     int         GetSubfieldCount() { return nSubfieldCount; }
00257     
00258     DDFSubfieldDefn *GetSubfield( int i );
00259     DDFSubfieldDefn *FindSubfieldDefn( const char * );
00260 
00268     int         GetFixedWidth() { return nFixedWidth; }
00269 
00275     int         IsRepeating() { return bRepeatingSubfields; }
00276 
00277     static char       *ExpandFormat( const char * );
00278 
00280     void SetRepeatingFlag( int n ) { bRepeatingSubfields = n; }
00281 
00282     char        *GetDefaultValue( int *pnSize );
00283     
00284   private:
00285 
00286     static char       *ExtractSubstring( const char * );
00287 
00288     DDFModule * poModule;
00289     char *      pszTag;
00290 
00291     char *      _fieldName;
00292     char *      _arrayDescr;
00293     char *      _formatControls;
00294 
00295     int         bRepeatingSubfields;
00296     int         nFixedWidth;    // zero if variable. 
00297 
00298     int         BuildSubfields();
00299     int         ApplyFormats();
00300 
00301     DDFFieldDefn::data_struct_code _data_struct_code;
00302 
00303     DDFFieldDefn::data_type_code   _data_type_code;
00304 
00305     int         nSubfieldCount;
00306     DDFSubfieldDefn **papoSubfields;
00307 };
00308 
00309 /************************************************************************/
00310 /*                           DDFSubfieldDefn                            */
00311 /*                                                                      */
00312 /*      Information from the DDR record for one subfield of a           */
00313 /*      particular field.                                               */
00314 /************************************************************************/
00315 
00323 class DDFSubfieldDefn
00324 {
00325 public:
00326 
00327                 DDFSubfieldDefn();
00328                 ~DDFSubfieldDefn();
00329 
00330     void        SetName( const char * pszName );
00331 
00333     const char  *GetName() { return pszName; }
00334     
00336     const char  *GetFormat() { return pszFormatString; }
00337     int         SetFormat( const char * pszFormat );
00338 
00347     DDFDataType GetType() { return eType; }
00348 
00349     double      ExtractFloatData( const char *pachData, int nMaxBytes,
00350                                   int * pnConsumedBytes );
00351     int         ExtractIntData( const char *pachData, int nMaxBytes,
00352                                 int * pnConsumedBytes );
00353     const char  *ExtractStringData( const char *pachData, int nMaxBytes,
00354                                     int * pnConsumedBytes );
00355     int         GetDataLength( const char *, int, int * );
00356     void        DumpData( const char *pachData, int nMaxBytes, FILE * fp );
00357 
00358     int         FormatStringValue( char *pachData, int nBytesAvailable, 
00359                                    int *pnBytesUsed, const char *pszValue, 
00360                                    int nValueLength = -1 );
00361 
00362     int         FormatIntValue( char *pachData, int nBytesAvailable, 
00363                                 int *pnBytesUsed, int nNewValue );
00364 
00365     int         FormatFloatValue( char *pachData, int nBytesAvailable, 
00366                                   int *pnBytesUsed, double dfNewValue );
00367 
00369     int         GetWidth() { return nFormatWidth; } // zero for variable.
00370 
00371     int         GetDefaultValue( char *pachData, int nBytesAvailable, 
00372                                  int *pnBytesUsed );
00373     
00374     void        Dump( FILE * fp );
00375 
00380 typedef enum {
00381     NotBinary=0,
00382     UInt=1,
00383     SInt=2,
00384     FPReal=3,
00385     FloatReal=4,
00386     FloatComplex=5
00387 } DDFBinaryFormat;
00388 
00389     DDFBinaryFormat GetBinaryFormat(void) const { return eBinaryFormat; }
00390     
00391 
00392 private:
00393 
00394   char      *pszName;   // a.k.a. subfield mnemonic
00395   char      *pszFormatString; 
00396 
00397   DDFDataType           eType;
00398   DDFBinaryFormat       eBinaryFormat;
00399 
00400 /* -------------------------------------------------------------------- */
00401 /*      bIsVariable determines whether we using the                     */
00402 /*      chFormatDelimeter (TRUE), or the fixed width (FALSE).           */
00403 /* -------------------------------------------------------------------- */
00404   int        bIsVariable;
00405   
00406   char       chFormatDelimeter;
00407   int        nFormatWidth;
00408 
00409 /* -------------------------------------------------------------------- */
00410 /*      Fetched string cache.  This is where we hold the values         */
00411 /*      returned from ExtractStringData().                              */
00412 /* -------------------------------------------------------------------- */
00413   int        nMaxBufChars;
00414   char       *pachBuffer;
00415 };
00416 
00417 /************************************************************************/
00418 /*                              DDFRecord                               */
00419 /*                                                                      */
00420 /*      Class that contains one DR record from a file.  We read into    */
00421 /*      the same record object repeatedly to ensure that repeated       */
00422 /*      leaders can be easily preserved.                                */
00423 /************************************************************************/
00424 
00430 class DDFRecord
00431 {
00432   public:
00433                 DDFRecord( DDFModule * );
00434                 ~DDFRecord();
00435 
00436     DDFRecord  *Clone();
00437     DDFRecord  *CloneOn( DDFModule * );
00438     
00439     void        Dump( FILE * );
00440 
00442     int         GetFieldCount() { return nFieldCount; }
00443 
00444     DDFField    *FindField( const char *, int = 0 );
00445     DDFField    *GetField( int );
00446 
00447     int         GetIntSubfield( const char *, int, const char *, int,
00448                                 int * = NULL );
00449     double      GetFloatSubfield( const char *, int, const char *, int,
00450                                   int * = NULL );
00451     const char *GetStringSubfield( const char *, int, const char *, int,
00452                                    int * = NULL );
00453 
00454     int         SetIntSubfield( const char *pszField, int iFieldIndex, 
00455                                 const char *pszSubfield, int iSubfieldIndex,
00456                                 int nValue );
00457     int         SetStringSubfield( const char *pszField, int iFieldIndex, 
00458                                    const char *pszSubfield, int iSubfieldIndex,
00459                                    const char *pszValue, int nValueLength=-1 );
00460     int         SetFloatSubfield( const char *pszField, int iFieldIndex, 
00461                                   const char *pszSubfield, int iSubfieldIndex,
00462                                   double dfNewValue );
00463 
00465     int         GetDataSize() { return nDataSize; }
00466 
00472     const char  *GetData() { return pachData; }
00473 
00478     DDFModule * GetModule() { return poModule; }
00479 
00480     int ResizeField( DDFField *poField, int nNewDataSize );
00481     int DeleteField( DDFField *poField );
00482     DDFField* AddField( DDFFieldDefn * );
00483 
00484     int CreateDefaultFieldInstance( DDFField *poField, int iIndexWithinField );
00485 
00486     int SetFieldRaw( DDFField *poField, int iIndexWithinField, 
00487                      const char *pachRawData, int nRawDataSize );
00488     int UpdateFieldRaw( DDFField *poField, int iIndexWithinField, 
00489                         int nStartOffset, int nOldSize,
00490                         const char *pachRawData, int nRawDataSize );
00491 
00492     int         Write();
00493     
00494     // This is really just for the DDFModule class.
00495     int         Read();
00496     void        Clear();
00497     int         ResetDirectory();
00498     
00499   private:
00500 
00501     int         ReadHeader();
00502     
00503     DDFModule   *poModule;
00504 
00505     int         nReuseHeader;   
00506 
00507     int         nFieldOffset;   // field data area, not dir entries.
00508 
00509     int         _sizeFieldTag;
00510     int         _sizeFieldPos;
00511     int         _sizeFieldLength;
00512 
00513     int         nDataSize;      // Whole record except leader with header
00514     char        *pachData;
00515 
00516     int         nFieldCount;
00517     DDFField    *paoFields;
00518 
00519     int         bIsClone;
00520 };
00521 
00522 /************************************************************************/
00523 /*                               DDFField                               */
00524 /*                                                                      */
00525 /*      This object represents one field in a DDFRecord.                */
00526 /************************************************************************/
00527 
00537 class DDFField
00538 {
00539   public:
00540     void                Initialize( DDFFieldDefn *, const char *pszData,
00541                                     int nSize );
00542 
00543     void                Dump( FILE * fp );
00544 
00545     const char         *GetSubfieldData( DDFSubfieldDefn *,
00546                                          int * = NULL, int = 0 );
00547 
00548     const char         *GetInstanceData( int nInstance, int *pnSize );
00549 
00554     const char         *GetData() { return pachData; }
00555 
00557     int                 GetDataSize() { return nDataSize; }
00558 
00559     int                 GetRepeatCount();
00560 
00562     DDFFieldDefn        *GetFieldDefn() { return poDefn; }
00563     
00564   private:
00565     DDFFieldDefn        *poDefn;
00566 
00567     int                 nDataSize;
00568 
00569     const char          *pachData;
00570 };
00571 
00572 
00573 #endif /* ndef _ISO8211_H_INCLUDED */

Generated on Mon Oct 6 16:31:38 2003 for SDTS_AL by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002