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 : 1633 : template<typename T> void write( T &v ) const 59 : : { 60 : 1633 : verifyBound( sizeof v ); 61 : 1633 : memcpy( mP, &v, sizeof v ); 62 : 1633 : mP += sizeof v; 63 : 1633 : } 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 : : //! Reads an integer value into a qsizetype 82 : : inline const QgsWkbPtr &operator>>( qsizetype &r ) const { int v; read( v ); r = v; return *this; } SIP_SKIP 83 : : inline const QgsWkbPtr &operator>>( unsigned int &v ) const { read( v ); return *this; } SIP_SKIP 84 : : inline const QgsWkbPtr &operator>>( char &v ) const { read( v ); return *this; } SIP_SKIP 85 : : inline const QgsWkbPtr &operator>>( QgsWkbTypes::Type &v ) const { read( v ); return *this; } SIP_SKIP 86 : : 87 : : //! Writes a double to the pointer 88 : 1135 : inline QgsWkbPtr &operator<<( double v ) { write( v ); return *this; } SIP_SKIP 89 : : //! Writes a float to the pointer 90 : : inline QgsWkbPtr &operator<<( float r ) { double v = r; write( v ); return *this; } SIP_SKIP 91 : : //! Writes an int to the pointer 92 : 1 : inline QgsWkbPtr &operator<<( int v ) { write( v ); return *this; } SIP_SKIP 93 : : //! Writes a size as int to the pointer 94 : : inline QgsWkbPtr &operator<<( qsizetype r ) { int v = r; write( v ); return *this; } SIP_SKIP 95 : : //! Writes an unsigned int to the pointer 96 : 333 : inline QgsWkbPtr &operator<<( unsigned int v ) { write( v ); return *this; } SIP_SKIP 97 : : //! Writes a char to the pointer 98 : 162 : inline QgsWkbPtr &operator<<( char v ) { write( v ); return *this; } SIP_SKIP 99 : : //! Writes a WKB type value to the pointer 100 : 2 : inline QgsWkbPtr &operator<<( QgsWkbTypes::Type v ) { write( v ); return *this; } SIP_SKIP 101 : : //! Append data from a byte array 102 : 87 : inline QgsWkbPtr &operator<<( const QByteArray &data ) { write( data ); return *this; } SIP_SKIP 103 : : 104 : 0 : inline void operator+=( int n ) { verifyBound( n ); mP += n; } SIP_SKIP 105 : : 106 : 0 : inline operator unsigned char *() const { return mP; } SIP_SKIP 107 : : 108 : : /** 109 : : * \brief size 110 : : * \note not available in Python bindings 111 : : */ 112 : 0 : inline int size() const { return mEnd - mStart; } SIP_SKIP 113 : : 114 : : /** 115 : : * \brief remaining 116 : : * \note not available in Python bindings 117 : : */ 118 : : inline int remaining() const { return mEnd - mP; } SIP_SKIP 119 : : 120 : : /** 121 : : * \brief writtenSize 122 : : * \note not available in Python bindings 123 : : */ 124 : : inline int writtenSize() const { return mP - mStart; } SIP_SKIP 125 : : }; 126 : : 127 : : /** 128 : : * \ingroup core 129 : : * \class QgsConstWkbPtr 130 : : * \brief A const WKB pointer. 131 : : */ 132 : : 133 : : class CORE_EXPORT QgsConstWkbPtr 134 : : { 135 : : protected: 136 : : mutable unsigned char *mP; 137 : : unsigned char *mEnd; 138 : : mutable bool mEndianSwap; 139 : : mutable QgsWkbTypes::Type mWkbType; 140 : : 141 : : /** 142 : : * \brief Verify bounds 143 : : * \note not available in Python bindings 144 : : */ 145 : : void verifyBound( int size ) const SIP_SKIP; 146 : : 147 : : /** 148 : : * \brief Read a value 149 : : * \note not available in Python bindings 150 : : */ 151 : 1378 : template<typename T> void read( T &v ) const SIP_SKIP 152 : : { 153 : 1378 : verifyBound( sizeof v ); 154 : 1378 : memcpy( &v, mP, sizeof( v ) ); 155 : 1378 : mP += sizeof( v ); 156 : 1378 : if ( mEndianSwap ) 157 : 0 : endian_swap( v ); 158 : 1376 : } 159 : : 160 : : public: 161 : : //! Construct WKB pointer from QByteArray 162 : : explicit QgsConstWkbPtr( const QByteArray &wkb ) SIP_SKIP; 163 : : QgsConstWkbPtr( const unsigned char *p SIP_ARRAY, int size SIP_ARRAYSIZE ); 164 : : 165 : : /** 166 : : * \brief readHeader 167 : : * \note not available in Python bindings 168 : : */ 169 : : QgsWkbTypes::Type readHeader() const SIP_SKIP; 170 : : 171 : 846 : inline const QgsConstWkbPtr &operator>>( double &v ) const { read( v ); return *this; } SIP_SKIP 172 : : inline const QgsConstWkbPtr &operator>>( float &r ) const { double v; read( v ); r = v; return *this; } SIP_SKIP 173 : 328 : inline const QgsConstWkbPtr &operator>>( int &v ) const { read( v ); return *this; } SIP_SKIP 174 : : inline const QgsConstWkbPtr &operator>>( unsigned int &v ) const { read( v ); return *this; } SIP_SKIP 175 : 204 : inline const QgsConstWkbPtr &operator>>( char &v ) const { read( v ); return *this; } SIP_SKIP 176 : : 177 : : //! Read a point 178 : : const QgsConstWkbPtr &operator>>( QPointF &point ) const; SIP_SKIP 179 : : //! Read a point array 180 : : const QgsConstWkbPtr &operator>>( QPolygonF &points ) const; SIP_SKIP 181 : : 182 : 0 : inline void operator+=( int n ) { verifyBound( n ); mP += n; } SIP_SKIP 183 : 74 : inline void operator-=( int n ) { mP -= n; } SIP_SKIP 184 : : 185 : 182 : inline operator const unsigned char *() const { return mP; } SIP_SKIP 186 : : 187 : : /** 188 : : * \brief remaining 189 : : * \note not available in Python bindings 190 : : */ 191 : : inline int remaining() const { return mEnd - mP; } SIP_SKIP 192 : : 193 : : private: 194 : 0 : template<typename T> void endian_swap( T &value ) const SIP_SKIP 195 : : { 196 : 0 : char *data = reinterpret_cast<char *>( &value ); 197 : 0 : std::size_t n = sizeof( value ); 198 : 0 : for ( std::size_t i = 0, m = n / 2; i < m; ++i ) 199 : : { 200 : 0 : std::swap( data[i], data[n - 1 - i] ); 201 : 0 : } 202 : 0 : } 203 : : }; 204 : : 205 : : #endif // QGSWKBPTR_H