Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgswkbptr.h 3 : : --------------------- 4 : : begin : January 2014 5 : : copyright : (C) 2014 by Juergen E. Fischer 6 : : email : jef at norbit dot de 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 : : #ifndef QGSWKBPTR_H 16 : : #define QGSWKBPTR_H 17 : : 18 : : #include "qgis_core.h" 19 : : #include "qgswkbtypes.h" 20 : : #include "qgis_sip.h" 21 : : #include "qgsexception.h" 22 : : #include "qpolygon.h" 23 : : 24 : : /** 25 : : * \ingroup core 26 : : * \brief Custom exception class for Wkb related exceptions. 27 : : * \note not available in Python bindings 28 : : */ 29 : : #ifndef SIP_RUN 30 : 2 : class CORE_EXPORT QgsWkbException : public QgsException 31 : : { 32 : : public: 33 : 2 : QgsWkbException( QString const &what ) : QgsException( what ) {} 34 : : }; 35 : : #endif 36 : : 37 : : 38 : : /** 39 : : * \ingroup core 40 : : * \class QgsWkbPtr 41 : : * \brief WKB pointer handler. 42 : : */ 43 : : class CORE_EXPORT QgsWkbPtr 44 : : { 45 : : mutable unsigned char *mP; 46 : : unsigned char *mStart; 47 : : unsigned char *mEnd; 48 : : 49 : : void verifyBound( int size ) const; 50 : : 51 : : template<typename T> void read( T &v ) const 52 : : { 53 : : verifyBound( sizeof v ); 54 : : memcpy( &v, mP, sizeof v ); 55 : : mP += sizeof v; 56 : : } 57 : : 58 : 1677 : template<typename T> void write( T &v ) const 59 : : { 60 : 1677 : verifyBound( sizeof v ); 61 : 1677 : memcpy( mP, &v, sizeof v ); 62 : 1677 : mP += sizeof v; 63 : 1677 : } 64 : : 65 : 87 : void write( const QByteArray &data ) const 66 : : { 67 : 87 : verifyBound( data.length() ); 68 : 87 : memcpy( mP, data.constData(), data.length() ); 69 : 87 : mP += data.length(); 70 : 87 : } 71 : : 72 : : public: 73 : : //! Construct WKB pointer from QByteArray 74 : : QgsWkbPtr( QByteArray &wkb ) SIP_SKIP; 75 : : 76 : : QgsWkbPtr( unsigned char *p SIP_ARRAY, int size SIP_ARRAYSIZE ); 77 : : 78 : : inline const QgsWkbPtr &operator>>( double &v ) const { read( v ); return *this; } SIP_SKIP 79 : : inline const QgsWkbPtr &operator>>( float &r ) const { double v; read( v ); r = v; return *this; } SIP_SKIP 80 : : inline const QgsWkbPtr &operator>>( int &v ) const { read( v ); return *this; } SIP_SKIP 81 : : #ifndef Q_PROCESSOR_X86_32 82 : : //! Reads an integer value into a qsizetype 83 : : inline const QgsWkbPtr &operator>>( qsizetype &r ) const { int v; read( v ); r = v; return *this; } SIP_SKIP 84 : : #endif 85 : : inline const QgsWkbPtr &operator>>( unsigned int &v ) const { read( v ); return *this; } SIP_SKIP 86 : : inline const QgsWkbPtr &operator>>( char &v ) const { read( v ); return *this; } SIP_SKIP 87 : : inline const QgsWkbPtr &operator>>( QgsWkbTypes::Type &v ) const { read( v ); return *this; } SIP_SKIP 88 : : 89 : : //! Writes a double to the pointer 90 : 1167 : inline QgsWkbPtr &operator<<( double v ) { write( v ); return *this; } SIP_SKIP 91 : : //! Writes a float to the pointer 92 : : inline QgsWkbPtr &operator<<( float r ) { double v = r; write( v ); return *this; } SIP_SKIP 93 : : //! Writes an int to the pointer 94 : 1 : inline QgsWkbPtr &operator<<( int v ) { write( v ); return *this; } SIP_SKIP 95 : : #ifndef Q_PROCESSOR_X86_32 96 : : //! Writes a size as int to the pointer 97 : : inline QgsWkbPtr &operator<<( qsizetype r ) { int v = r; write( v ); return *this; } SIP_SKIP 98 : : #endif 99 : : //! Writes an unsigned int to the pointer 100 : 342 : inline QgsWkbPtr &operator<<( unsigned int v ) { write( v ); return *this; } SIP_SKIP 101 : : //! Writes a char to the pointer 102 : 165 : inline QgsWkbPtr &operator<<( char v ) { write( v ); return *this; } SIP_SKIP 103 : : //! Writes a WKB type value to the pointer 104 : 2 : inline QgsWkbPtr &operator<<( QgsWkbTypes::Type v ) { write( v ); return *this; } SIP_SKIP 105 : : //! Append data from a byte array 106 : 87 : inline QgsWkbPtr &operator<<( const QByteArray &data ) { write( data ); return *this; } SIP_SKIP 107 : : 108 : 0 : inline void operator+=( int n ) { verifyBound( n ); mP += n; } SIP_SKIP 109 : : 110 : 0 : inline operator unsigned char *() const { return mP; } SIP_SKIP 111 : : 112 : : /** 113 : : * \brief size 114 : : * \note not available in Python bindings 115 : : */ 116 : 0 : inline int size() const { return mEnd - mStart; } SIP_SKIP 117 : : 118 : : /** 119 : : * \brief remaining 120 : : * \note not available in Python bindings 121 : : */ 122 : : inline int remaining() const { return mEnd - mP; } SIP_SKIP 123 : : 124 : : /** 125 : : * \brief writtenSize 126 : : * \note not available in Python bindings 127 : : */ 128 : : inline int writtenSize() const { return mP - mStart; } SIP_SKIP 129 : : }; 130 : : 131 : : /** 132 : : * \ingroup core 133 : : * \class QgsConstWkbPtr 134 : : * \brief A const WKB pointer. 135 : : */ 136 : : 137 : : class CORE_EXPORT QgsConstWkbPtr 138 : : { 139 : : protected: 140 : : mutable unsigned char *mP; 141 : : unsigned char *mEnd; 142 : : mutable bool mEndianSwap; 143 : : mutable QgsWkbTypes::Type mWkbType; 144 : : 145 : : /** 146 : : * \brief Verify bounds 147 : : * \note not available in Python bindings 148 : : */ 149 : : void verifyBound( int size ) const SIP_SKIP; 150 : : 151 : : /** 152 : : * \brief Read a value 153 : : * \note not available in Python bindings 154 : : */ 155 : 1425 : template<typename T> void read( T &v ) const SIP_SKIP 156 : : { 157 : 1425 : verifyBound( sizeof v ); 158 : 1425 : memcpy( &v, mP, sizeof( v ) ); 159 : 1425 : mP += sizeof( v ); 160 : 1425 : if ( mEndianSwap ) 161 : 0 : endian_swap( v ); 162 : 1423 : } 163 : : 164 : : public: 165 : : //! Construct WKB pointer from QByteArray 166 : : explicit QgsConstWkbPtr( const QByteArray &wkb ) SIP_SKIP; 167 : : QgsConstWkbPtr( const unsigned char *p SIP_ARRAY, int size SIP_ARRAYSIZE ); 168 : : 169 : : /** 170 : : * \brief readHeader 171 : : * \note not available in Python bindings 172 : : */ 173 : : QgsWkbTypes::Type readHeader() const SIP_SKIP; 174 : : 175 : 878 : inline const QgsConstWkbPtr &operator>>( double &v ) const { read( v ); return *this; } SIP_SKIP 176 : : inline const QgsConstWkbPtr &operator>>( float &r ) const { double v; read( v ); r = v; return *this; } SIP_SKIP 177 : 339 : inline const QgsConstWkbPtr &operator>>( int &v ) const { read( v ); return *this; } SIP_SKIP 178 : : inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { read( v ); return *this; } SIP_SKIP 179 : 208 : inline const QgsConstWkbPtr &operator>>( char &v ) const { read( v ); return *this; } SIP_SKIP 180 : : 181 : : //! Read a point 182 : : const QgsConstWkbPtr &operator>>( QPointF &point ) const; SIP_SKIP 183 : : //! Read a point array 184 : : const QgsConstWkbPtr &operator>>( QPolygonF &points ) const; SIP_SKIP 185 : : 186 : 0 : inline void operator+=( int n ) { verifyBound( n ); mP += n; } SIP_SKIP 187 : 74 : inline void operator-=( int n ) { mP -= n; } SIP_SKIP 188 : : 189 : 186 : inline operator const unsigned char *() const { return mP; } SIP_SKIP 190 : : 191 : : /** 192 : : * \brief remaining 193 : : * \note not available in Python bindings 194 : : */ 195 : : inline int remaining() const { return mEnd - mP; } SIP_SKIP 196 : : 197 : : private: 198 : 0 : template<typename T> void endian_swap( T &value ) const SIP_SKIP 199 : : { 200 : 0 : char *data = reinterpret_cast<char *>( &value ); 201 : 0 : std::size_t n = sizeof( value ); 202 : 0 : for ( std::size_t i = 0, m = n / 2; i < m; ++i ) 203 : : { 204 : 0 : std::swap( data[i], data[n - 1 - i] ); 205 : 0 : } 206 : 0 : } 207 : : }; 208 : : 209 : : #endif // QGSWKBPTR_H