ISO8211Lib
iso8211.h
1 /******************************************************************************
2  * $Id: iso8211.h e13dcd4dc171dfeed63f912ba06b9374ce4f3bb2 2018-03-18 21:37:41Z Even 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 
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 int 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 
79 class CPL_ODLL DDFModule
80 {
81  public:
82  DDFModule();
83  ~DDFModule();
84 
85  int Open( const char * pszFilename, int bFailQuietly = FALSE );
86  int Create( const char *pszFilename );
87  void Close();
88 
89  int Initialize( char chInterchangeLevel = '3',
90  char chLeaderIden = 'L',
91  char chCodeExtensionIndicator = 'E',
92  char chVersionNumber = '1',
93  char chAppIndicator = ' ',
94  const char *pszExtendedCharSet = " ! ",
95  int nSizeFieldLength = 3,
96  int nSizeFieldPos = 4,
97  int nSizeFieldTag = 4 );
98 
99  void Dump( FILE * fp );
100 
101  DDFRecord *ReadRecord();
102  void Rewind( long nOffset = -1 );
103 
104  DDFFieldDefn *FindFieldDefn( const char * );
105 
108  int GetFieldCount() const { return nFieldDefnCount; }
109  DDFFieldDefn *GetField(int);
110  void AddField( DDFFieldDefn *poNewFDefn );
111 
112  // This is really just for internal use.
113  int GetFieldControlLength() const { return _fieldControlLength; }
114  void AddCloneRecord( DDFRecord * );
115  void RemoveCloneRecord( DDFRecord * );
116 
117  // This is just for DDFRecord.
118  VSILFILE *GetFP() { return fpDDF; }
119  int GetSizeFieldTag() const { return (int)_sizeFieldTag; }
120 
121  // Advanced uses for 8211dump/8211createfromxml
122  int GetSizeFieldPos() const { return _sizeFieldPos; }
123  int GetSizeFieldLength() const { return _sizeFieldLength; }
124  char GetInterchangeLevel() const { return _interchangeLevel; }
125  char GetLeaderIden() const { return _leaderIden; }
126  char GetCodeExtensionIndicator() const { return _inlineCodeExtensionIndicator; }
127  char GetVersionNumber() const { return _versionNumber; }
128  char GetAppIndicator() const { return _appIndicator; }
129  const char* GetExtendedCharSet() const { return _extendedCharSet; }
130  void SetFieldControlLength(int nVal) { _fieldControlLength = nVal; }
131 
132  private:
133  VSILFILE *fpDDF;
134  int bReadOnly;
135  long nFirstRecordOffset;
136 
137  char _interchangeLevel;
138  char _inlineCodeExtensionIndicator;
139  char _versionNumber;
140  char _appIndicator;
141  int _fieldControlLength;
142  char _extendedCharSet[4];
143 
144  int _recLength;
145  char _leaderIden;
146  int _fieldAreaStart;
147  int _sizeFieldLength;
148  int _sizeFieldPos;
149  int _sizeFieldTag;
150 
151  // One DirEntry per field.
152  int nFieldDefnCount;
153  DDFFieldDefn **papoFieldDefns;
154 
155  DDFRecord *poRecord;
156 
157  int nCloneCount;
158  int nMaxCloneCount;
159  DDFRecord **papoClones;
160 };
161 
162 /************************************************************************/
163 /* DDFFieldDefn */
164 /************************************************************************/
165 
166  typedef enum { dsc_elementary, dsc_vector, dsc_array, dsc_concatenated } DDF_data_struct_code;
167  typedef enum { dtc_char_string,
168  dtc_implicit_point,
169  dtc_explicit_point,
170  dtc_explicit_point_scaled,
171  dtc_char_bit_string,
172  dtc_bit_string,
173  dtc_mixed_data_type } DDF_data_type_code;
174 
182 class CPL_ODLL DDFFieldDefn
183 {
184  public:
185  DDFFieldDefn();
186  ~DDFFieldDefn();
187 
188  int Create( const char *pszTag, const char *pszFieldName,
189  const char *pszDescription,
190  DDF_data_struct_code eDataStructCode,
191  DDF_data_type_code eDataTypeCode,
192  const char *pszFormat = nullptr );
193  void AddSubfield( DDFSubfieldDefn *poNewSFDefn,
194  int bDontAddToFormat = FALSE );
195  void AddSubfield( const char *pszName, const char *pszFormat );
196  int GenerateDDREntry( DDFModule * poModule, char **ppachData, int *pnLength );
197 
198  int Initialize( DDFModule * poModule, const char *pszTag,
199  int nSize, const char * pachRecord );
200 
201  void Dump( FILE * fp );
202 
206  const char *GetName() const { return pszTag; }
207 
211  const char *GetDescription() const { return _fieldName; }
212 
214  int GetSubfieldCount() const { return nSubfieldCount; }
215 
216  DDFSubfieldDefn *GetSubfield( int i );
217  DDFSubfieldDefn *FindSubfieldDefn( const char * );
218 
226  int GetFixedWidth() const { return nFixedWidth; }
227 
233  int IsRepeating() const { return bRepeatingSubfields; }
234 
235  static char *ExpandFormat( const char * );
236 
238  void SetRepeatingFlag( int n ) { bRepeatingSubfields = n; }
239 
240  char *GetDefaultValue( int *pnSize );
241 
242  const char *GetArrayDescr() const { return _arrayDescr; }
243  const char *GetFormatControls() const { return _formatControls; }
244  DDF_data_struct_code GetDataStructCode() const { return _data_struct_code; }
245  DDF_data_type_code GetDataTypeCode() const { return _data_type_code; }
246 
247  void SetFormatControls(const char* pszVal);
248 
249  private:
250 
251  static char *ExtractSubstring( const char * );
252 
253  DDFModule * poModule;
254  char * pszTag;
255 
256  char * _fieldName;
257  char * _arrayDescr;
258  char * _formatControls;
259 
260  int bRepeatingSubfields;
261  int nFixedWidth; // zero if variable.
262 
263  int BuildSubfields();
264  int ApplyFormats();
265 
266  DDF_data_struct_code _data_struct_code;
267 
268  DDF_data_type_code _data_type_code;
269 
270  int nSubfieldCount;
271  DDFSubfieldDefn **papoSubfields;
272 };
273 
274 /************************************************************************/
275 /* DDFSubfieldDefn */
276 /* */
277 /* Information from the DDR record for one subfield of a */
278 /* particular field. */
279 /************************************************************************/
280 
288 class CPL_ODLL DDFSubfieldDefn
289 {
290 public:
291 
292  DDFSubfieldDefn();
293  ~DDFSubfieldDefn();
294 
295  void SetName( const char * pszName );
296 
298  const char *GetName() const { return pszName; }
299 
301  const char *GetFormat() const { return pszFormatString; }
302  int SetFormat( const char * pszFormat );
303 
312  DDFDataType GetType() const { return eType; }
313 
314  double ExtractFloatData( const char *pachData, int nMaxBytes,
315  int * pnConsumedBytes );
316  int ExtractIntData( const char *pachData, int nMaxBytes,
317  int * pnConsumedBytes );
318  const char *ExtractStringData( const char *pachData, int nMaxBytes,
319  int * pnConsumedBytes );
320  int GetDataLength( const char *, int, int * );
321  void DumpData( const char *pachData, int nMaxBytes, FILE * fp );
322 
323  int FormatStringValue( char *pachData, int nBytesAvailable,
324  int *pnBytesUsed, const char *pszValue,
325  int nValueLength = -1 ) const;
326 
327  int FormatIntValue( char *pachData, int nBytesAvailable,
328  int *pnBytesUsed, int nNewValue ) const;
329 
330  int FormatFloatValue( char *pachData, int nBytesAvailable,
331  int *pnBytesUsed, double dfNewValue ) const;
332 
334  int GetWidth() const { return nFormatWidth; } // zero for variable.
335 
336  int GetDefaultValue( char *pachData, int nBytesAvailable,
337  int *pnBytesUsed ) const;
338 
339  void Dump( FILE * fp );
340 
345 typedef enum {
346  NotBinary=0,
347  UInt=1,
348  SInt=2,
349  FPReal=3,
350  FloatReal=4,
351  FloatComplex=5
352 } DDFBinaryFormat;
353 
354  DDFBinaryFormat GetBinaryFormat() const { return eBinaryFormat; }
355 
356 private:
357  char *pszName; // a.k.a. subfield mnemonic
358  char *pszFormatString;
359 
360  DDFDataType eType;
361  DDFBinaryFormat eBinaryFormat;
362 
363 /* -------------------------------------------------------------------- */
364 /* bIsVariable determines whether we using the */
365 /* chFormatDelimiter (TRUE), or the fixed width (FALSE). */
366 /* -------------------------------------------------------------------- */
367  int bIsVariable;
368 
369  char chFormatDelimiter;
370  int nFormatWidth;
371 
372 /* -------------------------------------------------------------------- */
373 /* Fetched string cache. This is where we hold the values */
374 /* returned from ExtractStringData(). */
375 /* -------------------------------------------------------------------- */
376  int nMaxBufChars;
377  char *pachBuffer;
378 };
379 
380 /************************************************************************/
381 /* DDFRecord */
382 /* */
383 /* Class that contains one DR record from a file. We read into */
384 /* the same record object repeatedly to ensure that repeated */
385 /* leaders can be easily preserved. */
386 /************************************************************************/
387 
393 class CPL_ODLL DDFRecord
394 {
395  public:
396  explicit DDFRecord( DDFModule * );
397  ~DDFRecord();
398 
399  DDFRecord *Clone();
400  DDFRecord *CloneOn( DDFModule * );
401 
402  void Dump( FILE * );
403 
405  int GetFieldCount() const { return nFieldCount; }
406 
407  DDFField *FindField( const char *, int = 0 );
408  DDFField *GetField( int );
409 
410  int GetIntSubfield( const char *, int, const char *, int,
411  int * = nullptr );
412  double GetFloatSubfield( const char *, int, const char *, int,
413  int * = nullptr );
414  const char *GetStringSubfield( const char *, int, const char *, int,
415  int * = nullptr );
416 
417  int SetIntSubfield( const char *pszField, int iFieldIndex,
418  const char *pszSubfield, int iSubfieldIndex,
419  int nValue );
420  int SetStringSubfield( const char *pszField, int iFieldIndex,
421  const char *pszSubfield, int iSubfieldIndex,
422  const char *pszValue, int nValueLength=-1 );
423  int SetFloatSubfield( const char *pszField, int iFieldIndex,
424  const char *pszSubfield, int iSubfieldIndex,
425  double dfNewValue );
426 
428  int GetDataSize() const { return nDataSize; }
429 
435  const char *GetData() const { return pachData; }
436 
441  DDFModule * GetModule() { return poModule; }
442 
443  int ResizeField( DDFField *poField, int nNewDataSize );
444  int DeleteField( DDFField *poField );
445  DDFField* AddField( DDFFieldDefn * );
446 
447  int CreateDefaultFieldInstance( DDFField *poField, int iIndexWithinField );
448 
449  int SetFieldRaw( DDFField *poField, int iIndexWithinField,
450  const char *pachRawData, int nRawDataSize );
451  int UpdateFieldRaw( DDFField *poField, int iIndexWithinField,
452  int nStartOffset, int nOldSize,
453  const char *pachRawData, int nRawDataSize );
454 
455  int Write();
456 
457  // Advanced uses for 8211dump/8211createfromxml
458  int GetReuseHeader() const { return nReuseHeader; }
459  int GetSizeFieldTag() const { return _sizeFieldTag; }
460  int GetSizeFieldPos() const { return _sizeFieldPos; }
461  int GetSizeFieldLength() const { return _sizeFieldLength; }
462  //void SetReuseHeader(int bFlag) { nReuseHeader = bFlag; }
463  void SetSizeFieldTag(int nVal) { _sizeFieldTag = nVal; }
464  void SetSizeFieldPos(int nVal) { _sizeFieldPos = nVal; }
465  void SetSizeFieldLength(int nVal) { _sizeFieldLength = nVal; }
466 
467  // This is really just for the DDFModule class.
468  int Read();
469  void Clear();
470  int ResetDirectory();
471  void RemoveIsCloneFlag() { bIsClone = FALSE; }
472 
473  private:
474 
475  int ReadHeader();
476 
477  DDFModule *poModule;
478 
479  int nReuseHeader;
480 
481  int nFieldOffset; // field data area, not dir entries.
482 
483  int _sizeFieldTag;
484  int _sizeFieldPos;
485  int _sizeFieldLength;
486 
487  int nDataSize; // Whole record except leader with header
488  char *pachData;
489 
490  int nFieldCount;
491  DDFField *paoFields;
492 
493  int bIsClone;
494 };
495 
496 /************************************************************************/
497 /* DDFField */
498 /* */
499 /* This object represents one field in a DDFRecord. */
500 /************************************************************************/
501 
511 class CPL_ODLL DDFField
512 {
513  public:
514  DDFField() : poDefn(nullptr), nDataSize(0), pachData(nullptr) {}
515 
516  void Initialize( DDFFieldDefn *, const char *pszData,
517  int nSize );
518 
519  void Dump( FILE * fp );
520 
521  const char *GetSubfieldData( DDFSubfieldDefn *,
522  int * = nullptr, int = 0 );
523 
524  const char *GetInstanceData( int nInstance, int *pnSize );
525 
530  const char *GetData() const { return pachData; }
531 
533  int GetDataSize() const { return nDataSize; }
534 
535  int GetRepeatCount();
536 
538  DDFFieldDefn *GetFieldDefn() { return poDefn; }
539 
540  private:
541  DDFFieldDefn *poDefn;
542 
543  int nDataSize;
544 
545  const char *pachData;
546 };
547 
548 #endif /* ndef ISO8211_H_INCLUDED */
Definition: iso8211.h:183
int IsRepeating() const
Definition: iso8211.h:233
int GetFixedWidth() const
Definition: iso8211.h:226
const char * GetDescription() const
Definition: iso8211.h:211
int GetSubfieldCount() const
Definition: iso8211.h:214
void SetRepeatingFlag(int n)
Definition: iso8211.h:238
const char * GetName() const
Definition: iso8211.h:206
Definition: iso8211.h:512
const char * GetData() const
Definition: iso8211.h:530
int GetDataSize() const
Definition: iso8211.h:533
DDFFieldDefn * GetFieldDefn()
Definition: iso8211.h:538
Definition: iso8211.h:80
int GetFieldCount() const
Definition: iso8211.h:108
Definition: iso8211.h:394
int GetFieldCount() const
Definition: iso8211.h:405
const char * GetData() const
Definition: iso8211.h:435
DDFModule * GetModule()
Definition: iso8211.h:441
int GetDataSize() const
Definition: iso8211.h:428
Definition: iso8211.h:289
DDFDataType GetType() const
Definition: iso8211.h:312
const char * GetFormat() const
Definition: iso8211.h:301
int GetWidth() const
Definition: iso8211.h:334
const char * GetName() const
Definition: iso8211.h:298