QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgshstoreutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgshstoreutils.h
3 ---------------------
4 begin : Sept 2018
5 copyright : (C) 2018 by Mathieu Pellerin
6 email : nirvn dot asia at gmail dot com
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
16#include "qgshstoreutils.h"
17
18#include <QRegularExpression>
19
20QVariantMap QgsHstoreUtils::parse( const QString &string )
21{
22 QVariantMap map;
23 QList<QString> bits;
24 static const QList<QString > sSeps{ "=>", "," };
25
26 int i = 0;
27 while ( i < string.length() )
28 {
29 while ( i < string.length() && string.at( i ).isSpace() )
30 ++i;
31 const QString current = string.mid( i );
32 const QString sep = sSeps.at( bits.length() );
33 if ( current.startsWith( '"' ) )
34 {
35 const thread_local QRegularExpression re( QStringLiteral( "^\"((?:\\\\.|[^\"\\\\])*)\".*" ) );
36 const QRegularExpressionMatch match = re.match( current );
37 bits << QString();
38 if ( match.hasMatch() )
39 {
40 bits[bits.length() - 1] = match.captured( 1 ).replace( QLatin1String( "\\\"" ), QLatin1String( "\"" ) ).replace( QLatin1String( "\\\\" ), QLatin1String( "\\" ) );
41 i += match.captured( 1 ).length() + 2;
42 while ( i < string.length() && string.at( i ).isSpace() )
43 ++i;
44
45 if ( QStringView{string}.mid( i ).startsWith( sep ) )
46 {
47 i += sep.length();
48 }
49 else if ( i < string.length() )
50 {
51 // hstore string format broken, end construction
52 i += current.length();
53 }
54 }
55 else
56 {
57 // hstore string format broken, end construction
58 i += current.length();
59 bits[bits.length() - 1] = current.trimmed();
60 }
61 }
62 else
63 {
64 const int sepPos = current.indexOf( sep );
65 if ( sepPos < 0 )
66 {
67 i += current.length();
68 bits << current.trimmed();
69 }
70 else
71 {
72 i += sepPos + sep.length();
73 bits << current.left( sepPos ).trimmed();
74 }
75 }
76
77 if ( bits.length() == 2 )
78 {
79 if ( !bits.at( 0 ).isEmpty() && !bits.at( 1 ).isEmpty() )
80 map[ bits.at( 0 ) ] = bits.at( 1 );
81 bits.clear();
82 }
83 }
84
85 return map;
86}
87
88QString QgsHstoreUtils::build( const QVariantMap &map )
89{
90 QStringList list;
91 for ( QVariantMap::const_iterator it = map.constBegin(); it != map.constEnd(); ++it )
92 {
93 QString key = it.key();
94 QString value = it.value().toString();
95 list << QString( "\"%1\"=>\"%2\"" ).arg( key.replace( "\\", "\\\\" ).replace( "\"", "\\\"" ),
96 value.replace( "\\", "\\\\" ).replace( "\"", "\\\"" ) );
97 }
98 return list.join( ',' );
99}
CORE_EXPORT QString build(const QVariantMap &map)
Build a hstore-formatted string from a QVariantMap.
CORE_EXPORT QVariantMap parse(const QString &string)
Returns a QVariantMap object containing the key and values from a hstore-formatted string.