OGRErr OGRGeometryCollection::addGeometryDirectly( OGRGeometry * poNewGeom ) { if( !isCompatibleSubType(poNewGeom->getGeometryType()) ) return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; if( poNewGeom->Is3D() && !Is3D() ) set3D(TRUE); if( poNewGeom->IsMeasured() && !IsMeasured() ) setMeasured(TRUE); if( !poNewGeom->Is3D() && Is3D() ) poNewGeom->set3D(TRUE); if( !poNewGeom->IsMeasured() && IsMeasured() ) poNewGeom->setMeasured(TRUE); OGRGeometry** papoNewGeoms = (OGRGeometry **) VSI_REALLOC_VERBOSE( papoGeoms, sizeof(void*) * (nGeomCount+1) ); if( papoNewGeoms == NULL ) return OGRERR_FAILURE; papoGeoms = papoNewGeoms; papoGeoms[nGeomCount] = poNewGeom; nGeomCount++; return OGRERR_NONE; }
OGRErr OGRGeometryCollection::addGeometryDirectly( OGRGeometry * poNewGeom ) { if( !isCompatibleSubType(poNewGeom->getGeometryType()) ) return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; HomogenizeDimensionalityWith(poNewGeom); OGRGeometry** papoNewGeoms = static_cast<OGRGeometry **>( VSI_REALLOC_VERBOSE(papoGeoms, sizeof(void*) * (nGeomCount + 1))); if( papoNewGeoms == nullptr ) return OGRERR_FAILURE; papoGeoms = papoNewGeoms; papoGeoms[nGeomCount] = poNewGeom; nGeomCount++; return OGRERR_NONE; }
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; }