1 /***************************************************************************
2     qgswkbptr.cpp
3     ---------------------
4     begin                : May 2015
5     copyright            : (C) 2015 by Marco Hugentobler
6     email                : marco dot hugentobler at sourcepole dot ch
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 #include "qgswkbptr.h"
16 #include "qgsapplication.h"
17 
QgsWkbPtr(QByteArray & wkb)18 QgsWkbPtr::QgsWkbPtr( QByteArray &wkb )
19 {
20   mP = reinterpret_cast<unsigned char *>( wkb.data() );
21   mStart = mP;
22   mEnd = mP + wkb.length();
23 }
24 
QgsWkbPtr(unsigned char * p,int size)25 QgsWkbPtr::QgsWkbPtr( unsigned char *p, int size )
26 {
27   mP = p;
28   mStart = mP;
29   mEnd = mP + size;
30 }
31 
verifyBound(int size) const32 void QgsWkbPtr::verifyBound( int size ) const
33 {
34   if ( !mP || mP + size > mEnd )
35     throw QgsWkbException( QStringLiteral( "wkb access out of bounds" ) );
36 }
37 
QgsConstWkbPtr(const QByteArray & wkb)38 QgsConstWkbPtr::QgsConstWkbPtr( const QByteArray &wkb )
39 {
40   mP = reinterpret_cast< unsigned char * >( const_cast<char *>( wkb.constData() ) );
41   mEnd = mP + wkb.length();
42   mEndianSwap = false;
43   mWkbType = QgsWkbTypes::Unknown;
44 }
45 
QgsConstWkbPtr(const unsigned char * p,int size)46 QgsConstWkbPtr::QgsConstWkbPtr( const unsigned char *p, int size )
47 {
48   mP = const_cast< unsigned char * >( p );
49   mEnd = mP + size;
50   mEndianSwap = false;
51   mWkbType = QgsWkbTypes::Unknown;
52 }
53 
readHeader() const54 QgsWkbTypes::Type QgsConstWkbPtr::readHeader() const
55 {
56   if ( !mP )
57     return QgsWkbTypes::Unknown;
58 
59   char wkbEndian;
60   *this >> wkbEndian;
61   mEndianSwap = wkbEndian != QgsApplication::endian();
62 
63   int wkbType;
64   *this >> wkbType;
65   mWkbType = static_cast<QgsWkbTypes::Type>( wkbType );
66 
67   return mWkbType;
68 }
69 
verifyBound(int size) const70 void QgsConstWkbPtr::verifyBound( int size ) const
71 {
72   if ( !mP || mP + size > mEnd )
73     throw QgsWkbException( QStringLiteral( "wkb access out of bounds" ) );
74 }
75 
operator >>(QPointF & point) const76 const QgsConstWkbPtr &QgsConstWkbPtr::operator>>( QPointF &point ) const
77 {
78   read( point.rx() );
79   read( point.ry() );
80   return *this;
81 }
82 
operator >>(QPolygonF & points) const83 const QgsConstWkbPtr &QgsConstWkbPtr::operator>>( QPolygonF &points ) const
84 {
85   const int skipZM = ( QgsWkbTypes::coordDimensions( mWkbType ) - 2 ) * sizeof( double );
86   Q_ASSERT( skipZM >= 0 );
87 
88   unsigned int nPoints;
89   read( nPoints );
90 
91   points.resize( nPoints );
92   QPointF *ptr = points.data();
93 
94   for ( unsigned int i = 0; i < nPoints; ++i, ++ptr )
95   {
96     read( ptr->rx() );
97     read( ptr->ry() );
98     mP += skipZM;
99   }
100   return *this;
101 }
102