www.pudn.com > mitab-1.5.1.zip > mitab_priv.h
/**********************************************************************
* $Id: mitab_priv.h,v 1.40 2005/10/06 19:15:31 dmorissette Exp $
*
* Name: mitab_priv.h
* Project: MapInfo TAB Read/Write library
* Language: C++
* Purpose: Header file containing private definitions for the library.
* Author: Daniel Morissette, dmorissette@dmsolutions.ca
*
**********************************************************************
* Copyright (c) 1999-2003, Daniel Morissette
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
**********************************************************************
*
* $Log: mitab_priv.h,v $
* Revision 1.40 2005/10/06 19:15:31 dmorissette
* Collections: added support for reading/writing pen/brush/symbol ids and
* for writing collection objects to .TAB/.MAP (bug 1126)
*
* Revision 1.39 2005/10/04 15:44:31 dmorissette
* First round of support for Collection objects. Currently supports reading
* from .TAB/.MAP and writing to .MIF. Still lacks symbol support and write
* support. (Based in part on patch and docs from Jim Hope, bug 1126)
*
* Revision 1.38 2005/03/22 23:24:54 dmorissette
* Added support for datum id in .MAP header (bug 910)
*
* Revision 1.37 2004/06/30 20:29:04 dmorissette
* Fixed refs to old address danmo@videotron.ca
*
* Revision 1.36 2003/08/12 23:17:21 dmorissette
* Added reading of v500+ coordsys affine params (Anthony D. - Encom)
*
* Revision 1.35 2003/01/18 20:25:44 daniel
* Increased MIDMAXCHAR value to 10000
*
* Revision 1.34 2002/04/25 16:05:24 julien
* Disabled the overflow warning in SetCoordFilter() by adding bIgnoreOverflow
* variable in Coordsys2Int of the TABMAPFile class and TABMAPHeaderBlock class
*
* Revision 1.33 2002/04/22 13:49:09 julien
* Add EOF validation in MIDDATAFile::GetLastLine() (Bug 819)
*
* Revision 1.32 2002/03/26 19:27:43 daniel
* Got rid of tabs in source
*
* Revision 1.31 2002/03/26 01:48:40 daniel
* Added Multipoint object type (V650)
*
* Revision 1.30 2002/02/22 20:44:51 julien
* Prevent infinite loop with TABRelation by suppress the m_poCurFeature object
* from the class and setting it in the calling function and add GetFeature in
* the class. (bug 706)
*
* Revision 1.29 2001/11/19 15:07:54 daniel
* Added TABMAPObjNone to handle the case of TAB_GEOM_NONE
*
* Revision 1.28 2001/11/17 21:54:06 daniel
* Made several changes in order to support writing objects in 16 bits
* coordinate format. New TABMAPObjHdr-derived classes are used to hold
* object info in mem until block is full.
*
* Revision 1.27 2001/09/18 20:33:52 warmerda
* fixed case of spatial search on file with just one object block
*
* Revision 1.26 2001/09/14 03:23:55 warmerda
* Substantial upgrade to support spatial queries using spatial indexes
*
* Revision 1.25 2001/05/01 18:28:10 daniel
* Fixed default BRUSH, should be BRUSH(1,0,16777215).
*
* Revision 1.24 2001/05/01 03:39:51 daniel
* Added SetLastPtr() to TABBinBlockManager.
*
* Revision 1.23 2001/03/15 03:57:51 daniel
* Added implementation for new OGRLayer::GetExtent(), returning data MBR.
*
* Revision 1.22 2000/11/23 21:11:07 daniel
* OOpps... VC++ didn't like the way TABPenDef, etc. were initialized
*
* Revision 1.21 2000/11/23 20:47:46 daniel
* Use MI defaults for Pen, Brush, Font, Symbol instead of all zeros
*
* Revision 1.20 2000/11/15 04:13:50 daniel
* Fixed writing of TABMAPToolBlock to allocate a new block when full
*
* Revision 1.19 2000/11/13 22:19:30 daniel
* Added TABINDNode::UpdateCurChildEntry()
*
* Revision 1.18 2000/05/19 06:45:25 daniel
* Modified generation of spatial index to split index nodes and produce a
* more balanced tree.
*
* Revision 1.17 2000/03/01 00:30:03 daniel
* Completed support for joined tables
*
* Revision 1.16 2000/02/28 16:53:23 daniel
* Added support for indexed, unique, and for new V450 object types
*
* ...
*
* Revision 1.1 1999/07/12 04:18:25 daniel
* Initial checkin
*
**********************************************************************/
#ifndef _MITAB_PRIV_H_INCLUDED_
#define _MITAB_PRIV_H_INCLUDED_
#include "cpl_conv.h"
#include "cpl_string.h"
#include "ogr_feature.h"
class TABFile;
class TABFeature;
class TABMAPToolBlock;
class TABMAPIndexBlock;
/*---------------------------------------------------------------------
* Access mode: Read or Write
*--------------------------------------------------------------------*/
typedef enum
{
TABRead,
TABWrite,
TABReadWrite /* ReadWrite not implemented yet */
} TABAccess;
/*---------------------------------------------------------------------
* Supported .MAP block types (the first byte at the beginning of a block)
*--------------------------------------------------------------------*/
#define TAB_RAWBIN_BLOCK -1
#define TABMAP_HEADER_BLOCK 0
#define TABMAP_INDEX_BLOCK 1
#define TABMAP_OBJECT_BLOCK 2
#define TABMAP_COORD_BLOCK 3
#define TABMAP_GARB_BLOCK 4
#define TABMAP_TOOL_BLOCK 5
#define TABMAP_LAST_VALID_BLOCK_TYPE 5
/*---------------------------------------------------------------------
* Drawing Tool types
*--------------------------------------------------------------------*/
#define TABMAP_TOOL_PEN 1
#define TABMAP_TOOL_BRUSH 2
#define TABMAP_TOOL_FONT 3
#define TABMAP_TOOL_SYMBOL 4
/*---------------------------------------------------------------------
* Limits related to .TAB version number. If we pass any of those limits
* then we have to switch dataset version up from 300 to 450
*--------------------------------------------------------------------*/
#define TAB_300_MAX_VERTICES 32767
/*---------------------------------------------------------------------
* struct TABMAPIndexEntry - Entries found in type 1 blocks of .MAP files
*
* We will use this struct to rebuild the geographic index in memory
*--------------------------------------------------------------------*/
typedef struct TABMAPIndexEntry_t
{
// These members refer to the info we find in the file
GInt32 XMin;
GInt32 YMin;
GInt32 XMax;
GInt32 YMax;
GInt32 nBlockPtr;
}TABMAPIndexEntry;
#define TAB_MAX_ENTRIES_INDEX_BLOCK ((512-4)/20)
/*---------------------------------------------------------------------
* TABVertex
*--------------------------------------------------------------------*/
typedef struct TABVertex_t
{
double x;
double y;
} TABVertex;
/*---------------------------------------------------------------------
* TABTableType - Attribute table format
*--------------------------------------------------------------------*/
typedef enum
{
TABTableNative, // The default
TABTableDBF,
TABTableAccess
} TABTableType;
/*---------------------------------------------------------------------
* TABFieldType - Native MapInfo attribute field types
*--------------------------------------------------------------------*/
typedef enum
{
TABFUnknown = 0,
TABFChar,
TABFInteger,
TABFSmallInt,
TABFDecimal,
TABFFloat,
TABFDate,
TABFLogical
} TABFieldType;
#define TABFIELDTYPE_2_STRING(type) \
(type == TABFChar ? "Char" : \
type == TABFInteger ? "Integer" : \
type == TABFSmallInt ? "SmallInt" : \
type == TABFDecimal ? "Decimal" : \
type == TABFFloat ? "Float" : \
type == TABFDate ? "Date" : \
type == TABFLogical ? "Logical" : \
"Unknown field type" )
/*---------------------------------------------------------------------
* TABDATFieldDef
*--------------------------------------------------------------------*/
typedef struct TABDATFieldDef_t
{
char szName[11];
char cType;
GByte byLength;
GByte byDecimals;
TABFieldType eTABType;
} TABDATFieldDef;
/*---------------------------------------------------------------------
* TABMAPCoordSecHdr
* struct used in the TABMAPCoordBlock to store info about the coordinates
* for a section of a PLINE MULTIPLE or a REGION.
*--------------------------------------------------------------------*/
typedef struct TABMAPCoordSecHdr_t
{
GInt32 numVertices;
GInt16 numHoles;
GInt32 nXMin;
GInt32 nYMin;
GInt32 nXMax;
GInt32 nYMax;
GInt32 nDataOffset;
int nVertexOffset;
} TABMAPCoordSecHdr;
/*---------------------------------------------------------------------
* TABProjInfo
* struct used to store the projection parameters from the .MAP header
*--------------------------------------------------------------------*/
typedef struct TABProjInfo_t
{
GByte nProjId; // See MapInfo Ref. Manual, App. F and G
GByte nEllipsoidId;
GByte nUnitsId;
double adProjParams[6]; // params in same order as in .MIF COORDSYS
GInt16 nDatumId; // Datum Id added in MapInfo 7.8+ (.map V500)
double dDatumShiftX; // Before that, we had to always lookup datum
double dDatumShiftY; // parameters to establish datum id
double dDatumShiftZ;
double adDatumParams[5];
// Affine parameters only in .map version 500 and up
GByte nAffineFlag; // 0=No affine param, 1=Affine params
GByte nAffineUnits;
double dAffineParamA; // Affine params
double dAffineParamB;
double dAffineParamC;
double dAffineParamD;
double dAffineParamE;
double dAffineParamF;
} TABProjInfo;
/*---------------------------------------------------------------------
* TABPenDef - Pen definition information
*--------------------------------------------------------------------*/
typedef struct TABPenDef_t
{
GInt32 nRefCount;
GByte nPixelWidth;
GByte nLinePattern;
int nPointWidth;
GInt32 rgbColor;
} TABPenDef;
/* MI Default = PEN(1,2,0) */
#define MITAB_PEN_DEFAULT {0, 1, 2, 0, 0x000000}
/*---------------------------------------------------------------------
* TABBrushDef - Brush definition information
*--------------------------------------------------------------------*/
typedef struct TABBrushDef_t
{
GInt32 nRefCount;
GByte nFillPattern;
GByte bTransparentFill; // 1 = Transparent
GInt32 rgbFGColor;
GInt32 rgbBGColor;
} TABBrushDef;
/* MI Default = BRUSH(1,0,16777215) */
#define MITAB_BRUSH_DEFAULT {0, 1, 0, 0, 0xffffff}
/*---------------------------------------------------------------------
* TABFontDef - Font Name information
*--------------------------------------------------------------------*/
typedef struct TABFontDef_t
{
GInt32 nRefCount;
char szFontName[33];
} TABFontDef;
/* MI Default = FONT("Arial",0,0,0) */
#define MITAB_FONT_DEFAULT {0, "Arial"}
/*---------------------------------------------------------------------
* TABSymbolDef - Symbol definition information
*--------------------------------------------------------------------*/
typedef struct TABSymbolDef_t
{
GInt32 nRefCount;
GInt16 nSymbolNo;
GInt16 nPointSize;
GByte _nUnknownValue_;// Style???
GInt32 rgbColor;
} TABSymbolDef;
/* MI Default = SYMBOL(35,0,12) */
#define MITAB_SYMBOL_DEFAULT {0, 35, 12, 0, 0x000000}
/*---------------------------------------------------------------------
* class TABToolDefTable
*
* Class to handle the list of Drawing Tool Definitions for a dataset
*
* This class also contains methods to read tool defs from the file and
* write them to the file.
*--------------------------------------------------------------------*/
class TABToolDefTable
{
protected:
TABPenDef **m_papsPen;
int m_numPen;
int m_numAllocatedPen;
TABBrushDef **m_papsBrush;
int m_numBrushes;
int m_numAllocatedBrushes;
TABFontDef **m_papsFont;
int m_numFonts;
int m_numAllocatedFonts;
TABSymbolDef **m_papsSymbol;
int m_numSymbols;
int m_numAllocatedSymbols;
public:
TABToolDefTable();
~TABToolDefTable();
int ReadAllToolDefs(TABMAPToolBlock *poToolBlock);
int WriteAllToolDefs(TABMAPToolBlock *poToolBlock);
TABPenDef *GetPenDefRef(int nIndex);
int AddPenDefRef(TABPenDef *poPenDef);
int GetNumPen();
TABBrushDef *GetBrushDefRef(int nIndex);
int AddBrushDefRef(TABBrushDef *poBrushDef);
int GetNumBrushes();
TABFontDef *GetFontDefRef(int nIndex);
int AddFontDefRef(TABFontDef *poFontDef);
int GetNumFonts();
TABSymbolDef *GetSymbolDefRef(int nIndex);
int AddSymbolDefRef(TABSymbolDef *poSymbolDef);
int GetNumSymbols();
int GetMinVersionNumber();
};
/*=====================================================================
Classes to handle Object Headers inside TABMAPObjectBlocks
=====================================================================*/
class TABMAPObjectBlock;
class TABMAPHeaderBlock;
class TABMAPObjHdr
{
public:
GByte m_nType;
GInt32 m_nId;
GInt32 m_nMinX; /* Object MBR */
GInt32 m_nMinY;
GInt32 m_nMaxX;
GInt32 m_nMaxY;
TABMAPObjHdr() {};
virtual ~TABMAPObjHdr() {};
static TABMAPObjHdr *NewObj(GByte nNewObjType, GInt32 nId=0);
static TABMAPObjHdr *ReadNextObj(TABMAPObjectBlock *poObjBlock,
TABMAPHeaderBlock *poHeader);
GBool IsCompressedType();
int WriteObjTypeAndId(TABMAPObjectBlock *);
void SetMBR(GInt32 nMinX, GInt32 nMinY, GInt32 nMaxX, GInt32 mMaxY);
virtual int WriteObj(TABMAPObjectBlock *) {return -1;};
// protected:
virtual int ReadObj(TABMAPObjectBlock *) {return -1;};
};
class TABMAPObjHdrWithCoord: public TABMAPObjHdr
{
public:
GInt32 m_nCoordBlockPtr;
GInt32 m_nCoordDataSize;
/* Eventually this class may have methods to help maintaining refs to
* coord. blocks when splitting object blocks.
*/
};
class TABMAPObjNone: public TABMAPObjHdr
{
public:
TABMAPObjNone() {};
virtual ~TABMAPObjNone() {};
virtual int WriteObj(TABMAPObjectBlock *) {return 0;};
// protected:
virtual int ReadObj(TABMAPObjectBlock *) {return 0;};
};
class TABMAPObjPoint: public TABMAPObjHdr
{
public:
GInt32 m_nX;
GInt32 m_nY;
GByte m_nSymbolId;
TABMAPObjPoint() {};
virtual ~TABMAPObjPoint() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjFontPoint: public TABMAPObjPoint
{
public:
GByte m_nPointSize;
GInt16 m_nFontStyle;
GByte m_nR;
GByte m_nG;
GByte m_nB;
GInt16 m_nAngle; /* In tenths of degree */
GByte m_nFontId;
TABMAPObjFontPoint() {};
virtual ~TABMAPObjFontPoint() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjCustomPoint: public TABMAPObjPoint
{
public:
GByte m_nUnknown_;
GByte m_nCustomStyle;
GByte m_nFontId;
TABMAPObjCustomPoint() {};
virtual ~TABMAPObjCustomPoint() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjLine: public TABMAPObjHdr
{
public:
GInt32 m_nX1;
GInt32 m_nY1;
GInt32 m_nX2;
GInt32 m_nY2;
GByte m_nPenId;
TABMAPObjLine() {};
virtual ~TABMAPObjLine() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjPLine: public TABMAPObjHdrWithCoord
{
public:
GInt16 m_numLineSections; /* MULTIPLINE/REGION only. Not in PLINE */
GInt32 m_nLabelX; /* Centroid/label location */
GInt32 m_nLabelY;
GInt32 m_nComprOrgX; /* Present only in compressed coord. case */
GInt32 m_nComprOrgY;
GByte m_nPenId;
GByte m_nBrushId;
GBool m_bSmooth; /* TRUE if (m_nCoordDataSize & 0x80000000) */
TABMAPObjPLine() {};
virtual ~TABMAPObjPLine() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjRectEllipse: public TABMAPObjHdr
{
public:
GInt32 m_nCornerWidth; /* For rounded rect only */
GInt32 m_nCornerHeight;
GByte m_nPenId;
GByte m_nBrushId;
TABMAPObjRectEllipse() {};
virtual ~TABMAPObjRectEllipse() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjArc: public TABMAPObjHdr
{
public:
GInt32 m_nStartAngle;
GInt32 m_nEndAngle;
GInt32 m_nArcEllipseMinX; /* MBR of the arc defining ellipse */
GInt32 m_nArcEllipseMinY; /* Only present in arcs */
GInt32 m_nArcEllipseMaxX;
GInt32 m_nArcEllipseMaxY;
GByte m_nPenId;
TABMAPObjArc() {};
virtual ~TABMAPObjArc() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjText: public TABMAPObjHdrWithCoord
{
public:
/* String and its len stored in the nCoordPtr and nCoordSize */
GInt16 m_nTextAlignment;
GInt32 m_nAngle;
GInt16 m_nFontStyle;
GByte m_nFGColorR;
GByte m_nFGColorG;
GByte m_nFGColorB;
GByte m_nBGColorR;
GByte m_nBGColorG;
GByte m_nBGColorB;
GInt32 m_nLineEndX;
GInt32 m_nLineEndY;
GInt32 m_nHeight;
GByte m_nFontId;
GByte m_nPenId;
TABMAPObjText() {};
virtual ~TABMAPObjText() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjMultiPoint: public TABMAPObjHdrWithCoord
{
public:
GInt32 m_nNumPoints;
GInt32 m_nComprOrgX; /* Present only in compressed coord. case */
GInt32 m_nComprOrgY;
GByte m_nSymbolId;
GInt32 m_nLabelX; /* Not sure if it's a label point, but */
GInt32 m_nLabelY; /* it's similar to what we find in PLINE */
TABMAPObjMultiPoint() {};
virtual ~TABMAPObjMultiPoint() {};
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
};
class TABMAPObjCollection: public TABMAPObjHdrWithCoord
{
public:
GInt32 m_nRegionDataSize;
GInt32 m_nPolylineDataSize;
GInt32 m_nMPointDataSize;
GInt32 m_nComprOrgX; /* Present only in compressed coord. case */
GInt32 m_nComprOrgY;
GInt32 m_nNumMultiPoints;
GInt16 m_nNumRegSections;
GInt16 m_nNumPLineSections;
GInt32 m_nTotalRegDataSize;
GInt32 m_nTotalPolyDataSize;
GByte m_nMultiPointSymbolId;
GByte m_nRegionPenId;
GByte m_nRegionBrushId;
GByte m_nPolylinePenId;
TABMAPObjCollection() {};
virtual ~TABMAPObjCollection()
{}
virtual int WriteObj(TABMAPObjectBlock *);
// protected:
virtual int ReadObj(TABMAPObjectBlock *);
private:
// private copy ctor and assignment operator to prevent shallow copying
TABMAPObjCollection& operator=(const TABMAPObjCollection& rhs);
TABMAPObjCollection(const TABMAPObjCollection& rhs);
};
/*=====================================================================
Classes to handle .MAP files low-level blocks
=====================================================================*/
/*---------------------------------------------------------------------
* class TABBinBlockManager
*
* This class is used to keep track of allocated blocks and is used
* by various classes that need to allocate a new block in a .MAP file.
*--------------------------------------------------------------------*/
class TABBinBlockManager
{
protected:
int m_nBlockSize;
GInt32 m_nLastAllocatedBlock;
public:
TABBinBlockManager(int nBlockSize=512) {m_nBlockSize=nBlockSize;
m_nLastAllocatedBlock = -1; };
~TABBinBlockManager() {};
GInt32 AllocNewBlock() {if (m_nLastAllocatedBlock==-1)
m_nLastAllocatedBlock = 0;
else
m_nLastAllocatedBlock+=m_nBlockSize;
return m_nLastAllocatedBlock; };
void Reset() {m_nLastAllocatedBlock=-1; };
void SetLastPtr(int nBlockPtr) {m_nLastAllocatedBlock=nBlockPtr; };
};
/*---------------------------------------------------------------------
* class TABRawBinBlock
*
* This is the base class used for all other data block types... it
* contains all the base functions to handle binary data.
*--------------------------------------------------------------------*/
class TABRawBinBlock
{
protected:
FILE *m_fp; /* Associated file handle */
TABAccess m_eAccess; /* Read/Write access mode */
int m_nBlockType;
GByte *m_pabyBuf; /* Buffer to contain the block's data */
int m_nBlockSize; /* Size of current block (and buffer) */
int m_nSizeUsed; /* Number of bytes used in buffer */
GBool m_bHardBlockSize;/* TRUE=Blocks MUST always be nSize bytes */
/* FALSE=last block may be less than nSize */
int m_nFileOffset; /* Location of current block in the file */
int m_nCurPos; /* Next byte to read from m_pabyBuf[] */
int m_nFirstBlockPtr;/* Size of file header when different from */
/* block size (used by GotoByteInFile()) */
int m_bModified; /* Used only to detect changes */
public:
TABRawBinBlock(TABAccess eAccessMode = TABRead,
GBool bHardBlockSize = TRUE);
virtual ~TABRawBinBlock();
virtual int ReadFromFile(FILE *fpSrc, int nOffset, int nSize = 512);
virtual int CommitToFile();
virtual int InitBlockFromData(GByte *pabyBuf, int nSize,
GBool bMakeCopy = TRUE,
FILE *fpSrc = NULL, int nOffset = 0);
virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
int GetBlockType();
virtual int GetBlockClass() { return TAB_RAWBIN_BLOCK; };
GInt32 GetStartAddress() {return m_nFileOffset;};
#ifdef DEBUG
virtual void Dump(FILE *fpOut = NULL);
#endif
void DumpBytes(GInt32 nValue, int nOffset=0, FILE *fpOut=NULL);
int GotoByteRel(int nOffset);
int GotoByteInBlock(int nOffset);
int GotoByteInFile(int nOffset, GBool bForceReadFromFile=FALSE);
void SetFirstBlockPtr(int nOffset);
int GetNumUnusedBytes();
int GetFirstUnusedByteOffset();
int GetCurAddress();
virtual int ReadBytes(int numBytes, GByte *pabyDstBuf);
GByte ReadByte();
GInt16 ReadInt16();
GInt32 ReadInt32();
float ReadFloat();
double ReadDouble();
virtual int WriteBytes(int nBytesToWrite, GByte *pBuf);
int WriteByte(GByte byValue);
int WriteInt16(GInt16 n16Value);
int WriteInt32(GInt32 n32Value);
int WriteFloat(float fValue);
int WriteDouble(double dValue);
int WriteZeros(int nBytesToWrite);
int WritePaddedString(int nFieldSize, const char *pszString);
void SetModifiedFlag(GBool bModified) {m_bModified=bModified;};
// This semi-private method gives a direct access to the internal
// buffer... to be used with extreme care!!!!!!!!!
GByte * GetCurDataPtr() { return (m_pabyBuf + m_nCurPos); } ;
};
/*---------------------------------------------------------------------
* class TABMAPHeaderBlock
*
* Class to handle Read/Write operation on .MAP Header Blocks
*--------------------------------------------------------------------*/
class TABMAPHeaderBlock: public TABRawBinBlock
{
protected:
TABProjInfo m_sProj;
public:
TABMAPHeaderBlock(TABAccess eAccessMode = TABRead);
~TABMAPHeaderBlock();
virtual int CommitToFile();
virtual int InitBlockFromData(GByte *pabyBuf, int nSize,
GBool bMakeCopy = TRUE,
FILE *fpSrc = NULL, int nOffset = 0);
virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
virtual int GetBlockClass() { return TABMAP_HEADER_BLOCK; };
int Int2Coordsys(GInt32 nX, GInt32 nY, double &dX, double &dY);
int Coordsys2Int(double dX, double dY, GInt32 &nX, GInt32 &nY,
GBool bIgnoreOverflow=FALSE);
int ComprInt2Coordsys(GInt32 nCenterX, GInt32 nCenterY,
int nDeltaX, int nDeltaY,
double &dX, double &dY);
int Int2CoordsysDist(GInt32 nX, GInt32 nY, double &dX, double &dY);
int Coordsys2IntDist(double dX, double dY, GInt32 &nX, GInt32 &nY);
int SetCoordsysBounds(double dXMin, double dYMin,
double dXMax, double dYMax);
int GetMapObjectSize(int nObjType);
GBool MapObjectUsesCoordBlock(int nObjType);
int GetProjInfo(TABProjInfo *psProjInfo);
int SetProjInfo(TABProjInfo *psProjInfo);
#ifdef DEBUG
virtual void Dump(FILE *fpOut = NULL);
#endif
// Instead of having over 30 get/set methods, we'll make all data
// members public and we will initialize them in the overloaded
// LoadFromFile(). For this reason, this class should be used with care.
GInt16 m_nMAPVersionNumber;
GInt16 m_nBlockSize;
double m_dCoordsys2DistUnits;
GInt32 m_nXMin;
GInt32 m_nYMin;
GInt32 m_nXMax;
GInt32 m_nYMax;
GBool m_bIntBoundsOverflow; // Set to TRUE if coordinates
// outside of bounds were written
GInt32 m_nFirstIndexBlock;
GInt32 m_nFirstGarbageBlock;
GInt32 m_nFirstToolBlock;
GInt32 m_numPointObjects;
GInt32 m_numLineObjects;
GInt32 m_numRegionObjects;
GInt32 m_numTextObjects;
GInt32 m_nMaxCoordBufSize;
GByte m_nDistUnitsCode; // See Appendix F
GByte m_nMaxSpIndexDepth;
GByte m_nCoordPrecision; // Num. decimal places on coord.
GByte m_nCoordOriginQuadrant;
GByte m_nReflectXAxisCoord;
GByte m_nMaxObjLenArrayId; // See gabyObjLenArray[]
GByte m_numPenDefs;
GByte m_numBrushDefs;
GByte m_numSymbolDefs;
GByte m_numFontDefs;
GInt16 m_numMapToolBlocks;
double m_XScale;
double m_YScale;
double m_XDispl;
double m_YDispl;
};
/*---------------------------------------------------------------------
* class TABMAPIndexBlock
*
* Class to handle Read/Write operation on .MAP Index Blocks (Type 01)
*--------------------------------------------------------------------*/
class TABMAPIndexBlock: public TABRawBinBlock
{
protected:
int m_numEntries;
TABMAPIndexEntry m_asEntries[TAB_MAX_ENTRIES_INDEX_BLOCK];
int ReadNextEntry(TABMAPIndexEntry *psEntry);
int WriteNextEntry(TABMAPIndexEntry *psEntry);
// Use these to keep track of current block's MBR
GInt32 m_nMinX;
GInt32 m_nMinY;
GInt32 m_nMaxX;
GInt32 m_nMaxY;
TABBinBlockManager *m_poBlockManagerRef;
// Info about child currently loaded
TABMAPIndexBlock *m_poCurChild;
int m_nCurChildIndex;
// Also need to know about its parent
TABMAPIndexBlock *m_poParentRef;
int ReadAllEntries();
public:
TABMAPIndexBlock(TABAccess eAccessMode = TABRead);
~TABMAPIndexBlock();
virtual int InitBlockFromData(GByte *pabyBuf, int nSize,
GBool bMakeCopy = TRUE,
FILE *fpSrc = NULL, int nOffset = 0);
virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
virtual int CommitToFile();
virtual int GetBlockClass() { return TABMAP_INDEX_BLOCK; };
int GetNumFreeEntries();
int GetNumEntries() {return m_numEntries;};
TABMAPIndexEntry *GetEntry( int iIndex );
int AddEntry(GInt32 XMin, GInt32 YMin,
GInt32 XMax, GInt32 YMax,
GInt32 nBlockPtr,
GBool bAddInThisNodeOnly=FALSE);
int GetCurMaxDepth();
void GetMBR(GInt32 &nXMin, GInt32 &nYMin,
GInt32 &nXMax, GInt32 &nYMax);
GInt32 GetNodeBlockPtr() { return GetStartAddress();};
void SetMAPBlockManagerRef(TABBinBlockManager *poBlockMgr);
void SetParentRef(TABMAPIndexBlock *poParent);
void SetCurChildRef(TABMAPIndexBlock *poChild, int nChildIndex);
int GetCurChildIndex() { return m_nCurChildIndex; }
TABMAPIndexBlock *GetCurChild() { return m_poCurChild; }
TABMAPIndexBlock *GetParentRef() { return m_poParentRef; }
int SplitNode(int nNewEntryX, int nNewEntryY);
int SplitRootNode(int nNewEntryX, int nNewEntryY);
void UpdateCurChildMBR(GInt32 nXMin, GInt32 nYMin,
GInt32 nXMax, GInt32 nYMax,
GInt32 nBlockPtr);
void RecomputeMBR();
int InsertEntry(GInt32 XMin, GInt32 YMin,
GInt32 XMax, GInt32 YMax, GInt32 nBlockPtr);
#ifdef DEBUG
virtual void Dump(FILE *fpOut = NULL);
#endif
};
/*---------------------------------------------------------------------
* class TABMAPObjectBlock
*
* Class to handle Read/Write operation on .MAP Object data Blocks (Type 02)
*--------------------------------------------------------------------*/
class TABMAPObjectBlock: public TABRawBinBlock
{
protected:
int m_numDataBytes; /* Excluding first 4 bytes header */
GInt32 m_nFirstCoordBlock;
GInt32 m_nLastCoordBlock;
GInt32 m_nCenterX;
GInt32 m_nCenterY;
// In order to compute block center, we need to keep track of MBR
GInt32 m_nMinX;
GInt32 m_nMinY;
GInt32 m_nMaxX;
GInt32 m_nMaxY;
int m_nCurObjectOffset; // -1 if there is no current object.
int m_nCurObjectId; // -1 if there is no current object.
int m_nCurObjectType; // -1 if there is no current object.
// Array of object headers held in memory until CommitToFile() is called
TABMAPObjHdr **m_papoObjHdr;
int m_numObjects;
void FreeObjectArray();
public:
TABMAPObjectBlock(TABAccess eAccessMode = TABRead);
~TABMAPObjectBlock();
virtual int CommitToFile();
virtual int InitBlockFromData(GByte *pabyBuf, int nSize,
GBool bMakeCopy = TRUE,
FILE *fpSrc = NULL, int nOffset = 0);
virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
virtual int GetBlockClass() { return TABMAP_OBJECT_BLOCK; };
virtual int ReadIntCoord(GBool bCompressed, GInt32 &nX, GInt32 &nY);
int WriteIntCoord(GInt32 nX, GInt32 nY, GBool bCompressed);
int WriteIntMBRCoord(GInt32 nXMin, GInt32 nYMin,
GInt32 nXMax, GInt32 nYMax,
GBool bCompressed);
int UpdateMBR(GInt32 nX, GInt32 nY);
int AddObject(TABMAPObjHdr *poObjHdr);
void AddCoordBlockRef(GInt32 nCoordBlockAddress);
void GetMBR(GInt32 &nXMin, GInt32 &nYMin,
GInt32 &nXMax, GInt32 &nYMax);
int AdvanceToNextObject( TABMAPHeaderBlock * );
int GetCurObjectOffset() { return m_nCurObjectOffset; }
int GetCurObjectId() { return m_nCurObjectId; }
int GetCurObjectType() { return m_nCurObjectType; }
#ifdef DEBUG
virtual void Dump(FILE *fpOut = NULL) { Dump(fpOut, FALSE); };
void Dump(FILE *fpOut, GBool bDetails);
#endif
};
/*---------------------------------------------------------------------
* class TABMAPCoordBlock
*
* Class to handle Read/Write operation on .MAP Coordinate Blocks (Type 03)
*--------------------------------------------------------------------*/
class TABMAPCoordBlock: public TABRawBinBlock
{
protected:
int m_numDataBytes; /* Excluding first 8 bytes header */
GInt32 m_nNextCoordBlock;
int m_numBlocksInChain;
GInt32 m_nComprOrgX;
GInt32 m_nComprOrgY;
// In order to compute block center, we need to keep track of MBR
GInt32 m_nMinX;
GInt32 m_nMinY;
GInt32 m_nMaxX;
GInt32 m_nMaxY;
TABBinBlockManager *m_poBlockManagerRef;
int m_nTotalDataSize; // Num bytes in whole chain of blocks
int m_nFeatureDataSize; // Num bytes for current feature coords
GInt32 m_nFeatureXMin; // Used to keep track of current
GInt32 m_nFeatureYMin; // feature MBR.
GInt32 m_nFeatureXMax;
GInt32 m_nFeatureYMax;
public:
TABMAPCoordBlock(TABAccess eAccessMode = TABRead);
~TABMAPCoordBlock();
virtual int InitBlockFromData(GByte *pabyBuf, int nSize,
GBool bMakeCopy = TRUE,
FILE *fpSrc = NULL, int nOffset = 0);
virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
virtual int CommitToFile();
virtual int GetBlockClass() { return TABMAP_COORD_BLOCK; };
void SetMAPBlockManagerRef(TABBinBlockManager *poBlockManager);
virtual int ReadBytes(int numBytes, GByte *pabyDstBuf);
virtual int WriteBytes(int nBytesToWrite, GByte *pBuf);
void SetComprCoordOrigin(GInt32 nX, GInt32 nY);
int ReadIntCoord(GBool bCompressed, GInt32 &nX, GInt32 &nY);
int ReadIntCoords(GBool bCompressed, int numCoords, GInt32 *panXY);
int ReadCoordSecHdrs(GBool bCompressed, GBool bV450Hdr,
int numSections, TABMAPCoordSecHdr *pasHdrs,
GInt32 &numVerticesTotal);
int WriteCoordSecHdrs(GBool bV450Hdr, int numSections,
TABMAPCoordSecHdr *pasHdrs,
GBool bCompressed);
void SetNextCoordBlock(GInt32 nNextCoordBlockAddress);
int WriteIntCoord(GInt32 nX, GInt32 nY, GBool bCompressed);
int GetNumBlocksInChain() { return m_numBlocksInChain; };
void ResetTotalDataSize() {m_nTotalDataSize = 0;};
int GetTotalDataSize() {return m_nTotalDataSize;};
void StartNewFeature();
int GetFeatureDataSize() {return m_nFeatureDataSize;};
//__TODO__ Can we flush GetFeatureMBR() and all MBR tracking in this class???
void GetFeatureMBR(GInt32 &nXMin, GInt32 &nYMin,
GInt32 &nXMax, GInt32 &nYMax);
#ifdef DEBUG
virtual void Dump(FILE *fpOut = NULL);
#endif
};
/*---------------------------------------------------------------------
* class TABMAPToolBlock
*
* Class to handle Read/Write operation on .MAP Drawing Tool Blocks (Type 05)
*
* In addition to handling the I/O, this class also maintains the list
* of Tool definitions in memory.
*--------------------------------------------------------------------*/
class TABMAPToolBlock: public TABRawBinBlock
{
protected:
int m_numDataBytes; /* Excluding first 8 bytes header */
GInt32 m_nNextToolBlock;
int m_numBlocksInChain;
TABBinBlockManager *m_poBlockManagerRef;
public:
TABMAPToolBlock(TABAccess eAccessMode = TABRead);
~TABMAPToolBlock();
virtual int InitBlockFromData(GByte *pabyBuf, int nSize,
GBool bMakeCopy = TRUE,
FILE *fpSrc = NULL, int nOffset = 0);
virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
virtual int CommitToFile();
virtual int GetBlockClass() { return TABMAP_TOOL_BLOCK; };
void SetMAPBlockManagerRef(TABBinBlockManager *poBlockManager);
virtual int ReadBytes(int numBytes, GByte *pabyDstBuf);
virtual int WriteBytes(int nBytesToWrite, GByte *pBuf);
void SetNextToolBlock(GInt32 nNextCoordBlockAddress);
GBool EndOfChain();
int GetNumBlocksInChain() { return m_numBlocksInChain; };
int CheckAvailableSpace(int nToolType);
#ifdef DEBUG
virtual void Dump(FILE *fpOut = NULL);
#endif
};
/*=====================================================================
Classes to deal with .MAP files at the MapInfo object level
=====================================================================*/
/*---------------------------------------------------------------------
* class TABIDFile
*
* Class to handle Read/Write operation on .ID files... the .ID file
* contains an index to the objects in the .MAP file by object id.
*--------------------------------------------------------------------*/
class TABIDFile
{
private:
char *m_pszFname;
FILE *m_fp;
TABAccess m_eAccessMode;
TABRawBinBlock *m_poIDBlock;
int m_nBlockSize;
GInt32 m_nMaxId;
public:
TABIDFile();
~TABIDFile();
int Open(const char *pszFname, const char *pszAccess);
int Close();
GInt32 GetObjPtr(GInt32 nObjId);
int SetObjPtr(GInt32 nObjId, GInt32 nObjPtr);
GInt32 GetMaxObjId();
#ifdef DEBUG
void Dump(FILE *fpOut = NULL);
#endif
};
/*---------------------------------------------------------------------
* class TABMAPFile
*
* Class to handle Read/Write operation on .MAP files... this class hides
* all the dealings with blocks, indexes, etc.
* Use this class to deal with MapInfo objects directly.
*--------------------------------------------------------------------*/
class TABMAPFile
{
private:
int m_nMinTABVersion;
char *m_pszFname;
FILE *m_fp;
TABAccess m_eAccessMode;
TABBinBlockManager m_oBlockManager;
TABMAPHeaderBlock *m_poHeader;
// Members used to access objects using the spatial index
TABMAPIndexBlock *m_poSpIndex;
// Member used to access objects using the object ids (.ID file)
TABIDFile *m_poIdIndex;
// Current object data block.
TABMAPObjectBlock *m_poCurObjBlock;
int m_nCurObjPtr;
int m_nCurObjType;
int m_nCurObjId;
TABMAPCoordBlock *m_poCurCoordBlock;
// Drawing Tool Def. table (takes care of all drawing tools in memory)
TABToolDefTable *m_poToolDefTable;
// Coordinates filter... default is MBR of the whole file
TABVertex m_sMinFilter;
TABVertex m_sMaxFilter;
GInt32 m_XMinFilter;
GInt32 m_YMinFilter;
GInt32 m_XMaxFilter;
GInt32 m_YMaxFilter;
int CommitObjBlock(GBool bInitNewBlock =TRUE);
int InitDrawingTools();
int CommitDrawingTools();
int CommitSpatialIndex();
// Stuff related to traversing spatial index.
TABMAPIndexBlock *m_poSpIndexLeaf;
int LoadNextMatchingObjectBlock(int bFirstObject);
TABRawBinBlock *PushBlock( int nFileOffset );
public:
TABMAPFile();
~TABMAPFile();
int Open(const char *pszFname, const char *pszAccess,
GBool bNoErrorMsg = FALSE );
int Close();
int Int2Coordsys(GInt32 nX, GInt32 nY, double &dX, double &dY);
int Coordsys2Int(double dX, double dY, GInt32 &nX, GInt32 &nY,
GBool bIgnoreOveflow=FALSE);
int Int2CoordsysDist(GInt32 nX, GInt32 nY, double &dX, double &dY);
int Coordsys2IntDist(double dX, double dY, GInt32 &nX, GInt32 &nY);
void SetCoordFilter(TABVertex sMin, TABVertex sMax);
void GetCoordFilter(TABVertex &sMin, TABVertex &sMax);
void ResetCoordFilter();
int SetCoordsysBounds(double dXMin, double dYMin,
double dXMax, double dYMax);
GInt32 GetMaxObjId();
int MoveToObjId(int nObjId);
void UpdateMapHeaderInfo(GByte nObjType);
int PrepareNewObj(int nObjId, GByte nObjType);
void ResetReading();
int GetNextFeatureId( int nPrevId );
int GetCurObjType();
int GetCurObjId();
TABMAPObjectBlock *GetCurObjBlock();
TABMAPCoordBlock *GetCurCoordBlock();
TABMAPCoordBlock *GetCoordBlock(int nFileOffset);
TABMAPHeaderBlock *GetHeaderBlock();
TABIDFile *GetIDFileRef();
TABRawBinBlock *GetIndexObjectBlock(int nFileOffset);
int ReadPenDef(int nPenIndex, TABPenDef *psDef);
int ReadBrushDef(int nBrushIndex, TABBrushDef *psDef);
int ReadFontDef(int nFontIndex, TABFontDef *psDef);
int ReadSymbolDef(int nSymbolIndex, TABSymbolDef *psDef);
int WritePenDef(TABPenDef *psDef);
int WriteBrushDef(TABBrushDef *psDef);
int WriteFontDef(TABFontDef *psDef);
int WriteSymbolDef(TABSymbolDef *psDef);
int GetMinTABFileVersion();
#ifdef DEBUG
void Dump(FILE *fpOut = NULL);
#endif
};
/*---------------------------------------------------------------------
* class TABINDNode
*
* An index node in a .IND file.
*
* This class takes care of reading child nodes as necessary when looking
* for a given key value in the index tree.
*--------------------------------------------------------------------*/
class TABINDNode
{
private:
FILE *m_fp;
TABAccess m_eAccessMode;
TABINDNode *m_poCurChildNode;
TABINDNode *m_poParentNodeRef;
TABBinBlockManager *m_poBlockManagerRef;
int m_nSubTreeDepth;
int m_nKeyLength;
TABFieldType m_eFieldType;
GBool m_bUnique;
GInt32 m_nCurDataBlockPtr;
int m_nCurIndexEntry;
TABRawBinBlock *m_poDataBlock;
int m_numEntriesInNode;
GInt32 m_nPrevNodePtr;
GInt32 m_nNextNodePtr;
int GotoNodePtr(GInt32 nNewNodePtr);
GInt32 ReadIndexEntry(int nEntryNo, GByte *pKeyValue);
int IndexKeyCmp(GByte *pKeyValue, int nEntryNo);
int InsertEntry(GByte *pKeyValue, GInt32 nRecordNo,
GBool bInsertAfterCurChild=FALSE,
GBool bMakeNewEntryCurChild=FALSE);
int SetNodeBufferDirectly(int numEntries, GByte *pBuf,
int nCurIndexEntry=0,
TABINDNode *poCurChild=NULL);
public:
TABINDNode(TABAccess eAccessMode = TABRead);
~TABINDNode();
int InitNode(FILE *fp, int nBlockPtr,
int nKeyLength, int nSubTreeDepth, GBool bUnique,
TABBinBlockManager *poBlockMgr=NULL,
TABINDNode *poParentNode=NULL,
int nPrevNodePtr=0, int nNextNodePtr=0);
int SetFieldType(TABFieldType eType);
TABFieldType GetFieldType() {return m_eFieldType;};
void SetUnique(GBool bUnique){m_bUnique = bUnique;};
GBool IsUnique() {return m_bUnique;};
int GetKeyLength() {return m_nKeyLength;};
int GetSubTreeDepth() {return m_nSubTreeDepth;};
GInt32 GetNodeBlockPtr() {return m_nCurDataBlockPtr;};
int GetNumEntries() {return m_numEntriesInNode;};
int GetMaxNumEntries() {return (512-12)/(m_nKeyLength+4);};
GInt32 FindFirst(GByte *pKeyValue);
GInt32 FindNext(GByte *pKeyValue);
int CommitToFile();
int AddEntry(GByte *pKeyValue, GInt32 nRecordNo,
GBool bAddInThisNodeOnly=FALSE,
GBool bInsertAfterCurChild=FALSE,
GBool bMakeNewEntryCurChild=FALSE);
int SplitNode();
int SplitRootNode();
GByte* GetNodeKey();
int UpdateCurChildEntry(GByte *pKeyValue, GInt32 nRecordNo);
int UpdateSplitChild(GByte *pKeyValue1, GInt32 nRecordNo1,
GByte *pKeyValue2, GInt32 nRecordNo2,
int nNewCurChildNo /* 1 or 2 */);
int SetNodeBlockPtr(GInt32 nThisNodePtr);
int SetPrevNodePtr(GInt32 nPrevNodePtr);
int SetNextNodePtr(GInt32 nNextNodePtr);
#ifdef DEBUG
void Dump(FILE *fpOut = NULL);
#endif
};
/*---------------------------------------------------------------------
* class TABINDFile
*
* Class to handle table field index (.IND) files... we use this
* class as the main entry point to open and search the table field indexes.
* Note that .IND files are supported for read access only.
*--------------------------------------------------------------------*/
class TABINDFile
{
private:
char *m_pszFname;
FILE *m_fp;
TABAccess m_eAccessMode;
TABBinBlockManager m_oBlockManager;
int m_numIndexes;
TABINDNode **m_papoIndexRootNodes;
GByte **m_papbyKeyBuffers;
int ValidateIndexNo(int nIndexNumber);
int ReadHeader();
int WriteHeader();
public:
TABINDFile();
~TABINDFile();
int Open(const char *pszFname, const char *pszAccess,
GBool bTestOpenNoError=FALSE);
int Close();
int GetNumIndexes() {return m_numIndexes;};
int SetIndexFieldType(int nIndexNumber, TABFieldType eType);
int SetIndexUnique(int nIndexNumber, GBool bUnique=TRUE);
GByte *BuildKey(int nIndexNumber, GInt32 nValue);
GByte *BuildKey(int nIndexNumber, const char *pszStr);
GByte *BuildKey(int nIndexNumber, double dValue);
GInt32 FindFirst(int nIndexNumber, GByte *pKeyValue);
GInt32 FindNext(int nIndexNumber, GByte *pKeyValue);
int CreateIndex(TABFieldType eType, int nFieldSize);
int AddEntry(int nIndexNumber, GByte *pKeyValue, GInt32 nRecordNo);
#ifdef DEBUG
void Dump(FILE *fpOut = NULL);
#endif
};
/*---------------------------------------------------------------------
* class TABDATFile
*
* Class to handle Read/Write operation on .DAT files... the .DAT file
* contains the table of attribute field values.
*--------------------------------------------------------------------*/
class TABDATFile
{
private:
char *m_pszFname;
FILE *m_fp;
TABAccess m_eAccessMode;
TABTableType m_eTableType;
TABRawBinBlock *m_poHeaderBlock;
int m_numFields;
TABDATFieldDef *m_pasFieldDef;
TABRawBinBlock *m_poRecordBlock;
int m_nBlockSize;
int m_nRecordSize;
int m_nCurRecordId;
GBool m_bCurRecordDeletedFlag;
GInt32 m_numRecords;
GInt32 m_nFirstRecordPtr;
GBool m_bWriteHeaderInitialized;
int InitWriteHeader();
int WriteHeader();
public:
TABDATFile();
~TABDATFile();
int Open(const char *pszFname, const char *pszAccess,
TABTableType eTableType =TABTableNative);
int Close();
int GetNumFields();
TABFieldType GetFieldType(int nFieldId);
int GetFieldWidth(int nFieldId);
int GetFieldPrecision(int nFieldId);
int ValidateFieldInfoFromTAB(int iField, const char *pszName,
TABFieldType eType,
int nWidth, int nPrecision);
int AddField(const char *pszName, TABFieldType eType,
int nWidth, int nPrecision=0);
GInt32 GetNumRecords();
TABRawBinBlock *GetRecordBlock(int nRecordId);
GBool IsCurrentRecordDeleted() { return m_bCurRecordDeletedFlag;};
int CommitRecordToFile();
const char *ReadCharField(int nWidth);
GInt32 ReadIntegerField(int nWidth);
GInt16 ReadSmallIntField(int nWidth);
double ReadFloatField(int nWidth);
double ReadDecimalField(int nWidth);
const char *ReadLogicalField(int nWidth);
const char *ReadDateField(int nWidth);
int WriteCharField(const char *pszValue, int nWidth,
TABINDFile *poINDFile, int nIndexNo);
int WriteIntegerField(GInt32 nValue,
TABINDFile *poINDFile, int nIndexNo);
int WriteSmallIntField(GInt16 nValue,
TABINDFile *poINDFile, int nIndexNo);
int WriteFloatField(double dValue,
TABINDFile *poINDFile, int nIndexNo);
int WriteDecimalField(double dValue, int nWidth, int nPrecision,
TABINDFile *poINDFile, int nIndexNo);
int WriteLogicalField(const char *pszValue,
TABINDFile *poINDFile, int nIndexNo);
int WriteDateField(const char *pszValue,
TABINDFile *poINDFile, int nIndexNo);
#ifdef DEBUG
void Dump(FILE *fpOut = NULL);
#endif
};
/*---------------------------------------------------------------------
* class TABRelation
*
* Class that maintains a relation between 2 tables through a field
* in each table (the SQL "where table1.field1=table2.field2" found in
* TABView datasets).
*
* An instance of this class is used to read data records from the
* combined tables as if they were a single one.
*--------------------------------------------------------------------*/
class TABRelation
{
private:
/* Information about the main table.
*/
TABFile *m_poMainTable;
char *m_pszMainFieldName;
int m_nMainFieldNo;
/* Information about the related table.
* NOTE: The related field MUST be indexed.
*/
TABFile *m_poRelTable;
char *m_pszRelFieldName;
int m_nRelFieldNo;
TABINDFile *m_poRelINDFileRef;
int m_nRelFieldIndexNo;
int m_nUniqueRecordNo;
/* Main and Rel table field map:
* For each field in the source tables, -1 means that the field is not
* selected, and a value >=0 is the index of this field in the combined
* FeatureDefn
*/
int *m_panMainTableFieldMap;
int *m_panRelTableFieldMap;
OGRFeatureDefn *m_poDefn;
void ResetAllMembers();
GByte *BuildFieldKey(TABFeature *poFeature, int nFieldNo,
TABFieldType eType, int nIndexNo);
public:
TABRelation();
~TABRelation();
int Init(const char *pszViewName,
TABFile *poMainTable, TABFile *poRelTable,
const char *pszMainFieldName,
const char *pszRelFieldName,
char **papszSelectedFields);
int CreateRelFields();
OGRFeatureDefn *GetFeatureDefn() {return m_poDefn;};
TABFieldType GetNativeFieldType(int nFieldId);
TABFeature *GetFeature(int nFeatureId);
int SetFeature(TABFeature *poFeature, int nFeatureId=-1);
int SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
TABFieldType *paeMapInfoNativeFieldTypes=NULL);
int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
int nWidth=0, int nPrecision=0,
GBool bIndexed=FALSE, GBool bUnique=FALSE);
int SetFieldIndexed(int nFieldId);
GBool IsFieldIndexed(int nFieldId);
GBool IsFieldUnique(int nFieldId);
const char *GetMainFieldName() {return m_pszMainFieldName;};
const char *GetRelFieldName() {return m_pszRelFieldName;};
};
/*---------------------------------------------------------------------
* class MIDDATAFile
*
* Class to handle a file pointer with a copy of the latest readed line
*
*--------------------------------------------------------------------*/
class MIDDATAFile
{
public:
MIDDATAFile();
~MIDDATAFile();
int Open(const char *pszFname, const char *pszAccess);
int Close();
const char *GetLine();
const char *GetLastLine();
int Rewind();
void SaveLine(const char *pszLine);
const char *GetSavedLine();
void WriteLine(const char*, ...);
GBool IsValidFeature(const char *pszString);
// Translation information
void SetTranslation(double, double, double, double);
double GetXTrans(double);
double GetYTrans(double);
double GetXMultiplier(){return m_dfXMultiplier;}
const char *GetDelimiter(){return m_pszDelimiter;}
void SetDelimiter(const char *pszDelimiter){m_pszDelimiter=pszDelimiter;}
void SetEof(GBool bEof);
GBool GetEof();
private:
FILE *m_fp;
const char *m_pszDelimiter;
// Set limit for the length of a line
#define MIDMAXCHAR 10000
char m_szLastRead[MIDMAXCHAR];
char m_szSavedLine[MIDMAXCHAR];
char *m_pszFname;
TABAccess m_eAccessMode;
double m_dfXMultiplier;
double m_dfYMultiplier;
double m_dfXDisplacement;
double m_dfYDisplacement;
GBool m_bEof;
};
/*=====================================================================
Function prototypes
=====================================================================*/
TABRawBinBlock *TABCreateMAPBlockFromFile(FILE *fpSrc, int nOffset,
int nSize = 512,
GBool bHardBlockSize = TRUE,
TABAccess eAccessMode = TABRead);
#endif /* _MITAB_PRIV_H_INCLUDED_ */