1 : /**********************************************************************
2 : * $Id: mitab_middatafile.cpp,v 1.14 2006/01/27 13:54:06 fwarmerdam Exp $
3 : *
4 : * Name: mitab_datfile.cpp
5 : * Project: MapInfo TAB Read/Write library
6 : * Language: C++
7 : * Purpose: Implementation of the MIDDATAFile class used to handle
8 : * reading/writing of the MID/MIF files
9 : * Author: Stephane Villeneuve, stephane.v@videotron.ca
10 : *
11 : **********************************************************************
12 : * Copyright (c) 1999, 2000, Stephane Villeneuve
13 : *
14 : * Permission is hereby granted, free of charge, to any person obtaining a
15 : * copy of this software and associated documentation files (the "Software"),
16 : * to deal in the Software without restriction, including without limitation
17 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 : * and/or sell copies of the Software, and to permit persons to whom the
19 : * Software is furnished to do so, subject to the following conditions:
20 : *
21 : * The above copyright notice and this permission notice shall be included
22 : * in all copies or substantial portions of the Software.
23 : *
24 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 : * DEALINGS IN THE SOFTWARE.
31 : **********************************************************************
32 : *
33 : * $Log: mitab_middatafile.cpp,v $
34 : * Revision 1.14 2006/01/27 13:54:06 fwarmerdam
35 : * fixed memory leak
36 : *
37 : * Revision 1.13 2005/10/04 19:36:10 dmorissette
38 : * Added support for reading collections from MIF files (bug 1126)
39 : *
40 : * Revision 1.12 2005/09/29 19:46:55 dmorissette
41 : * Use "\t" as default delimiter in constructor (Anthony D - bugs 1155 and 37)
42 : *
43 : * Revision 1.11 2004/05/20 13:50:06 fwarmerdam
44 : * Call CPLReadLine(NULL) in Close() method to clean up working buffer.
45 : *
46 : * Revision 1.10 2002/04/26 14:16:49 julien
47 : * Finishing the implementation of Multipoint (support for MIF)
48 : *
49 : * Revision 1.9 2002/04/24 18:37:39 daniel
50 : * Added return statement at end of GetLastLine()
51 : *
52 : * Revision 1.8 2002/04/22 13:49:09 julien
53 : * Add EOF validation in MIDDATAFile::GetLastLine() (Bug 819)
54 : *
55 : * Revision 1.7 2001/09/19 14:49:49 warmerda
56 : * use VSIRewind() instead of rewind()
57 : *
58 : * Revision 1.6 2001/01/22 16:03:58 warmerda
59 : * expanded tabs
60 : *
61 : * Revision 1.5 2000/01/15 22:30:44 daniel
62 : * Switch to MIT/X-Consortium OpenSource license
63 : *
64 : * Revision 1.4 1999/12/19 17:41:29 daniel
65 : * Fixed a memory leak
66 : *
67 : * Revision 1.3 1999/11/14 17:43:32 stephane
68 : * Add ifdef to remove CPLError if OGR is define
69 : *
70 : * Revision 1.2 1999/11/11 01:22:05 stephane
71 : * Remove DebugFeature call, Point Reading error, add IsValidFeature() to
72 : * test correctly if we are on a feature
73 : *
74 : * Revision 1.1 1999/11/08 04:16:07 stephane
75 : * First Revision
76 : *
77 : *
78 : **********************************************************************/
79 :
80 : #include "mitab.h"
81 :
82 : /*=====================================================================
83 : * class MIDDATAFile
84 : *
85 : *====================================================================*/
86 :
87 36 : MIDDATAFile::MIDDATAFile()
88 : {
89 36 : m_fp = NULL;
90 36 : m_szLastRead[0] = '\0';
91 36 : m_szSavedLine[0] = '\0';
92 36 : m_pszDelimiter = "\t"; // Encom 2003 (was NULL)
93 :
94 36 : m_dfXMultiplier = 1.0;
95 36 : m_dfYMultiplier = 1.0;
96 36 : m_dfXDisplacement = 0.0;
97 36 : m_dfYDisplacement = 0.0;
98 :
99 36 : }
100 :
101 36 : MIDDATAFile::~MIDDATAFile()
102 : {
103 36 : Close();
104 36 : }
105 :
106 4 : void MIDDATAFile::SaveLine(const char *pszLine)
107 : {
108 4 : if (pszLine == NULL)
109 : {
110 0 : m_szSavedLine[0] = '\0';
111 : }
112 : else
113 : {
114 4 : strncpy(m_szSavedLine,pszLine,MIDMAXCHAR);
115 : }
116 4 : }
117 :
118 4 : const char *MIDDATAFile::GetSavedLine()
119 : {
120 4 : return m_szSavedLine;
121 : }
122 :
123 36 : int MIDDATAFile::Open(const char *pszFname, const char *pszAccess)
124 : {
125 36 : if (m_fp)
126 : {
127 0 : return -1;
128 : }
129 :
130 : /*-----------------------------------------------------------------
131 : * Validate access mode and make sure we use Text access.
132 : *----------------------------------------------------------------*/
133 36 : if (EQUALN(pszAccess, "r", 1))
134 : {
135 22 : m_eAccessMode = TABRead;
136 22 : pszAccess = "rt";
137 : }
138 14 : else if (EQUALN(pszAccess, "w", 1))
139 : {
140 14 : m_eAccessMode = TABWrite;
141 14 : pszAccess = "wt";
142 : }
143 : else
144 : {
145 0 : return -1;
146 : }
147 :
148 : /*-----------------------------------------------------------------
149 : * Open file for reading
150 : *----------------------------------------------------------------*/
151 36 : m_pszFname = CPLStrdup(pszFname);
152 36 : m_fp = VSIFOpen(m_pszFname, pszAccess);
153 :
154 36 : if (m_fp == NULL)
155 : {
156 0 : CPLFree(m_pszFname);
157 0 : m_pszFname = NULL;
158 0 : return -1;
159 : }
160 :
161 36 : SetEof(VSIFEof(m_fp));
162 36 : return 0;
163 : }
164 :
165 32 : int MIDDATAFile::Rewind()
166 : {
167 32 : if (m_fp == NULL || m_eAccessMode == TABWrite)
168 0 : return -1;
169 :
170 : else
171 : {
172 32 : VSIRewind(m_fp);
173 32 : SetEof(VSIFEof(m_fp));
174 : }
175 32 : return 0;
176 : }
177 :
178 72 : int MIDDATAFile::Close()
179 : {
180 72 : if (m_fp == NULL)
181 36 : return 0;
182 :
183 : // Close file
184 36 : VSIFClose(m_fp);
185 36 : m_fp = NULL;
186 :
187 : // clear readline buffer.
188 36 : CPLReadLine( NULL );
189 :
190 36 : CPLFree(m_pszFname);
191 36 : m_pszFname = NULL;
192 :
193 36 : return 0;
194 :
195 : }
196 :
197 1062 : const char *MIDDATAFile::GetLine()
198 : {
199 : const char *pszLine;
200 :
201 1062 : if (m_eAccessMode == TABRead)
202 : {
203 :
204 1062 : pszLine = CPLReadLine(m_fp);
205 :
206 1062 : SetEof(VSIFEof(m_fp));
207 :
208 1062 : if (pszLine == NULL)
209 : {
210 24 : m_szLastRead[0] = '\0';
211 : }
212 : else
213 : {
214 1038 : strncpy(m_szLastRead,pszLine,MIDMAXCHAR);
215 : }
216 : //if (pszLine)
217 : // printf("%s\n",pszLine);
218 1062 : return pszLine;
219 : }
220 : else
221 0 : CPLAssert(FALSE);
222 :
223 0 : return NULL;
224 : }
225 :
226 236 : const char *MIDDATAFile::GetLastLine()
227 : {
228 : // Return NULL if EOF
229 236 : if(GetEof())
230 : {
231 18 : return NULL;
232 : }
233 218 : else if (m_eAccessMode == TABRead)
234 : {
235 : // printf("%s\n",m_szLastRead);
236 218 : return m_szLastRead;
237 : }
238 :
239 : // We should never get here (Read/Write mode not implemented)
240 0 : CPLAssert(FALSE);
241 0 : return NULL;
242 : }
243 :
244 435 : void MIDDATAFile::WriteLine(const char *pszFormat,...)
245 : {
246 : va_list args;
247 :
248 870 : if (m_eAccessMode == TABWrite && m_fp)
249 : {
250 435 : va_start(args, pszFormat);
251 435 : vfprintf( m_fp, pszFormat, args );
252 435 : va_end(args);
253 : }
254 : else
255 : {
256 0 : CPLAssert(FALSE);
257 : }
258 435 : }
259 :
260 :
261 : void MIDDATAFile::SetTranslation(double dfXMul,double dfYMul,
262 : double dfXTran,
263 36 : double dfYTran)
264 : {
265 36 : m_dfXMultiplier = dfXMul;
266 36 : m_dfYMultiplier = dfYMul;
267 36 : m_dfXDisplacement = dfXTran;
268 36 : m_dfYDisplacement = dfYTran;
269 36 : }
270 :
271 542 : double MIDDATAFile::GetXTrans(double dfX)
272 : {
273 542 : return (dfX * m_dfXMultiplier) + m_dfXDisplacement;
274 : }
275 :
276 542 : double MIDDATAFile::GetYTrans(double dfY)
277 : {
278 542 : return (dfY * m_dfYMultiplier) + m_dfYDisplacement;
279 : }
280 :
281 :
282 133 : GBool MIDDATAFile::IsValidFeature(const char *pszString)
283 : {
284 : char **papszToken ;
285 :
286 133 : papszToken = CSLTokenizeString(pszString);
287 :
288 : // printf("%s\n",pszString);
289 :
290 133 : if (CSLCount(papszToken) == 0)
291 : {
292 14 : CSLDestroy(papszToken);
293 14 : return FALSE;
294 : }
295 :
296 119 : if (EQUAL(papszToken[0],"NONE") || EQUAL(papszToken[0],"POINT") ||
297 : EQUAL(papszToken[0],"LINE") || EQUAL(papszToken[0],"PLINE") ||
298 : EQUAL(papszToken[0],"REGION") || EQUAL(papszToken[0],"ARC") ||
299 : EQUAL(papszToken[0],"TEXT") || EQUAL(papszToken[0],"RECT") ||
300 : EQUAL(papszToken[0],"ROUNDRECT") || EQUAL(papszToken[0],"ELLIPSE") ||
301 : EQUAL(papszToken[0],"MULTIPOINT")|| EQUAL(papszToken[0],"COLLECTION") )
302 : {
303 59 : CSLDestroy(papszToken);
304 59 : return TRUE;
305 : }
306 :
307 60 : CSLDestroy(papszToken);
308 60 : return FALSE;
309 :
310 : }
311 :
312 :
313 236 : GBool MIDDATAFile::GetEof()
314 : {
315 236 : return m_bEof;
316 : }
317 :
318 :
319 1130 : void MIDDATAFile::SetEof(GBool bEof)
320 : {
321 1130 : m_bEof = bEof;
322 1130 : }
|