示例#1
0
OGRErr OGRCurveCollection::importBodyFromWkb( OGRGeometry* poGeom,
                                       unsigned char * pabyData,
                                       int nSize,
                                       int nDataOffset,
                                       int bAcceptCompoundCurve,
                                       OGRErr (*pfnAddCurveDirectlyFromWkb)(OGRGeometry* poGeom, OGRCurve* poCurve),
                                       OGRwkbVariant eWkbVariant )
{

/* -------------------------------------------------------------------- */
/*      Get the Geoms.                                                  */
/* -------------------------------------------------------------------- */
    int nIter = nCurveCount;
    nCurveCount = 0;
    for( int iGeom = 0; iGeom < nIter; iGeom++ )
    {
        OGRErr  eErr;
        OGRGeometry* poSubGeom = NULL;

        /* Parses sub-geometry */
        unsigned char* pabySubData = pabyData + nDataOffset;
        if( nSize < 9 && nSize != -1 )
            return OGRERR_NOT_ENOUGH_DATA;

        OGRwkbGeometryType eSubGeomType;
        OGRBoolean bIs3D;
        if ( OGRReadWKBGeometryType( pabySubData, eWkbVariant, &eSubGeomType, &bIs3D ) != OGRERR_NONE )
            return OGRERR_FAILURE;

        if( (eSubGeomType != wkbCompoundCurve && OGR_GT_IsCurve(eSubGeomType)) ||
            (bAcceptCompoundCurve && eSubGeomType == wkbCompoundCurve) )
        {
            eErr = OGRGeometryFactory::
                createFromWkb( pabySubData, NULL,
                               &poSubGeom, nSize, eWkbVariant );
        }
        else
        {
            CPLDebug("OGR", "Cannot add geometry of type (%d) to geometry of type (%d)",
                     eSubGeomType, poGeom->getGeometryType());
            return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
        }

        if( eErr == OGRERR_NONE )
            eErr = pfnAddCurveDirectlyFromWkb(poGeom, (OGRCurve*)poSubGeom);
        if( eErr != OGRERR_NONE )
        {
            delete poSubGeom;
            return eErr;
        }

        int nSubGeomWkbSize = poSubGeom->WkbSize();
        if( nSize != -1 )
            nSize -= nSubGeomWkbSize;

        nDataOffset += nSubGeomWkbSize;
    }

    return OGRERR_NONE;
}
示例#2
0
OGRErr OGRPoint::importFromWkb( unsigned char * pabyData,
                                int nSize )

{
    OGRwkbByteOrder     eByteOrder;
    
    if( nSize < 21 && nSize != -1 )
        return OGRERR_NOT_ENOUGH_DATA;

/* -------------------------------------------------------------------- */
/*      Get the byte order byte.                                        */
/* -------------------------------------------------------------------- */
    eByteOrder = DB2_V72_FIX_BYTE_ORDER((OGRwkbByteOrder) *pabyData);
    if (!( eByteOrder == wkbXDR || eByteOrder == wkbNDR ))
        return OGRERR_CORRUPT_DATA;

/* -------------------------------------------------------------------- */
/*      Get the geometry feature type.  For now we assume that          */
/*      geometry type is between 0 and 255 so we only have to fetch     */
/*      one byte.                                                       */
/* -------------------------------------------------------------------- */
    OGRBoolean bIs3D;
    OGRwkbGeometryType eGeometryType;
    OGRErr err = OGRReadWKBGeometryType( pabyData, &eGeometryType, &bIs3D );

    if( err != OGRERR_NONE || eGeometryType != wkbPoint )
        return OGRERR_CORRUPT_DATA;

/* -------------------------------------------------------------------- */
/*      Get the vertex.                                                 */
/* -------------------------------------------------------------------- */
    memcpy( &x, pabyData + 5,     8 );
    memcpy( &y, pabyData + 5 + 8, 8 );
    
    if( OGR_SWAP( eByteOrder ) )
    {
        CPL_SWAPDOUBLE( &x );
        CPL_SWAPDOUBLE( &y );
    }

    if( bIs3D )
    {
        if ( nSize < 29 && nSize != -1 )
            return OGRERR_NOT_ENOUGH_DATA;

        memcpy( &z, pabyData + 5 + 16, 8 );
        if( OGR_SWAP( eByteOrder ) )
        {
            CPL_SWAPDOUBLE( &z );
        }
        nCoordDimension = 3;
    }
    else
    {
        z = 0;
        nCoordDimension = 2;
    }

    return OGRERR_NONE;
}
示例#3
0
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;
}