OGRErr OGRGeometryCollection::importFromWkbInternal( const unsigned char * pabyData, int nSize, int nRecLevel, OGRwkbVariant eWkbVariant, int& nBytesConsumedOut ) { nBytesConsumedOut = -1; // Arbitrary value, but certainly large enough for reasonable use cases. if( nRecLevel == 32 ) { CPLError( CE_Failure, CPLE_AppDefined, "Too many recursion levels (%d) while parsing WKB geometry.", nRecLevel ); return OGRERR_CORRUPT_DATA; } nGeomCount = 0; OGRwkbByteOrder eByteOrder = wkbXDR; int nDataOffset = 0; OGRErr eErr = importPreambleOfCollectionFromWkb( pabyData, nSize, nDataOffset, eByteOrder, 9, nGeomCount, eWkbVariant ); if( eErr != OGRERR_NONE ) return eErr; // coverity[tainted_data] papoGeoms = static_cast<OGRGeometry **>( VSI_CALLOC_VERBOSE(sizeof(void*), nGeomCount)); if( nGeomCount != 0 && papoGeoms == nullptr ) { nGeomCount = 0; return OGRERR_NOT_ENOUGH_MEMORY; } /* -------------------------------------------------------------------- */ /* Get the Geoms. */ /* -------------------------------------------------------------------- */ for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { // Parses sub-geometry. const unsigned char* pabySubData = pabyData + nDataOffset; if( nSize < 9 && nSize != -1 ) return OGRERR_NOT_ENOUGH_DATA; OGRwkbGeometryType eSubGeomType = wkbUnknown; eErr = OGRReadWKBGeometryType( pabySubData, eWkbVariant, &eSubGeomType ); if( eErr != OGRERR_NONE ) return eErr; if( !isCompatibleSubType(eSubGeomType) ) { nGeomCount = iGeom; CPLDebug( "OGR", "Cannot add geometry of type (%d) to geometry of type (%d)", eSubGeomType, getGeometryType()); return OGRERR_CORRUPT_DATA; } OGRGeometry* poSubGeom = nullptr; int nSubGeomBytesConsumed = -1; if( OGR_GT_IsSubClassOf(eSubGeomType, wkbGeometryCollection) ) { poSubGeom = OGRGeometryFactory::createGeometry( eSubGeomType ); if( poSubGeom == nullptr ) eErr = OGRERR_FAILURE; else eErr = poSubGeom->toGeometryCollection()-> importFromWkbInternal( pabySubData, nSize, nRecLevel + 1, eWkbVariant, nSubGeomBytesConsumed ); } else { eErr = OGRGeometryFactory:: createFromWkb( pabySubData, nullptr, &poSubGeom, nSize, eWkbVariant, nSubGeomBytesConsumed ); } if( eErr != OGRERR_NONE ) { nGeomCount = iGeom; delete poSubGeom; return eErr; } papoGeoms[iGeom] = poSubGeom; if( papoGeoms[iGeom]->Is3D() ) flags |= OGR_G_3D; if( papoGeoms[iGeom]->IsMeasured() ) flags |= OGR_G_MEASURED; CPLAssert( nSubGeomBytesConsumed > 0 ); if( nSize != -1 ) { CPLAssert( nSize >= nSubGeomBytesConsumed ); nSize -= nSubGeomBytesConsumed; } nDataOffset += nSubGeomBytesConsumed; } nBytesConsumedOut = nDataOffset; return OGRERR_NONE; }
TABFeature* IMapInfoFile::CreateTABFeature(OGRFeature *poFeature) { TABFeature *poTABFeature = nullptr; OGRwkbGeometryType eGType; TABPoint *poTABPointFeature = nullptr; TABRegion *poTABRegionFeature = nullptr; TABPolyline *poTABPolylineFeature = nullptr; /*----------------------------------------------------------------- * MITAB won't accept new features unless they are in a type derived * from TABFeature... so we have to do our best to map to the right * feature type based on the geometry type. *----------------------------------------------------------------*/ OGRGeometry* poGeom = poFeature->GetGeometryRef(); if( poGeom != nullptr ) eGType = poGeom->getGeometryType(); else eGType = wkbNone; switch( wkbFlatten(eGType) ) { /*------------------------------------------------------------- * POINT *------------------------------------------------------------*/ case wkbPoint: poTABFeature = new TABPoint(poFeature->GetDefnRef()); if(poFeature->GetStyleString()) { poTABPointFeature = cpl::down_cast<TABPoint*>(poTABFeature); poTABPointFeature->SetSymbolFromStyleString( poFeature->GetStyleString()); } break; /*------------------------------------------------------------- * REGION *------------------------------------------------------------*/ case wkbPolygon: case wkbMultiPolygon: poTABFeature = new TABRegion(poFeature->GetDefnRef()); if(poFeature->GetStyleString()) { poTABRegionFeature = cpl::down_cast<TABRegion*>(poTABFeature); poTABRegionFeature->SetPenFromStyleString( poFeature->GetStyleString()); poTABRegionFeature->SetBrushFromStyleString( poFeature->GetStyleString()); } break; /*------------------------------------------------------------- * LINE/PLINE/MULTIPLINE *------------------------------------------------------------*/ case wkbLineString: case wkbMultiLineString: poTABFeature = new TABPolyline(poFeature->GetDefnRef()); if(poFeature->GetStyleString()) { poTABPolylineFeature = cpl::down_cast<TABPolyline*>(poTABFeature); poTABPolylineFeature->SetPenFromStyleString( poFeature->GetStyleString()); } break; /*------------------------------------------------------------- * Collection types that are not directly supported... convert * to multiple features in output file through recursive calls. *------------------------------------------------------------*/ case wkbGeometryCollection: case wkbMultiPoint: { OGRErr eStatus = OGRERR_NONE; assert(poGeom); // for clang static analyzer OGRGeometryCollection *poColl = poGeom->toGeometryCollection(); OGRFeature *poTmpFeature = poFeature->Clone(); for( int i = 0; eStatus==OGRERR_NONE && poColl != nullptr && i<poColl->getNumGeometries(); i++) { poTmpFeature->SetFID(OGRNullFID); poTmpFeature->SetGeometry(poColl->getGeometryRef(i)); eStatus = ICreateFeature(poTmpFeature); } delete poTmpFeature; return nullptr; } break; /*------------------------------------------------------------- * Unsupported type.... convert to MapInfo geometry NONE *------------------------------------------------------------*/ case wkbUnknown: default: poTABFeature = new TABFeature(poFeature->GetDefnRef()); break; } if( poGeom != nullptr ) poTABFeature->SetGeometryDirectly(poGeom->clone()); for (int i=0; i< poFeature->GetDefnRef()->GetFieldCount();i++) { poTABFeature->SetField(i,poFeature->GetRawFieldRef( i )); } poTABFeature->SetFID(poFeature->GetFID()); return poTABFeature; }