LCOV - code coverage report
Current view: directory - frmts/iso8211 - iso8211.h (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 15 13 86.7 %
Date: 2012-04-28 Functions: 15 13 86.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: iso8211.h 20996 2010-10-28 18:38:15Z rouault $
       3                 :  *
       4                 :  * Project:  ISO 8211 Access
       5                 :  * Purpose:  Main declarations for ISO 8211.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #ifndef _ISO8211_H_INCLUDED
      31                 : #define _ISO8211_H_INCLUDED
      32                 : 
      33                 : #include "cpl_port.h"
      34                 : #include "cpl_vsi.h"
      35                 : 
      36                 : /**
      37                 :   General data type
      38                 :     */
      39                 : typedef enum {
      40                 :     DDFInt,
      41                 :     DDFFloat,
      42                 :     DDFString,
      43                 :     DDFBinaryString
      44                 : } DDFDataType;
      45                 :   
      46                 : /************************************************************************/
      47                 : /*      These should really be private to the library ... they are      */
      48                 : /*      mostly conveniences.                                            */
      49                 : /************************************************************************/
      50                 : 
      51                 : long CPL_ODLL DDFScanInt( const char *pszString, int nMaxChars );
      52                 : int  CPL_ODLL DDFScanVariable( const char * pszString, int nMaxChars, int nDelimChar );
      53                 : char CPL_ODLL *DDFFetchVariable( const char *pszString, int nMaxChars,
      54                 :                         int nDelimChar1, int nDelimChar2,
      55                 :                         int *pnConsumedChars );
      56                 : 
      57                 : #define DDF_FIELD_TERMINATOR    30
      58                 : #define DDF_UNIT_TERMINATOR     31
      59                 : 
      60                 : /************************************************************************/
      61                 : /*                           Predeclarations                            */
      62                 : /************************************************************************/
      63                 : 
      64                 : class DDFFieldDefn;
      65                 : class DDFSubfieldDefn;
      66                 : class DDFRecord;
      67                 : class DDFField;
      68                 : 
      69                 : /************************************************************************/
      70                 : /*                              DDFModule                               */
      71                 : /************************************************************************/
      72                 : 
      73                 : /**
      74                 :   The primary class for reading ISO 8211 files.  This class contains all
      75                 :   the information read from the DDR record, and is used to read records
      76                 :   from the file.           
      77                 : 
      78                 : */  
      79                 : 
      80                 : class CPL_ODLL DDFModule
      81                 : {
      82                 :   public:
      83                 :                 DDFModule();
      84                 :                 ~DDFModule();
      85                 :                 
      86                 :     int         Open( const char * pszFilename, int bFailQuietly = FALSE );
      87                 :     int         Create( const char *pszFilename );
      88                 :     void        Close();
      89                 : 
      90                 :     int         Initialize( char chInterchangeLevel = '3',
      91                 :                             char chLeaderIden = 'L', 
      92                 :                             char chCodeExtensionIndicator = 'E',
      93                 :                             char chVersionNumber = '1',
      94                 :                             char chAppIndicator = ' ',
      95                 :                             const char *pszExtendedCharSet = " ! ",
      96                 :                             int nSizeFieldLength = 3,
      97                 :                             int nSizeFieldPos = 4,
      98                 :                             int nSizeFieldTag = 4 );
      99                 : 
     100                 :     void        Dump( FILE * fp );
     101                 : 
     102                 :     DDFRecord   *ReadRecord( void );
     103                 :     void        Rewind( long nOffset = -1 );
     104                 : 
     105                 :     DDFFieldDefn *FindFieldDefn( const char * );
     106                 : 
     107                 :     /** Fetch the number of defined fields. */
     108                 : 
     109                 :     int         GetFieldCount() { return nFieldDefnCount; }
     110                 :     DDFFieldDefn *GetField(int);
     111                 :     void        AddField( DDFFieldDefn *poNewFDefn );
     112                 :     
     113                 :     // This is really just for internal use.
     114            1104 :     int         GetFieldControlLength() { return _fieldControlLength; }
     115                 :     void        AddCloneRecord( DDFRecord * );
     116                 :     void        RemoveCloneRecord( DDFRecord * );
     117                 :     
     118                 :     // This is just for DDFRecord.
     119           98474 :     VSILFILE   *GetFP() { return fpDDF; }
     120                 :     
     121                 :   private:
     122                 :     VSILFILE    *fpDDF;
     123                 :     int         bReadOnly;
     124                 :     long        nFirstRecordOffset;
     125                 : 
     126                 :     char        _interchangeLevel;
     127                 :     char        _inlineCodeExtensionIndicator;
     128                 :     char        _versionNumber;
     129                 :     char        _appIndicator;
     130                 :     int         _fieldControlLength;
     131                 :     char        _extendedCharSet[4];
     132                 : 
     133                 :     long _recLength;
     134                 :     char _leaderIden;
     135                 :     long _fieldAreaStart;
     136                 :     long _sizeFieldLength;
     137                 :     long _sizeFieldPos;
     138                 :     long _sizeFieldTag;
     139                 : 
     140                 :     // One DirEntry per field.  
     141                 :     int         nFieldDefnCount;
     142                 :     DDFFieldDefn **papoFieldDefns;
     143                 : 
     144                 :     DDFRecord   *poRecord;
     145                 : 
     146                 :     int         nCloneCount;
     147                 :     int         nMaxCloneCount;
     148                 :     DDFRecord   **papoClones;
     149                 : };
     150                 : 
     151                 : /************************************************************************/
     152                 : /*                             DDFFieldDefn                             */
     153                 : /************************************************************************/
     154                 : 
     155                 :   typedef enum { dsc_elementary, dsc_vector, dsc_array, dsc_concatenated } DDF_data_struct_code;
     156                 :   typedef enum { dtc_char_string, 
     157                 :                  dtc_implicit_point, 
     158                 :                  dtc_explicit_point, 
     159                 :                  dtc_explicit_point_scaled, 
     160                 :                  dtc_char_bit_string, 
     161                 :                  dtc_bit_string, 
     162                 :                  dtc_mixed_data_type } DDF_data_type_code;
     163                 : 
     164                 : /**
     165                 :  * Information from the DDR defining one field.  Note that just because
     166                 :  * a field is defined for a DDFModule doesn't mean that it actually occurs
     167                 :  * on any records in the module.  DDFFieldDefns are normally just significant
     168                 :  * as containers of the DDFSubfieldDefns.
     169                 :  */
     170                 : 
     171                 : class CPL_ODLL DDFFieldDefn
     172                 : {
     173                 :   public:
     174                 :                 DDFFieldDefn();
     175                 :                 ~DDFFieldDefn();
     176                 : 
     177                 :     int         Create( const char *pszTag, const char *pszFieldName,
     178                 :                         const char *pszDescription,
     179                 :                         DDF_data_struct_code eDataStructCode,
     180                 :                         DDF_data_type_code   eDataTypeCode,
     181                 :                         const char *pszFormat = NULL );
     182                 :     void        AddSubfield( DDFSubfieldDefn *poNewSFDefn,
     183                 :                              int bDontAddToFormat = FALSE );
     184                 :     void        AddSubfield( const char *pszName, const char *pszFormat );
     185                 :     int         GenerateDDREntry( char **ppachData, int *pnLength ); 
     186                 :                             
     187                 :     int         Initialize( DDFModule * poModule, const char *pszTag,
     188                 :                             int nSize, const char * pachRecord );
     189                 :     
     190                 :     void        Dump( FILE * fp );
     191                 : 
     192                 :     /** Fetch a pointer to the field name (tag).
     193                 :      * @return this is an internal copy and shouldn't be freed.
     194                 :      */
     195         2014620 :     const char  *GetName() { return pszTag; }
     196                 : 
     197                 :     /** Fetch a longer descriptio of this field.
     198                 :      * @return this is an internal copy and shouldn't be freed.
     199                 :      */
     200                 :     const char  *GetDescription() { return _fieldName; }
     201                 : 
     202                 :     /** Get the number of subfields. */
     203          282818 :     int         GetSubfieldCount() { return nSubfieldCount; }
     204                 :     
     205                 :     DDFSubfieldDefn *GetSubfield( int i );
     206                 :     DDFSubfieldDefn *FindSubfieldDefn( const char * );
     207                 : 
     208                 :     /**
     209                 :      * Get the width of this field.  This function isn't normally used
     210                 :      * by applications.
     211                 :      *
     212                 :      * @return The width of the field in bytes, or zero if the field is not
     213                 :      * apparently of a fixed width.
     214                 :      */
     215            1158 :     int         GetFixedWidth() { return nFixedWidth; }
     216                 : 
     217                 :     /**
     218                 :      * Fetch repeating flag.
     219                 :      * @see DDFField::GetRepeatCount()
     220                 :      * @return TRUE if the field is marked as repeating.
     221                 :      */
     222             280 :     int         IsRepeating() { return bRepeatingSubfields; }
     223                 : 
     224                 :     static char       *ExpandFormat( const char * );
     225                 : 
     226                 :     /** this is just for an S-57 hack for swedish data */
     227                 :     void SetRepeatingFlag( int n ) { bRepeatingSubfields = n; }
     228                 : 
     229                 :     char        *GetDefaultValue( int *pnSize );
     230                 :     
     231                 :   private:
     232                 : 
     233                 :     static char       *ExtractSubstring( const char * );
     234                 : 
     235                 :     DDFModule * poModule;
     236                 :     char *      pszTag;
     237                 : 
     238                 :     char *      _fieldName;
     239                 :     char *      _arrayDescr;
     240                 :     char *      _formatControls;
     241                 : 
     242                 :     int         bRepeatingSubfields;
     243                 :     int         nFixedWidth;    // zero if variable. 
     244                 : 
     245                 :     int         BuildSubfields();
     246                 :     int         ApplyFormats();
     247                 : 
     248                 :     DDF_data_struct_code _data_struct_code;
     249                 : 
     250                 :     DDF_data_type_code   _data_type_code;
     251                 : 
     252                 :     int         nSubfieldCount;
     253                 :     DDFSubfieldDefn **papoSubfields;
     254                 : };
     255                 : 
     256                 : /************************************************************************/
     257                 : /*                           DDFSubfieldDefn                            */
     258                 : /*                                                                      */
     259                 : /*      Information from the DDR record for one subfield of a           */
     260                 : /*      particular field.                                               */
     261                 : /************************************************************************/
     262                 : 
     263                 : /**
     264                 :  * Information from the DDR record describing one subfield of a DDFFieldDefn.
     265                 :  * All subfields of a field will occur in each occurance of that field
     266                 :  * (as a DDFField) in a DDFRecord.  Subfield's actually contain formatted
     267                 :  * data (as instances within a record).
     268                 :  */
     269                 : 
     270                 : class CPL_ODLL DDFSubfieldDefn
     271                 : {
     272                 : public:
     273                 : 
     274                 :                 DDFSubfieldDefn();
     275                 :                 ~DDFSubfieldDefn();
     276                 : 
     277                 :     void        SetName( const char * pszName );
     278                 : 
     279                 :     /** Get pointer to subfield name. */
     280          226042 :     const char  *GetName() { return pszName; }
     281                 :     
     282                 :     /** Get pointer to subfield format string */
     283             486 :     const char  *GetFormat() { return pszFormatString; }
     284                 :     int         SetFormat( const char * pszFormat );
     285                 : 
     286                 :     /**
     287                 :      * Get the general type of the subfield.  This can be used to
     288                 :      * determine which of ExtractFloatData(), ExtractIntData() or
     289                 :      * ExtractStringData() should be used.
     290                 :      * @return The subfield type.  One of DDFInt, DDFFloat, DDFString or
     291                 :      * DDFBinaryString.
     292                 :      */
     293                 :       
     294            5792 :     DDFDataType GetType() { return eType; }
     295                 : 
     296                 :     double      ExtractFloatData( const char *pachData, int nMaxBytes,
     297                 :                                   int * pnConsumedBytes );
     298                 :     int         ExtractIntData( const char *pachData, int nMaxBytes,
     299                 :                                 int * pnConsumedBytes );
     300                 :     const char  *ExtractStringData( const char *pachData, int nMaxBytes,
     301                 :                                     int * pnConsumedBytes );
     302                 :     int         GetDataLength( const char *, int, int * );
     303                 :     void        DumpData( const char *pachData, int nMaxBytes, FILE * fp );
     304                 : 
     305                 :     int         FormatStringValue( char *pachData, int nBytesAvailable, 
     306                 :                                    int *pnBytesUsed, const char *pszValue, 
     307                 :                                    int nValueLength = -1 );
     308                 : 
     309                 :     int         FormatIntValue( char *pachData, int nBytesAvailable, 
     310                 :                                 int *pnBytesUsed, int nNewValue );
     311                 : 
     312                 :     int         FormatFloatValue( char *pachData, int nBytesAvailable, 
     313                 :                                   int *pnBytesUsed, double dfNewValue );
     314                 : 
     315                 :     /** Get the subfield width (zero for variable). */
     316           11364 :     int         GetWidth() { return nFormatWidth; } // zero for variable.
     317                 : 
     318                 :     int         GetDefaultValue( char *pachData, int nBytesAvailable, 
     319                 :                                  int *pnBytesUsed );
     320                 :     
     321                 :     void        Dump( FILE * fp );
     322                 : 
     323                 : /**
     324                 :   Binary format: this is the digit immediately following the B or b for
     325                 :   binary formats. 
     326                 :   */
     327                 : typedef enum {
     328                 :     NotBinary=0,
     329                 :     UInt=1,
     330                 :     SInt=2,
     331                 :     FPReal=3,
     332                 :     FloatReal=4,
     333                 :     FloatComplex=5
     334                 : } DDFBinaryFormat;
     335                 : 
     336               0 :     DDFBinaryFormat GetBinaryFormat(void) const { return eBinaryFormat; }
     337                 :     
     338                 : 
     339                 : private:
     340                 : 
     341                 :   char      *pszName;   // a.k.a. subfield mnemonic
     342                 :   char      *pszFormatString; 
     343                 : 
     344                 :   DDFDataType           eType;
     345                 :   DDFBinaryFormat       eBinaryFormat;
     346                 : 
     347                 : /* -------------------------------------------------------------------- */
     348                 : /*      bIsVariable determines whether we using the                     */
     349                 : /*      chFormatDelimeter (TRUE), or the fixed width (FALSE).           */
     350                 : /* -------------------------------------------------------------------- */
     351                 :   int        bIsVariable;
     352                 :   
     353                 :   char       chFormatDelimeter;
     354                 :   int        nFormatWidth;
     355                 : 
     356                 : /* -------------------------------------------------------------------- */
     357                 : /*      Fetched string cache.  This is where we hold the values         */
     358                 : /*      returned from ExtractStringData().                              */
     359                 : /* -------------------------------------------------------------------- */
     360                 :   int        nMaxBufChars;
     361                 :   char       *pachBuffer;
     362                 : };
     363                 : 
     364                 : /************************************************************************/
     365                 : /*                              DDFRecord                               */
     366                 : /*                                                                      */
     367                 : /*      Class that contains one DR record from a file.  We read into    */
     368                 : /*      the same record object repeatedly to ensure that repeated       */
     369                 : /*      leaders can be easily preserved.                                */
     370                 : /************************************************************************/
     371                 : 
     372                 : /**
     373                 :  * Contains instance data from one data record (DR).  The data is contained
     374                 :  * as a list of DDFField instances partitioning the raw data into fields.
     375                 :  */
     376                 : 
     377                 : class CPL_ODLL DDFRecord
     378                 : {
     379                 :   public:
     380                 :                 DDFRecord( DDFModule * );
     381                 :                 ~DDFRecord();
     382                 : 
     383                 :     DDFRecord  *Clone();
     384                 :     DDFRecord  *CloneOn( DDFModule * );
     385                 :     
     386                 :     void        Dump( FILE * );
     387                 : 
     388                 :     /** Get the number of DDFFields on this record. */
     389                 :     int         GetFieldCount() { return nFieldCount; }
     390                 : 
     391                 :     DDFField    *FindField( const char *, int = 0 );
     392                 :     DDFField    *GetField( int );
     393                 : 
     394                 :     int         GetIntSubfield( const char *, int, const char *, int,
     395                 :                                 int * = NULL );
     396                 :     double      GetFloatSubfield( const char *, int, const char *, int,
     397                 :                                   int * = NULL );
     398                 :     const char *GetStringSubfield( const char *, int, const char *, int,
     399                 :                                    int * = NULL );
     400                 : 
     401                 :     int         SetIntSubfield( const char *pszField, int iFieldIndex, 
     402                 :                                 const char *pszSubfield, int iSubfieldIndex,
     403                 :                                 int nValue );
     404                 :     int         SetStringSubfield( const char *pszField, int iFieldIndex, 
     405                 :                                    const char *pszSubfield, int iSubfieldIndex,
     406                 :                                    const char *pszValue, int nValueLength=-1 );
     407                 :     int         SetFloatSubfield( const char *pszField, int iFieldIndex, 
     408                 :                                   const char *pszSubfield, int iSubfieldIndex,
     409                 :                                   double dfNewValue );
     410                 : 
     411                 :     /** Fetch size of records raw data (GetData()) in bytes. */
     412                 :     int         GetDataSize() { return nDataSize; }
     413                 : 
     414                 :     /**
     415                 :      * Fetch the raw data for this record.  The returned pointer is effectively
     416                 :      * to the data for the first field of the record, and is of size 
     417                 :      * GetDataSize().
     418                 :      */
     419               0 :     const char  *GetData() { return pachData; }
     420                 : 
     421                 :     /**
     422                 :      * Fetch the DDFModule with which this record is associated.
     423                 :      */
     424                 : 
     425                 :     DDFModule * GetModule() { return poModule; }
     426                 : 
     427                 :     int ResizeField( DDFField *poField, int nNewDataSize );
     428                 :     int DeleteField( DDFField *poField );
     429                 :     DDFField* AddField( DDFFieldDefn * );
     430                 : 
     431                 :     int CreateDefaultFieldInstance( DDFField *poField, int iIndexWithinField );
     432                 : 
     433                 :     int SetFieldRaw( DDFField *poField, int iIndexWithinField, 
     434                 :                      const char *pachRawData, int nRawDataSize );
     435                 :     int UpdateFieldRaw( DDFField *poField, int iIndexWithinField, 
     436                 :                         int nStartOffset, int nOldSize,
     437                 :                         const char *pachRawData, int nRawDataSize );
     438                 : 
     439                 :     int         Write();
     440                 :     
     441                 :     // This is really just for the DDFModule class.
     442                 :     int         Read();
     443                 :     void        Clear();
     444                 :     int         ResetDirectory();
     445                 :     
     446                 :   private:
     447                 : 
     448                 :     int         ReadHeader();
     449                 :     
     450                 :     DDFModule   *poModule;
     451                 : 
     452                 :     int         nReuseHeader;   
     453                 : 
     454                 :     int         nFieldOffset;   // field data area, not dir entries.
     455                 : 
     456                 :     int         _sizeFieldTag;
     457                 :     int         _sizeFieldPos;
     458                 :     int         _sizeFieldLength;
     459                 : 
     460                 :     int         nDataSize;      // Whole record except leader with header
     461                 :     char        *pachData;
     462                 : 
     463                 :     int         nFieldCount;
     464                 :     DDFField    *paoFields;
     465                 : 
     466                 :     int         bIsClone;
     467                 : };
     468                 : 
     469                 : /************************************************************************/
     470                 : /*                               DDFField                               */
     471                 : /*                                                                      */
     472                 : /*      This object represents one field in a DDFRecord.                */
     473                 : /************************************************************************/
     474                 : 
     475                 : /**
     476                 :  * This object represents one field in a DDFRecord.  This
     477                 :  * models an instance of the fields data, rather than it's data definition
     478                 :  * which is handled by the DDFFieldDefn class.  Note that a DDFField
     479                 :  * doesn't have DDFSubfield children as you would expect.  To extract
     480                 :  * subfield values use GetSubfieldData() to find the right data pointer and
     481                 :  * then use ExtractIntData(), ExtractFloatData() or ExtractStringData().
     482                 :  */
     483                 : 
     484                 : class CPL_ODLL DDFField
     485                 : {
     486                 :   public:
     487                 :     void                Initialize( DDFFieldDefn *, const char *pszData,
     488                 :                                     int nSize );
     489                 : 
     490                 :     void                Dump( FILE * fp );
     491                 : 
     492                 :     const char         *GetSubfieldData( DDFSubfieldDefn *,
     493                 :                                          int * = NULL, int = 0 );
     494                 : 
     495                 :     const char         *GetInstanceData( int nInstance, int *pnSize );
     496                 : 
     497                 :     /**
     498                 :      * Return the pointer to the entire data block for this record. This
     499                 :      * is an internal copy, and shouldn't be freed by the application.
     500                 :      */
     501          180362 :     const char         *GetData() { return pachData; }
     502                 : 
     503                 :     /** Return the number of bytes in the data block returned by GetData(). */
     504          178852 :     int                 GetDataSize() { return nDataSize; }
     505                 : 
     506                 :     int                 GetRepeatCount();
     507                 : 
     508                 :     /** Fetch the corresponding DDFFieldDefn. */
     509          548102 :     DDFFieldDefn        *GetFieldDefn() { return poDefn; }
     510                 :     
     511                 :   private:
     512                 :     DDFFieldDefn        *poDefn;
     513                 : 
     514                 :     int                 nDataSize;
     515                 : 
     516                 :     const char          *pachData;
     517                 : };
     518                 : 
     519                 : 
     520                 : #endif /* ndef _ISO8211_H_INCLUDED */

Generated by: LCOV version 1.7