#ifndef _ISO8211_H_INCLUDED
#define _ISO8211_H_INCLUDED
#include "cpl_port.h"
typedef enum {
DDFInt,
DDFFloat,
DDFString,
DDFBinaryString
} DDFDataType;
/* These should really be private to the library ... they are */
/* mostly conveniences. */
long DDFScanInt( const char *pszString, int nMaxChars );
int DDFScanVariable( const char * pszString, int nMaxChars, int nDelimChar );
char *DDFFetchVariable( const char *pszString, int nMaxChars,
int nDelimChar1, int nDelimChar2,
int *pnConsumedChars );
#define DDF_FIELD_TERMINATOR 30
#define DDF_UNIT_TERMINATOR 31
/* Predeclarations */
class DDFFieldDefn;
class DDFSubfieldDefn;
class DDFRecord;
class DDFField;
/* DDFModule */
class DDFModule
{
public:
DDFModule();
~DDFModule();
int Open( const char * pszFilename );
void Close();
void Dump( FILE * fp );
DDFRecord *ReadRecord( void );
void Rewind( long nOffset = -1 );
DDFFieldDefn *FindFieldDefn( const char * );
int GetFieldCount() { return nFieldDefnCount; }
DDFFieldDefn *GetField(int);
// This is really just for internal use.
int GetFieldControlLength() { return _fieldControlLength; }
void AddCloneRecord( DDFRecord * );
void RemoveCloneRecord( DDFRecord * );
// This is just for DDFRecord.
FILE *GetFP() { return fpDDF; }
private:
FILE *fpDDF;
long nFirstRecordOffset;
char _interchangeLevel;
char _inlineCodeExtensionIndicator;
char _versionNumber;
char _appIndicator;
int _fieldControlLength;
long _recLength;
char _leaderIden;
long _fieldAreaStart;
long _sizeFieldLength;
long _sizeFieldPos;
long _sizeFieldTag;
// One DirEntry per field.
int nFieldDefnCount;
DDFFieldDefn *paoFieldDefns;
DDFRecord *poRecord;
int nCloneCount;
int nMaxCloneCount;
DDFRecord **papoClones;
};
/* DDFFieldDefn */
class DDFFieldDefn
{
public:
DDFFieldDefn();
~DDFFieldDefn();
int Initialize( DDFModule * poModule, const char *pszTag,
int nSize, const char * pachRecord );
void Dump( FILE * fp );
const char *GetName() { return pszTag; }
const char *GetDescription() { return _fieldName; }
int GetSubfieldCount() { return nSubfieldCount; }
DDFSubfieldDefn *GetSubfield( int i );
DDFSubfieldDefn *FindSubfieldDefn( const char * );
int GetFixedWidth() { return nFixedWidth; }
int IsRepeating() { return bRepeatingSubfields; }
typedef enum { elementary, vector, array, concatenated } data_struct_code;
typedef enum { char_string,
implicit_point,
explicit_point,
explicit_point_scaled,
char_bit_string,
bit_string,
mixed_data_type } data_type_code;
private:
DDFModule * poModule;
char * pszTag;
char * _fieldName;
char * _arrayDescr;
char * _formatControls;
int bRepeatingSubfields;
int nFixedWidth; // zero if variable.
int BuildSubfields();
int ApplyFormats();
DDFFieldDefn::data_struct_code _data_struct_code;
DDFFieldDefn::data_type_code _data_type_code;
int nSubfieldCount;
DDFSubfieldDefn *paoSubfields;
};
/* DDFSubfieldDefn */
/* */
/* Information from the DDR record for one subfield of a */
/* particular field. */
class DDFSubfieldDefn
{
public:
DDFSubfieldDefn();
~DDFSubfieldDefn();
void SetName( const char * pszName );
const char *GetName() { return pszName; }
const char *GetFormat() { return pszFormatString; }
int SetFormat( const char * pszFormat );
DDFDataType GetType() { return eType; }
double ExtractFloatData( const char *pachData, int nMaxBytes,
int * pnConsumedBytes );
int ExtractIntData( const char *pachData, int nMaxBytes,
int * pnConsumedBytes );
const char *ExtractStringData( const char *pachData, int nMaxBytes,
int * pnConsumedBytes );
int GetDataLength( const char *, int, int * );
void DumpData( const char *pachData, int nMaxBytes, FILE * fp );
int GetWidth() { return nFormatWidth; } // zero for variable.
void Dump( FILE * fp );
private:
typedef enum {
NotBinary=0,
UInt=1,
SInt=2,
FPReal=3,
FloatReal=4,
FloatComplex=5
} DDFBinaryFormat;
char *pszName; // a.k.a. subfield mnemonic
char *pszFormatString;
DDFDataType eType;
DDFBinaryFormat eBinaryFormat;
/* -------------------------------------------------------------------- */
/* bIsVariable determines whether we using the */
/* chFormatDelimeter (TRUE), or the fixed width (FALSE). */
/* -------------------------------------------------------------------- */
int bIsVariable;
char chFormatDelimeter;
int nFormatWidth;
/* -------------------------------------------------------------------- */
/* Fetched string cache. This is where we hold the values */
/* returned from ExtractStringData(). */
/* -------------------------------------------------------------------- */
int nMaxBufChars;
char *pachBuffer;
};
/* DDFRecord */
/* */
/* Class that contains one DR record from a file. We read into */
/* the same record object repeatedly to ensure that repeated */
/* leaders can be easily preserved. */
class DDFRecord
{
public:
DDFRecord( DDFModule * );
~DDFRecord();
DDFRecord *Clone();
void Dump( FILE * );
int GetFieldCount() { return nFieldCount; }
DDFField *FindField( const char *, int = 0 );
DDFField *GetField( int );
int GetIntSubfield( const char *, int, const char *, int,
int * = NULL );
double GetFloatSubfield( const char *, int, const char *, int,
int * = NULL );
const char *GetStringSubfield( const char *, int, const char *, int,
int * = NULL );
int GetDataSize() { return nDataSize; }
const char *GetData() { return pachData; }
DDFModule * GetModule() { return poModule; }
// This is really just for the DDFModule class.
int Read();
void Clear();
private:
int ReadHeader();
DDFModule *poModule;
int nReuseHeader;
int nFieldOffset; // field data area, not dir entries.
int nDataSize; // Whole record except leader with header
char *pachData;
int nFieldCount;
DDFField *paoFields;
int bIsClone;
};
/* DDFField */
/* */
/* This object represents one field in a DDFRecord. */
class DDFField
{
public:
void Initialize( DDFFieldDefn *, const char *pszData,
int nSize );
void Dump( FILE * fp );
const char *GetSubfieldData( DDFSubfieldDefn *,
int * = NULL, int = 0 );
const char *GetData() { return pachData; }
int GetDataSize() { return nDataSize; }
int GetRepeatCount();
DDFFieldDefn *GetFieldDefn() { return poDefn; }
private:
DDFFieldDefn *poDefn;
int nDataSize;
const char *pachData;
};
#endif /* ndef _ISO8211_H_INCLUDED */