1 : /**********************************************************************
2 : * $Id: gmlhandler.cpp 20021 2010-07-11 11:56:20Z rouault $
3 : *
4 : * Project: GML Reader
5 : * Purpose: Implementation of GMLHandler class.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : **********************************************************************
9 : * Copyright (c) 2002, Frank Warmerdam
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 OR
22 : * 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 : #include <ctype.h>
31 : #include "gmlreaderp.h"
32 : #include "cpl_conv.h"
33 : #include "cpl_string.h"
34 :
35 : #if HAVE_XERCES == 1
36 :
37 : /* Must be a multiple of 4 */
38 : #define MAX_TOKEN_SIZE 1000
39 :
40 : /************************************************************************/
41 : /* GMLXercesHandler() */
42 : /************************************************************************/
43 :
44 27 : GMLXercesHandler::GMLXercesHandler( GMLReader *poReader ) : GMLHandler(poReader)
45 : {
46 27 : m_nEntityCounter = 0;
47 27 : }
48 :
49 : /************************************************************************/
50 : /* startElement() */
51 : /************************************************************************/
52 :
53 : void GMLXercesHandler::startElement(const XMLCh* const uri,
54 : const XMLCh* const localname,
55 : const XMLCh* const qname,
56 780 : const Attributes& attrs )
57 :
58 : {
59 : char szElementName[MAX_TOKEN_SIZE];
60 :
61 780 : m_nEntityCounter = 0;
62 :
63 : /* A XMLCh character can expand to 4 bytes in UTF-8 */
64 780 : if (4 * tr_strlen( localname ) >= MAX_TOKEN_SIZE)
65 : {
66 : static int bWarnOnce = FALSE;
67 0 : XMLCh* tempBuffer = (XMLCh*) CPLMalloc(sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4 + 1));
68 0 : memcpy(tempBuffer, localname, sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4));
69 0 : tempBuffer[MAX_TOKEN_SIZE / 4] = 0;
70 0 : tr_strcpy( szElementName, tempBuffer );
71 0 : CPLFree(tempBuffer);
72 0 : if (!bWarnOnce)
73 : {
74 0 : bWarnOnce = TRUE;
75 0 : CPLError(CE_Warning, CPLE_AppDefined, "A too big element name has been truncated");
76 : }
77 : }
78 : else
79 780 : tr_strcpy( szElementName, localname );
80 :
81 780 : if (GMLHandler::startElement(szElementName, (void*) &attrs) == CE_Failure)
82 : {
83 0 : throw SAXNotSupportedException("Out of memory");
84 : }
85 780 : }
86 :
87 : /************************************************************************/
88 : /* endElement() */
89 : /************************************************************************/
90 : void GMLXercesHandler::endElement(const XMLCh* const uri,
91 : const XMLCh* const localname,
92 768 : const XMLCh* const qname )
93 :
94 : {
95 : char szElementName[MAX_TOKEN_SIZE];
96 :
97 768 : m_nEntityCounter = 0;
98 :
99 : /* A XMLCh character can expand to 4 bytes in UTF-8 */
100 768 : if (4 * tr_strlen( localname ) >= MAX_TOKEN_SIZE)
101 : {
102 0 : XMLCh* tempBuffer = (XMLCh*) CPLMalloc(sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4 + 1));
103 0 : memcpy(tempBuffer, localname, sizeof(XMLCh) * (MAX_TOKEN_SIZE / 4));
104 0 : tempBuffer[MAX_TOKEN_SIZE / 4] = 0;
105 0 : tr_strcpy( szElementName, tempBuffer );
106 0 : CPLFree(tempBuffer);
107 : }
108 : else
109 768 : tr_strcpy( szElementName, localname );
110 :
111 768 : if (GMLHandler::endElement(szElementName) == CE_Failure)
112 : {
113 0 : throw SAXNotSupportedException("Out of memory");
114 : }
115 768 : }
116 :
117 : #if XERCES_VERSION_MAJOR >= 3
118 : /************************************************************************/
119 : /* characters() (xerces 3 version) */
120 : /************************************************************************/
121 :
122 : void GMLXercesHandler::characters(const XMLCh* const chars_in,
123 : const XMLSize_t length )
124 : {
125 : char* utf8String = tr_strdup(chars_in);
126 : int nLen = strlen(utf8String);
127 : OGRErr eErr = GMLHandler::dataHandler(utf8String, nLen);
128 : CPLFree(utf8String);
129 : if (eErr == CE_Failure)
130 : {
131 : throw SAXNotSupportedException("Out of memory");
132 : }
133 : }
134 :
135 : #else
136 : /************************************************************************/
137 : /* characters() (xerces 2 version) */
138 : /************************************************************************/
139 :
140 : void GMLXercesHandler::characters(const XMLCh* const chars_in,
141 1523 : const unsigned int length )
142 :
143 : {
144 1523 : char* utf8String = tr_strdup(chars_in);
145 1523 : int nLen = strlen(utf8String);
146 1523 : OGRErr eErr = GMLHandler::dataHandler(utf8String, nLen);
147 1523 : CPLFree(utf8String);
148 1523 : if (eErr == CE_Failure)
149 : {
150 0 : throw SAXNotSupportedException("Out of memory");
151 : }
152 1523 : }
153 : #endif
154 :
155 : /************************************************************************/
156 : /* fatalError() */
157 : /************************************************************************/
158 :
159 0 : void GMLXercesHandler::fatalError( const SAXParseException &exception)
160 :
161 : {
162 : char *pszErrorMessage;
163 :
164 0 : pszErrorMessage = tr_strdup( exception.getMessage() );
165 : CPLError( CE_Failure, CPLE_AppDefined,
166 : "XML Parsing Error: %s\n",
167 0 : pszErrorMessage );
168 :
169 0 : CPLFree( pszErrorMessage );
170 0 : }
171 :
172 : /************************************************************************/
173 : /* startEntity() */
174 : /************************************************************************/
175 :
176 0 : void GMLXercesHandler::startEntity (const XMLCh *const name)
177 : {
178 0 : m_nEntityCounter ++;
179 0 : if (m_nEntityCounter > 1000 && !m_poReader->HasStoppedParsing())
180 : {
181 0 : throw SAXNotSupportedException("File probably corrupted (million laugh pattern)");
182 : }
183 0 : }
184 :
185 : /************************************************************************/
186 : /* GetFID() */
187 : /************************************************************************/
188 :
189 60 : char* GMLXercesHandler::GetFID(void* attr)
190 : {
191 60 : const Attributes* attrs = (const Attributes*) attr;
192 : int nFIDIndex;
193 : XMLCh anFID[100];
194 :
195 60 : tr_strcpy( anFID, "fid" );
196 60 : nFIDIndex = attrs->getIndex( anFID );
197 60 : if( nFIDIndex != -1 )
198 54 : return tr_strdup( attrs->getValue( nFIDIndex ) );
199 :
200 6 : return NULL;
201 : }
202 :
203 : /************************************************************************/
204 : /* GetAttributes() */
205 : /************************************************************************/
206 :
207 144 : char* GMLXercesHandler::GetAttributes(void* attr)
208 : {
209 144 : const Attributes* attrs = (const Attributes*) attr;
210 144 : CPLString osRes;
211 : char *pszString;
212 :
213 159 : for(unsigned int i=0; i < attrs->getLength(); i++)
214 : {
215 15 : osRes += " ";
216 15 : pszString = tr_strdup(attrs->getQName(i));
217 15 : osRes += pszString;
218 15 : CPLFree( pszString );
219 15 : osRes += "=\"";
220 15 : pszString = tr_strdup(attrs->getValue(i));
221 15 : osRes += pszString;
222 15 : CPLFree( pszString );
223 15 : osRes += "\"";
224 : }
225 144 : return CPLStrdup(osRes);
226 : }
227 :
228 : #else
229 :
230 :
231 : /************************************************************************/
232 : /* GMLExpatHandler() */
233 : /************************************************************************/
234 :
235 : GMLExpatHandler::GMLExpatHandler( GMLReader *poReader, XML_Parser oParser ) : GMLHandler(poReader)
236 :
237 : {
238 : m_oParser = oParser;
239 : m_bStopParsing = FALSE;
240 : m_nDataHandlerCounter = 0;
241 : }
242 :
243 : /************************************************************************/
244 : /* startElement() */
245 : /************************************************************************/
246 :
247 : OGRErr GMLExpatHandler::startElement(const char *pszName, void* attr )
248 :
249 : {
250 : if (m_bStopParsing)
251 : return CE_Failure;
252 :
253 : const char* pszColon = strchr(pszName, ':');
254 : if (pszColon)
255 : pszName = pszColon + 1;
256 :
257 : if (GMLHandler::startElement(pszName, attr) == CE_Failure)
258 : {
259 : CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
260 : m_bStopParsing = TRUE;
261 : XML_StopParser(m_oParser, XML_FALSE);
262 : return CE_Failure;
263 : }
264 :
265 : return CE_None;
266 : }
267 :
268 : /************************************************************************/
269 : /* endElement() */
270 : /************************************************************************/
271 : OGRErr GMLExpatHandler::endElement(const char* pszName )
272 :
273 : {
274 : if (m_bStopParsing)
275 : return CE_Failure;
276 :
277 : const char* pszColon = strchr(pszName, ':');
278 : if (pszColon)
279 : pszName = pszColon + 1;
280 :
281 : if (GMLHandler::endElement(pszName) == CE_Failure)
282 : {
283 : CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
284 : m_bStopParsing = TRUE;
285 : XML_StopParser(m_oParser, XML_FALSE);
286 : return CE_Failure;
287 : }
288 :
289 : return CE_None;
290 : }
291 :
292 : /************************************************************************/
293 : /* characters() */
294 : /************************************************************************/
295 :
296 : OGRErr GMLExpatHandler::dataHandler(const char *data, int nLen)
297 :
298 : {
299 : if (m_bStopParsing)
300 : return CE_Failure;
301 :
302 : m_nDataHandlerCounter ++;
303 : if (m_nDataHandlerCounter >= BUFSIZ)
304 : {
305 : CPLError(CE_Failure, CPLE_AppDefined, "File probably corrupted (million laugh pattern)");
306 : m_bStopParsing = TRUE;
307 : XML_StopParser(m_oParser, XML_FALSE);
308 : return CE_Failure;
309 : }
310 :
311 : if (GMLHandler::dataHandler(data, nLen) == CE_Failure)
312 : {
313 : CPLError(CE_Failure, CPLE_OutOfMemory, "Out of memory");
314 : m_bStopParsing = TRUE;
315 : XML_StopParser(m_oParser, XML_FALSE);
316 : return CE_Failure;
317 : }
318 :
319 : return CE_None;
320 : }
321 :
322 : /************************************************************************/
323 : /* GetFID() */
324 : /************************************************************************/
325 :
326 : char* GMLExpatHandler::GetFID(void* attr)
327 : {
328 : const char** papszIter = (const char** )attr;
329 : while(*papszIter)
330 : {
331 : if (strcmp(*papszIter, "fid") == 0)
332 : {
333 : return CPLStrdup(papszIter[1]);
334 : }
335 :
336 : papszIter += 2;
337 : }
338 : return NULL;
339 : }
340 :
341 : /************************************************************************/
342 : /* GetAttributes() */
343 : /************************************************************************/
344 :
345 : char* GMLExpatHandler::GetAttributes(void* attr)
346 : {
347 : const char** papszIter = (const char** )attr;
348 : CPLString osRes;
349 : while(*papszIter)
350 : {
351 : osRes += " ";
352 : osRes += *papszIter;
353 : osRes += "=\"";
354 : osRes += papszIter[1];
355 : osRes += "\"";
356 :
357 : papszIter += 2;
358 : }
359 : return CPLStrdup( osRes );
360 : }
361 :
362 : #endif
363 :
364 :
365 :
366 : /************************************************************************/
367 : /* GMLHandler() */
368 : /************************************************************************/
369 :
370 27 : GMLHandler::GMLHandler( GMLReader *poReader )
371 :
372 : {
373 27 : m_poReader = poReader;
374 27 : m_pszCurField = NULL;
375 27 : m_pszGeometry = NULL;
376 27 : m_nGeomAlloc = m_nGeomLen = 0;
377 27 : m_nDepthFeature = m_nDepth = 0;
378 27 : }
379 :
380 : /************************************************************************/
381 : /* ~GMLHandler() */
382 : /************************************************************************/
383 :
384 27 : GMLHandler::~GMLHandler()
385 :
386 : {
387 27 : CPLFree( m_pszCurField );
388 27 : CPLFree( m_pszGeometry );
389 27 : }
390 :
391 :
392 : /************************************************************************/
393 : /* startElement() */
394 : /************************************************************************/
395 :
396 780 : OGRErr GMLHandler::startElement(const char *pszName, void* attr )
397 :
398 : {
399 780 : GMLReadState *poState = m_poReader->GetState();
400 :
401 780 : int nLNLenBytes = strlen(pszName);
402 :
403 : /* -------------------------------------------------------------------- */
404 : /* If we are in the midst of collecting a feature attribute */
405 : /* value, then this must be a complex attribute which we don't */
406 : /* try to collect for now, so just terminate the field */
407 : /* collection. */
408 : /* -------------------------------------------------------------------- */
409 780 : if( m_pszCurField != NULL )
410 : {
411 56 : CPLFree( m_pszCurField );
412 56 : m_pszCurField = NULL;
413 : }
414 :
415 : /* -------------------------------------------------------------------- */
416 : /* If we are collecting geometry, or if we determine this is a */
417 : /* geometry element then append to the geometry info. */
418 : /* -------------------------------------------------------------------- */
419 780 : if( m_pszGeometry != NULL
420 : || IsGeometryElement( pszName ) )
421 : {
422 : /* should save attributes too! */
423 :
424 : int bReadGeometry;
425 :
426 146 : if( m_pszGeometry == NULL )
427 : {
428 : /* If the <GeometryElementPath> is defined in the .gfs, use it */
429 : /* to read the appropriate geometry element */
430 : const char* pszGeometryElement = (poState->m_poFeature) ?
431 68 : poState->m_poFeature->GetClass()->GetGeometryElement() : NULL;
432 68 : if (pszGeometryElement != NULL)
433 4 : bReadGeometry = strcmp(poState->m_pszPath, pszGeometryElement) == 0;
434 : else
435 64 : bReadGeometry = TRUE;
436 68 : if (bReadGeometry)
437 66 : m_nGeometryDepth = poState->m_nPathLength;
438 : }
439 : else
440 78 : bReadGeometry = TRUE;
441 :
442 146 : if (bReadGeometry)
443 : {
444 144 : char* pszAttributes = GetAttributes(attr);
445 :
446 144 : if( m_nGeomLen + nLNLenBytes + 4 + strlen( pszAttributes ) >
447 : m_nGeomAlloc )
448 : {
449 : m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLenBytes + 1000 +
450 66 : strlen( pszAttributes ));
451 : char* pszNewGeometry = (char *)
452 66 : VSIRealloc( m_pszGeometry, m_nGeomAlloc);
453 66 : if (pszNewGeometry == NULL)
454 : {
455 0 : CPLFree(pszAttributes);
456 0 : return CE_Failure;
457 : }
458 66 : m_pszGeometry = pszNewGeometry;
459 : }
460 :
461 144 : strcpy( m_pszGeometry+m_nGeomLen++, "<" );
462 144 : strcpy( m_pszGeometry+m_nGeomLen, pszName );
463 144 : m_nGeomLen += nLNLenBytes;
464 : /* saving attributes */
465 144 : strcat( m_pszGeometry + m_nGeomLen, pszAttributes );
466 144 : m_nGeomLen += strlen( pszAttributes );
467 144 : CPLFree(pszAttributes);
468 144 : strcat( m_pszGeometry + (m_nGeomLen++), ">" );
469 : }
470 : }
471 :
472 : /* -------------------------------------------------------------------- */
473 : /* Is it a feature? If so push a whole new state, and return. */
474 : /* -------------------------------------------------------------------- */
475 634 : else if( m_nDepthFeature == 0 &&
476 : m_poReader->IsFeatureElement( pszName ) )
477 : {
478 60 : char* pszFID = GetFID(attr);
479 :
480 60 : m_poReader->PushFeature( pszName, pszFID);
481 :
482 60 : CPLFree(pszFID);
483 :
484 60 : m_nDepthFeature = m_nDepth;
485 60 : m_nDepth ++;
486 :
487 60 : return CE_None;
488 : }
489 :
490 : /* -------------------------------------------------------------------- */
491 : /* If it is (or at least potentially is) a simple attribute, */
492 : /* then start collecting it. */
493 : /* -------------------------------------------------------------------- */
494 574 : else if( m_poReader->IsAttributeElement( pszName ) )
495 : {
496 274 : CPLFree( m_pszCurField );
497 274 : m_pszCurField = CPLStrdup("");
498 : }
499 :
500 : /* -------------------------------------------------------------------- */
501 : /* Push the element onto the current state's path. */
502 : /* -------------------------------------------------------------------- */
503 720 : poState->PushPath( pszName );
504 :
505 720 : m_nDepth ++;
506 :
507 720 : return CE_None;
508 : }
509 :
510 : /************************************************************************/
511 : /* endElement() */
512 : /************************************************************************/
513 768 : OGRErr GMLHandler::endElement(const char* pszName )
514 :
515 : {
516 768 : m_nDepth --;
517 :
518 768 : GMLReadState *poState = m_poReader->GetState();
519 :
520 768 : int nLNLenBytes = strlen(pszName);
521 :
522 : /* -------------------------------------------------------------------- */
523 : /* Is this closing off an attribute value? We assume so if */
524 : /* we are collecting an attribute value and got to this point. */
525 : /* We don't bother validating that the closing tag matches the */
526 : /* opening tag. */
527 : /* -------------------------------------------------------------------- */
528 768 : if( m_pszCurField != NULL )
529 : {
530 218 : CPLAssert( poState->m_poFeature != NULL );
531 :
532 218 : m_poReader->SetFeatureProperty( poState->m_pszPath, m_pszCurField );
533 218 : CPLFree( m_pszCurField );
534 218 : m_pszCurField = NULL;
535 : }
536 :
537 : /* -------------------------------------------------------------------- */
538 : /* If we are collecting Geometry than store it, and consider if */
539 : /* this is the end of the geometry. */
540 : /* -------------------------------------------------------------------- */
541 768 : if( m_pszGeometry != NULL )
542 : {
543 : /* should save attributes too! */
544 :
545 144 : if( m_nGeomLen + nLNLenBytes + 4 > m_nGeomAlloc )
546 : {
547 0 : m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLenBytes + 1000);
548 : char* pszNewGeometry = (char *)
549 0 : VSIRealloc( m_pszGeometry, m_nGeomAlloc);
550 0 : if (pszNewGeometry == NULL)
551 : {
552 0 : return CE_Failure;
553 : }
554 0 : m_pszGeometry = pszNewGeometry;
555 : }
556 :
557 144 : strcat( m_pszGeometry+m_nGeomLen, "</" );
558 144 : strcpy( m_pszGeometry+m_nGeomLen+2, pszName );
559 144 : strcat( m_pszGeometry+m_nGeomLen+nLNLenBytes+2, ">" );
560 144 : m_nGeomLen += nLNLenBytes + 3;
561 :
562 144 : if( poState->m_nPathLength == m_nGeometryDepth+1 )
563 : {
564 66 : if( poState->m_poFeature != NULL )
565 58 : poState->m_poFeature->SetGeometryDirectly( m_pszGeometry );
566 : else
567 8 : CPLFree( m_pszGeometry );
568 :
569 66 : m_pszGeometry = NULL;
570 66 : m_nGeomAlloc = m_nGeomLen = 0;
571 : }
572 : }
573 :
574 : /* -------------------------------------------------------------------- */
575 : /* If we are collecting a feature, and this element tag matches */
576 : /* element name for the class, then we have finished the */
577 : /* feature, and we pop the feature read state. */
578 : /* -------------------------------------------------------------------- */
579 768 : if( m_nDepth == m_nDepthFeature && poState->m_poFeature != NULL
580 : && strcmp(pszName,
581 : poState->m_poFeature->GetClass()->GetElementName()) == 0 )
582 : {
583 60 : m_nDepthFeature = 0;
584 60 : m_poReader->PopState();
585 : }
586 :
587 : /* -------------------------------------------------------------------- */
588 : /* Otherwise, we just pop the element off the local read states */
589 : /* element stack. */
590 : /* -------------------------------------------------------------------- */
591 : else
592 : {
593 708 : if( strcmp(pszName,poState->GetLastComponent()) == 0 )
594 708 : poState->PopPath();
595 : else
596 : {
597 0 : CPLAssert( FALSE );
598 : }
599 : }
600 :
601 768 : return CE_None;
602 : }
603 :
604 : /************************************************************************/
605 : /* characters() */
606 : /************************************************************************/
607 :
608 1523 : OGRErr GMLHandler::dataHandler(const char *data, int nLen)
609 :
610 : {
611 1523 : int nIter = 0;
612 :
613 1523 : if( m_pszCurField != NULL )
614 : {
615 274 : int nCurFieldLength = strlen(m_pszCurField);
616 :
617 : // Ignore white space
618 274 : if (nCurFieldLength == 0)
619 : {
620 1056 : while (nIter < nLen &&
621 : ( data[nIter] == ' ' || data[nIter] == 10 || data[nIter]== 13 || data[nIter] == '\t') )
622 508 : nIter ++;
623 : }
624 :
625 274 : int nCharsLen = nLen - nIter;
626 :
627 : char *pszNewCurField = (char *)
628 : VSIRealloc( m_pszCurField,
629 274 : nCurFieldLength+ nCharsLen +1 );
630 274 : if (pszNewCurField == NULL)
631 : {
632 0 : return CE_Failure;
633 : }
634 274 : m_pszCurField = pszNewCurField;
635 274 : memcpy( m_pszCurField + nCurFieldLength, data + nIter, nCharsLen);
636 274 : nCurFieldLength += nCharsLen;
637 :
638 274 : m_pszCurField[nCurFieldLength] = '\0';
639 : }
640 1249 : else if( m_pszGeometry != NULL )
641 : {
642 : // Ignore white space
643 222 : if (m_nGeomLen == 0)
644 : {
645 0 : while (nIter < nLen &&
646 : ( data[nIter] == ' ' || data[nIter] == 10 || data[nIter]== 13 || data[nIter] == '\t') )
647 0 : nIter ++;
648 : }
649 :
650 222 : int nCharsLen = nLen - nIter;
651 :
652 222 : if( m_nGeomLen + nCharsLen + 4 > m_nGeomAlloc )
653 : {
654 0 : m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nCharsLen + 1000);
655 : char* pszNewGeometry = (char *)
656 0 : VSIRealloc( m_pszGeometry, m_nGeomAlloc);
657 0 : if (pszNewGeometry == NULL)
658 : {
659 0 : return CE_Failure;
660 : }
661 0 : m_pszGeometry = pszNewGeometry;
662 : }
663 :
664 222 : memcpy( m_pszGeometry+m_nGeomLen, data + nIter, nCharsLen);
665 222 : m_nGeomLen += nCharsLen;
666 222 : m_pszGeometry[m_nGeomLen] = '\0';
667 : }
668 :
669 1523 : return CE_None;
670 : }
671 :
672 :
673 : /************************************************************************/
674 : /* IsGeometryElement() */
675 : /************************************************************************/
676 :
677 702 : int GMLHandler::IsGeometryElement( const char *pszElement )
678 :
679 : {
680 : return strcmp(pszElement,"Polygon") == 0
681 : || strcmp(pszElement,"MultiPolygon") == 0
682 : || strcmp(pszElement,"MultiPoint") == 0
683 : || strcmp(pszElement,"MultiLineString") == 0
684 : || strcmp(pszElement,"MultiSurface") == 0
685 : || strcmp(pszElement,"GeometryCollection") == 0
686 : || strcmp(pszElement,"Point") == 0
687 : || strcmp(pszElement,"Curve") == 0
688 : || strcmp(pszElement,"MultiCurve") == 0
689 : || strcmp(pszElement,"TopoCurve") == 0
690 : || strcmp(pszElement,"Surface") == 0
691 : || strcmp(pszElement,"TopoSurface") == 0
692 : || strcmp(pszElement,"PolygonPatch") == 0
693 702 : || strcmp(pszElement,"LineString") == 0;
694 : }
|