19 #include <QStringList>
26 : mFilePath( filePath )
37 const QString columnNameRx( QStringLiteral(
"[a-zA-Z_\x80-\xFF][a-zA-Z0-9_\x80-\xFF]*" ) );
43 const QList<QPair<QString, QString> > items = QUrlQuery( url ).queryItems( QUrl::FullyEncoded );
44 for (
int i = 0; i < items.size(); i++ )
46 QString key = items.
at( i ).first;
47 QString value = items.at( i ).second;
48 if ( key == QLatin1String(
"layer_ref" ) )
52 int pos = value.indexOf(
':' );
53 QString layerId, vlayerName;
57 vlayerName = QStringLiteral(
"vtab%1" ).arg( layerIdx );
61 layerId = value.left( pos );
62 vlayerName = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
67 else if ( key == QLatin1String(
"layer" ) )
71 int pos = value.indexOf(
':' );
74 QString providerKey, source, vlayerName, encoding = QStringLiteral(
"UTF-8" );
76 providerKey = value.left( pos );
77 int pos2 = value.indexOf(
':', pos + 1 );
78 if ( pos2 - pos == 2 )
79 pos2 = value.indexOf(
':', pos + 3 );
82 source = QUrl::fromPercentEncoding( value.mid( pos + 1, pos2 - pos - 1 ).toUtf8() );
83 int pos3 = value.indexOf(
':', pos2 + 1 );
86 vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1, pos3 - pos2 - 1 ).toUtf8() );
87 encoding = value.mid( pos3 + 1 );
91 vlayerName = QUrl::fromPercentEncoding( value.mid( pos2 + 1 ).toUtf8() );
96 source = QUrl::fromPercentEncoding( value.mid( pos + 1 ).toUtf8() );
97 vlayerName = QStringLiteral(
"vtab%1" ).arg( layerIdx );
100 def.
addSource( vlayerName, source, providerKey, encoding );
103 else if ( key == QLatin1String(
"geometry" ) )
107 QRegExp reGeom(
"(" + columnNameRx +
")(?::([a-zA-Z0-9]+):(\\d+))?" );
108 int pos = reGeom.indexIn( value );
112 if ( reGeom.captureCount() > 1 )
125 else if ( key == QLatin1String(
"nogeometry" ) )
129 else if ( key == QLatin1String(
"uid" ) )
133 else if ( key == QLatin1String(
"query" ) )
136 def.
setQuery( QUrl::fromPercentEncoding( value.toUtf8() ) );
138 else if ( key == QLatin1String(
"field" ) )
141 QRegExp reField(
"(" + columnNameRx +
"):(int|real|text)" );
142 int pos = reField.indexIn( value );
145 QString fieldName( reField.cap( 1 ) );
146 QString fieldType( reField.cap( 2 ) );
147 if ( fieldType == QLatin1String(
"int" ) )
151 else if ( fieldType == QLatin1String(
"real" ) )
155 if ( fieldType == QLatin1String(
"text" ) )
161 else if ( key == QLatin1String(
"lazy" ) )
177 return "0123456789ABCDEF"[value & 0xF];
180 static inline ushort encodeNibble( ushort
c )
187 while ( ptr + 4 <= end )
189 quint32 data = qFromUnaligned<quint32>( ptr );
190 if ( data &= 0x80808080U )
192 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
193 uint idx = qCountLeadingZeroBits( data );
195 uint idx = qCountTrailingZeroBits( data );
204 if ( quint8( *ptr ) & 0x80 )
217 const char *in = ba.constData();
218 const char *
const end = ba.constEnd();
222 return QString::fromLatin1( ba, ba.size() );
225 QByteArray intermediate = ba;
226 intermediate.resize( ba.size() * 3 - ( in - ba.constData() ) );
227 uchar *out =
reinterpret_cast<uchar *
>( intermediate.data() + ( in - ba.constData() ) );
228 for ( ; in < end; ++in )
234 *out++ = encodeNibble( uchar( *in ) >> 4 );
235 *out++ = encodeNibble( uchar( *in ) & 0xf );
240 *out++ = uchar( *in );
244 return QString::fromLatin1( intermediate, out -
reinterpret_cast<uchar *
>( intermediate.data() ) );
251 url = QUrl::fromLocalFile(
filePath() );
253 QUrlQuery urlQuery( url );
258 if ( l.isReferenced() )
259 urlQuery.addQueryItem( QStringLiteral(
"layer_ref" ), QStringLiteral(
"%1:%2" ).arg( l.reference(), l.name() ) );
266 QString( QUrl::toPercentEncoding( l.name() ) ),
268 QString( QUrl::toPercentEncoding( l.source() ) ) ).toUtf8() ) );
271 if ( !
query().isEmpty() )
273 urlQuery.addQueryItem( QStringLiteral(
"query" ),
query() );
276 if ( !
uid().isEmpty() )
277 urlQuery.addQueryItem( QStringLiteral(
"uid" ),
uid() );
280 urlQuery.addQueryItem( QStringLiteral(
"nogeometry" ), QString() );
286 urlQuery.addQueryItem( QStringLiteral(
"geometry" ),
geometryField() );
289 const auto constFields =
fields();
290 for (
const QgsField &f : constFields )
292 if ( f.type() == QVariant::Int )
293 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":int" );
294 else if ( f.type() == QVariant::Double )
295 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":real" );
296 else if ( f.type() == QVariant::String )
297 urlQuery.addQueryItem( QStringLiteral(
"field" ), f.name() +
":text" );
302 urlQuery.addQueryItem( QStringLiteral(
"lazy" ), QString() );
305 url.setQuery( urlQuery );
312 return QString(
toUrl().toEncoded() );
322 mSourceLayers.append(
SourceLayer( name, source, provider, encoding ) );
330 if ( l.name() == name )
343 if ( l.isReferenced() )