SDTS_AL
iso8211.h
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 
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 
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 
109  int GetFieldCount() { return nFieldDefnCount; }
110  DDFFieldDefn *GetField(int);
111  void AddField( DDFFieldDefn *poNewFDefn );
112 
113  // This is really just for internal use.
114  int GetFieldControlLength() { return _fieldControlLength; }
115  void AddCloneRecord( DDFRecord * );
116  void RemoveCloneRecord( DDFRecord * );
117 
118  // This is just for DDFRecord.
119  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 
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 
195  const char *GetName() { return pszTag; }
196 
200  const char *GetDescription() { return _fieldName; }
201 
203  int GetSubfieldCount() { return nSubfieldCount; }
204 
205  DDFSubfieldDefn *GetSubfield( int i );
206  DDFSubfieldDefn *FindSubfieldDefn( const char * );
207 
215  int GetFixedWidth() { return nFixedWidth; }
216 
222  int IsRepeating() { return bRepeatingSubfields; }
223 
224  static char *ExpandFormat( const char * );
225 
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 
270 class CPL_ODLL DDFSubfieldDefn
271 {
272 public:
273 
274  DDFSubfieldDefn();
275  ~DDFSubfieldDefn();
276 
277  void SetName( const char * pszName );
278 
280  const char *GetName() { return pszName; }
281 
283  const char *GetFormat() { return pszFormatString; }
284  int SetFormat( const char * pszFormat );
285 
294  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 
316  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 
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  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 
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 
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 
412  int GetDataSize() { return nDataSize; }
413 
419  const char *GetData() { return pachData; }
420 
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 
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 
501  const char *GetData() { return pachData; }
502 
504  int GetDataSize() { return nDataSize; }
505 
506  int GetRepeatCount();
507 
509  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 */