1 : /******************************************************************************
2 : * $Id: hfadictionary.cpp 18895 2010-02-23 19:30:01Z warmerdam $
3 : *
4 : * Project: Erdas Imagine (.img) Translator
5 : * Purpose: Implementation of the HFADictionary class for managing the
6 : * dictionary read from the HFA file. Most work done by the
7 : * HFAType, and HFAField classes.
8 : * Author: Frank Warmerdam, warmerdam@pobox.com
9 : *
10 : ******************************************************************************
11 : * Copyright (c) 1999, Intergraph Corporation
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "hfa_p.h"
33 : #include "cpl_conv.h"
34 :
35 : CPL_CVSID("$Id: hfadictionary.cpp 18895 2010-02-23 19:30:01Z warmerdam $");
36 :
37 : static const char *apszDefDefn[] = {
38 :
39 : "Edsc_Table",
40 : "{1:lnumrows,}Edsc_Table",
41 :
42 : "Edsc_Column",
43 : "{1:lnumRows,1:LcolumnDataPtr,1:e4:integer,real,complex,string,dataType,1:lmaxNumChars,}Edsc_Column",
44 :
45 : "Eprj_Size",
46 : "{1:dwidth,1:dheight,}Eprj_Size",
47 :
48 : "Eprj_Coordinate",
49 : "{1:dx,1:dy,}Eprj_Coordinate",
50 :
51 : "Eprj_MapInfo",
52 : "{0:pcproName,1:*oEprj_Coordinate,upperLeftCenter,1:*oEprj_Coordinate,lowerRightCenter,1:*oEprj_Size,pixelSize,0:pcunits,}Eprj_MapInfo",
53 :
54 : "Eimg_StatisticsParameters830",
55 : "{0:poEmif_String,LayerNames,1:*bExcludedValues,1:oEmif_String,AOIname,1:lSkipFactorX,1:lSkipFactorY,1:*oEdsc_BinFunction,BinFunction,}Eimg_StatisticsParameters830",
56 :
57 : "Esta_Statistics",
58 : "{1:dminimum,1:dmaximum,1:dmean,1:dmedian,1:dmode,1:dstddev,}Esta_Statistics",
59 :
60 : "Edsc_BinFunction",
61 : "{1:lnumBins,1:e4:direct,linear,logarithmic,explicit,binFunctionType,1:dminLimit,1:dmaxLimit,1:*bbinLimits,}Edsc_BinFunction",
62 :
63 : "Eimg_NonInitializedValue",
64 : "{1:*bvalueBD,}Eimg_NonInitializedValue",
65 :
66 : "Eprj_MapProjection842",
67 : "{1:x{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,MIFDictionary,0:pCMIFObject,}Emif_MIFObject,projection,1:x{0:pcstring,}Emif_String,title,}Eprj_MapProjection842",
68 :
69 : "Emif_MIFObject",
70 : "{1:x{0:pcstring,}Emif_String,type,1:x{0:pcstring,}Emif_String,MIFDictionary,0:pCMIFObject,}Emif_MIFObject",
71 :
72 : "Eprj_ProParameters",
73 : "{1:e2:EPRJ_INTERNAL,EPRJ_EXTERNAL,proType,1:lproNumber,0:pcproExeName,0:pcproName,1:lproZone,0:pdproParams,1:*oEprj_Spheroid,proSpheroid,}Eprj_ProParameters",
74 :
75 : "Eprj_Datum",
76 : "{0:pcdatumname,1:e3:EPRJ_DATUM_PARAMETRIC,EPRJ_DATUM_GRID,EPRJ_DATUM_REGRESSION,type,0:pdparams,0:pcgridname,}Eprj_Datum",
77 :
78 : "Eprj_Spheroid",
79 : "{0:pcsphereName,1:da,1:db,1:deSquared,1:dradius,}Eprj_Spheroid",
80 :
81 : NULL,
82 : NULL };
83 :
84 :
85 :
86 : /************************************************************************/
87 : /* ==================================================================== */
88 : /* HFADictionary */
89 : /* ==================================================================== */
90 : /************************************************************************/
91 :
92 :
93 : /************************************************************************/
94 : /* HFADictionary() */
95 : /************************************************************************/
96 :
97 445 : HFADictionary::HFADictionary( const char * pszString )
98 :
99 : {
100 : int i;
101 :
102 445 : nTypes = 0;
103 445 : nTypesMax = 0;
104 445 : papoTypes = NULL;
105 :
106 445 : osDictionaryText = pszString;
107 445 : bDictionaryTextDirty = FALSE;
108 :
109 : /* -------------------------------------------------------------------- */
110 : /* Read all the types. */
111 : /* -------------------------------------------------------------------- */
112 16396 : while( pszString != NULL && *pszString != '.' )
113 : {
114 : HFAType *poNewType;
115 :
116 15506 : poNewType = new HFAType();
117 31012 : pszString = poNewType->Initialize( pszString );
118 :
119 15506 : if( pszString != NULL )
120 15506 : AddType( poNewType );
121 : else
122 0 : delete poNewType;
123 : }
124 :
125 : /* -------------------------------------------------------------------- */
126 : /* Complete the definitions. */
127 : /* -------------------------------------------------------------------- */
128 15951 : for( i = 0; i < nTypes; i++ )
129 : {
130 15506 : papoTypes[i]->CompleteDefn( this );
131 : }
132 445 : }
133 :
134 : /************************************************************************/
135 : /* ~HFADictionary() */
136 : /************************************************************************/
137 :
138 445 : HFADictionary::~HFADictionary()
139 :
140 : {
141 : int i;
142 :
143 15954 : for( i = 0; i < nTypes; i++ )
144 15509 : delete papoTypes[i];
145 :
146 445 : CPLFree( papoTypes );
147 445 : }
148 :
149 : /************************************************************************/
150 : /* AddType() */
151 : /************************************************************************/
152 :
153 15509 : void HFADictionary::AddType( HFAType *poType )
154 :
155 : {
156 15509 : if( nTypes == nTypesMax )
157 : {
158 1280 : nTypesMax = nTypes * 2 + 10;
159 : papoTypes = (HFAType **) CPLRealloc( papoTypes,
160 1280 : sizeof(void*) * nTypesMax );
161 : }
162 :
163 15509 : papoTypes[nTypes++] = poType;
164 15509 : }
165 :
166 : /************************************************************************/
167 : /* FindType() */
168 : /************************************************************************/
169 :
170 11533 : HFAType * HFADictionary::FindType( const char * pszName )
171 :
172 : {
173 : int i;
174 :
175 188804 : for( i = 0; i < nTypes; i++ )
176 : {
177 188801 : if( papoTypes[i]->pszTypeName != NULL &&
178 : strcmp(pszName,papoTypes[i]->pszTypeName) == 0 )
179 11530 : return( papoTypes[i] );
180 : }
181 :
182 : /* -------------------------------------------------------------------- */
183 : /* Check if this is a type have other knowledge of. If so, add */
184 : /* it to the dictionary now. I'm not sure how some files end */
185 : /* up being distributed using types not in the dictionary. */
186 : /* -------------------------------------------------------------------- */
187 3 : for( i = 0; apszDefDefn[i] != NULL; i += 2 )
188 : {
189 3 : if( strcmp( pszName, apszDefDefn[i] ) == 0 )
190 : {
191 3 : HFAType *poNewType = new HFAType();
192 :
193 3 : poNewType->Initialize( apszDefDefn[i+1] );
194 3 : AddType( poNewType );
195 3 : poNewType->CompleteDefn( this );
196 :
197 3 : osDictionaryText.erase( osDictionaryText.size() - 1, 1 );
198 3 : osDictionaryText += apszDefDefn[i+1];
199 3 : osDictionaryText += ",.";
200 :
201 3 : bDictionaryTextDirty = TRUE;
202 :
203 3 : return poNewType;
204 : }
205 : }
206 :
207 0 : return NULL;
208 : }
209 :
210 : /************************************************************************/
211 : /* GetItemSize() */
212 : /* */
213 : /* Get the size of a basic (atomic) item. */
214 : /************************************************************************/
215 :
216 61527 : int HFADictionary::GetItemSize( char chType )
217 :
218 : {
219 61527 : switch( chType )
220 : {
221 : case '1':
222 : case '2':
223 : case '4':
224 : case 'c':
225 : case 'C':
226 18082 : return 1;
227 :
228 : case 'e':
229 : case 's':
230 : case 'S':
231 8747 : return 2;
232 :
233 : case 't':
234 : case 'l':
235 : case 'L':
236 : case 'f':
237 23828 : return 4;
238 :
239 : case 'd':
240 : case 'm':
241 8589 : return 8;
242 :
243 : case 'M':
244 0 : return 16;
245 :
246 : case 'b':
247 2281 : return -1;
248 :
249 : case 'o':
250 : case 'x':
251 0 : return 0;
252 :
253 : default:
254 0 : CPLAssert( FALSE );
255 : }
256 :
257 0 : return 0;
258 : }
259 :
260 : /************************************************************************/
261 : /* Dump() */
262 : /************************************************************************/
263 :
264 0 : void HFADictionary::Dump( FILE * fp )
265 :
266 : {
267 : int i;
268 :
269 0 : VSIFPrintf( fp, "\nHFADictionary:\n" );
270 :
271 0 : for( i = 0; i < nTypes; i++ )
272 : {
273 0 : papoTypes[i]->Dump( fp );
274 : }
275 0 : }
|