QtBase  v6.3.1
qcborvalue_p.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2020 Intel Corporation.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QCBORVALUE_P_H
41 #define QCBORVALUE_P_H
42 
43 //
44 // W A R N I N G
45 // -------------
46 //
47 // This file is not part of the Qt API.
48 // This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include "qcborvalue.h"
55 
56 #if QT_CONFIG(cborstreamreader)
57 # include "qcborstreamreader.h"
58 #endif
59 
60 #include <private/qglobal_p.h>
61 #include <private/qstringconverter_p.h>
62 
63 #include <math.h>
64 
66 
67 namespace QtCbor {
68 struct Undefined {};
69 struct Element
70 {
71  enum ValueFlag : quint32 {
72  IsContainer = 0x0001,
73  HasByteData = 0x0002,
74  StringIsUtf16 = 0x0004,
75  StringIsAscii = 0x0008
76  };
77  Q_DECLARE_FLAGS(ValueFlags, ValueFlag)
78 
79  union {
82  };
84  ValueFlags flags = {};
85 
87  : value(v), type(t), flags(f)
88  {}
89 
92  {}
93 
94  double fpvalue() const
95  {
96  double d;
97  memcpy(&d, &value, sizeof(d));
98  return d;
99  }
100 };
101 Q_DECLARE_OPERATORS_FOR_FLAGS(Element::ValueFlags)
102 static_assert(sizeof(Element) == 16);
103 
104 struct ByteData
105 {
107 
108  const char *byte() const { return reinterpret_cast<const char *>(this + 1); }
109  char *byte() { return reinterpret_cast<char *>(this + 1); }
110  const QChar *utf16() const { return reinterpret_cast<const QChar *>(this + 1); }
111  QChar *utf16() { return reinterpret_cast<QChar *>(this + 1); }
112 
113  QByteArray toByteArray() const { return QByteArray(byte(), len); }
114  QString toString() const { return QString(utf16(), len / 2); }
115  QString toUtf8String() const { return QString::fromUtf8(byte(), len); }
116 
118  QLatin1String asLatin1() const { return QLatin1String(byte(), len); }
119  QStringView asStringView() const{ return QStringView(utf16(), len / 2); }
120  QString asQStringRaw() const { return QString::fromRawData(utf16(), len / 2); }
121 };
122 static_assert(std::is_trivial<ByteData>::value);
124 } // namespace QtCbor
125 
127 
129 {
132 
133 public:
135 
139 
140  void deref() { if (!ref.deref()) delete this; }
141  void compact(qsizetype reserved);
145 
147  {
148  // This function does not do overflow checking, since the len parameter
149  // is expected to be trusted. There's another version of this function
150  // in decodeStringFromCbor(), which checks.
151 
152  qptrdiff offset = data.size();
153 
154  // align offset
155  offset += alignof(QtCbor::ByteData) - 1;
156  offset &= ~(alignof(QtCbor::ByteData) - 1);
157 
159 
160  usedData += increment;
161  data.resize(offset + increment);
162 
163  char *ptr = data.begin() + offset;
164  auto b = new (ptr) QtCbor::ByteData;
165  b->len = len;
166  if (block)
167  memcpy(b->byte(), block, len);
168 
169  return offset;
170  }
171 
173  {
174  if ((e.flags & QtCbor::Element::HasByteData) == 0)
175  return nullptr;
176 
177  size_t offset = size_t(e.value);
178  Q_ASSERT((offset % alignof(QtCbor::ByteData)) == 0);
179  Q_ASSERT(offset + sizeof(QtCbor::ByteData) <= size_t(data.size()));
180 
181  auto b = reinterpret_cast<const QtCbor::ByteData *>(data.constData() + offset);
182  Q_ASSERT(offset + sizeof(*b) + size_t(b->len) <= size_t(data.size()));
183  return b;
184  }
186  {
187  return byteData(elements.at(idx));
188  }
189 
191  {
192  const QtCbor::Element &e = elements.at(idx);
193  if (e.type != type || (e.flags & QtCbor::Element::IsContainer) == 0)
194  return nullptr;
195  return e.container;
196  }
197 
200  {
201  if (value.container)
202  return replaceAt_complex(e, value, disp);
203 
204  e = { value.value_helper(), value.type() };
205  if (value.isContainer())
206  e.container = nullptr;
207  }
209  {
211  if (e.flags & QtCbor::Element::IsContainer) {
212  e.container->deref();
213  e.container = nullptr;
214  e.flags = {};
215  } else if (auto b = byteData(e)) {
216  usedData -= b->len + sizeof(QtCbor::ByteData);
217  }
218  replaceAt_internal(e, value, disp);
219  }
221  {
222  replaceAt_internal(*elements.insert(elements.begin() + int(idx), {}), value, disp);
223  }
224 
226  {
228  }
230  {
232  }
234  {
236  }
238  QtCbor::Element::ValueFlags extraFlags = {})
239  {
241  QtCbor::Element::HasByteData | extraFlags));
242  }
244  void appendAsciiString(const char *str, qsizetype len)
245  {
247  }
248  void appendUtf8String(const char *str, qsizetype len)
249  {
251  }
253  {
254  if (!QtPrivate::isAscii(s))
255  return append(QString(s));
256 
257  // US-ASCII is a subset of UTF-8, so we can keep in 8-bit
258  appendByteData(s.latin1(), s.size(), QCborValue::String,
260  }
262 
263 #if QT_STRINGVIEW_LEVEL < 2
264  void append(const QString &s)
265  {
267  }
268 #endif
269 
271  {
272  if (QtPrivate::isAscii(s))
274  else
275  appendByteData(reinterpret_cast<const char *>(s.utf16()), s.size() * 2,
277  }
278  void append(const QCborValue &v)
279  {
280  insertAt(elements.size(), v);
281  }
282 
284  {
285  const auto &e = elements.at(idx);
286  const auto data = byteData(e);
287  if (!data)
288  return QByteArray();
289  return data->toByteArray();
290  }
292  {
293  const auto &e = elements.at(idx);
294  const auto data = byteData(e);
295  if (!data)
296  return QString();
297  if (e.flags & QtCbor::Element::StringIsUtf16)
298  return data->toString();
299  if (e.flags & QtCbor::Element::StringIsAscii)
300  return data->asLatin1();
301  return data->toUtf8String();
302  }
303 
304  static void resetValue(QCborValue &v)
305  {
306  v.container = nullptr;
307  }
308 
311  {
313  result.n = n;
314  result.container = d;
315  if (d && disp == CopyContainer)
316  d->ref.ref();
317  return result;
318  }
319 
321  {
322  const auto &e = elements.at(idx);
323 
324  if (e.flags & QtCbor::Element::IsContainer) {
325  if (e.type == QCborValue::Tag && e.container->elements.size() != 2) {
326  // invalid tags can be created due to incomplete parsing
327  return makeValue(QCborValue::Invalid, 0, nullptr);
328  }
329  return makeValue(e.type, -1, e.container);
330  } else if (e.flags & QtCbor::Element::HasByteData) {
331  return makeValue(e.type, idx, const_cast<QCborContainerPrivate *>(this));
332  }
333  return makeValue(e.type, e.value);
334  }
337  {
339  qSwap(e, elements[idx]);
340 
341  if (e.flags & QtCbor::Element::IsContainer) {
342  if (e.type == QCborValue::Tag && e.container->elements.size() != 2) {
343  // invalid tags can be created due to incomplete parsing
344  e.container->deref();
345  return makeValue(QCborValue::Invalid, 0, nullptr);
346  }
347  return makeValue(e.type, -1, e.container, MoveContainer);
348  } else if (e.flags & QtCbor::Element::HasByteData) {
349  return extractAt_complex(e);
350  }
351  return makeValue(e.type, e.value);
352  }
353 
355  {
356  if (value.n >= 0 && value.container)
357  return value.container->elements.at(value.n);
358 
360  e.value = value.n;
361  e.type = value.t;
362  if (value.container) {
363  e.container = value.container;
365  }
366  return e;
367  }
368 
369  static int compareUtf8(const QtCbor::ByteData *b, const QLatin1String &s)
370  {
371  return QUtf8::compareUtf8(QByteArrayView(b->byte(), b->len), s);
372  }
373 
375  {
376  return QUtf8::compareUtf8(QByteArrayView(b->byte(), b->len), s);
377  }
378 
379  template<typename String>
380  int stringCompareElement(const QtCbor::Element &e, String s) const
381  {
382  if (e.type != QCborValue::String)
383  return int(e.type) - int(QCborValue::String);
384 
385  const QtCbor::ByteData *b = byteData(e);
386  if (!b)
387  return s.isEmpty() ? 0 : -1;
388 
389  if (e.flags & QtCbor::Element::StringIsUtf16)
390  return QtPrivate::compareStrings(b->asStringView(), s);
391  return compareUtf8(b, s);
392  }
393 
394  template<typename String>
395  bool stringEqualsElement(const QtCbor::Element &e, String s) const
396  {
397  return stringCompareElement(e, s) == 0;
398  }
399 
400  template<typename String>
401  bool stringEqualsElement(qsizetype idx, String s) const
402  {
403  return stringEqualsElement(elements.at(idx), s);
404  }
405 
409  {
410  auto &e1 = elements.at(idx);
411  auto e2 = elementFromValue(value);
412  return compareElement_helper(this, e1, value.container, e2);
413  }
414 
416  {
417  replaceAt(idx, {});
419  }
420 
421 #if QT_CONFIG(cborstreamreader)
422  void decodeValueFromCbor(QCborStreamReader &reader, int remainingStackDepth);
423  void decodeStringFromCbor(QCborStreamReader &reader);
424  static inline void setErrorInReader(QCborStreamReader &reader, QCborError error);
425 #endif
426 };
427 
429 
430 #endif // QCBORVALUE_P_H
#define value
[5]
FT_UInt idx
Definition: cffcmap.c:135
FT_Error error
Definition: cffdrivr.c:657
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
qsizetype size_type
Definition: qbytearray.h:441
static QByteArray fromRawData(const char *data, qsizetype size)
Definition: qbytearray.h:396
QString stringAt(qsizetype idx) const
Definition: qcborvalue_p.h:291
void insertAt(qsizetype idx, const QCborValue &value, ContainerDisposition disp=CopyContainer)
Definition: qcborvalue_p.h:220
QByteArray::size_type usedData
Definition: qcborvalue_p.h:136
QCborContainerPrivate * containerAt(qsizetype idx, QCborValue::Type type) const
Definition: qcborvalue_p.h:190
static int compareUtf8(const QtCbor::ByteData *b, QStringView s)
Definition: qcborvalue_p.h:374
void replaceAt_internal(QtCbor::Element &e, const QCborValue &value, ContainerDisposition disp)
Definition: qcborvalue_p.h:199
void append(QStringView s)
Definition: qcborvalue_p.h:270
void appendUtf8String(const char *str, qsizetype len)
Definition: qcborvalue_p.h:248
void append(const QString &s)
Definition: qcborvalue_p.h:264
void append(const QCborValue &v)
Definition: qcborvalue_p.h:278
const QtCbor::ByteData * byteData(qsizetype idx) const
Definition: qcborvalue_p.h:185
void appendByteData(const char *data, qsizetype len, QCborValue::Type type, QtCbor::Element::ValueFlags extraFlags={})
Definition: qcborvalue_p.h:237
static int compareUtf8(const QtCbor::ByteData *b, const QLatin1String &s)
Definition: qcborvalue_p.h:369
static QCborContainerPrivate * grow(QCborContainerPrivate *d, qsizetype index)
Definition: qcborvalue.cpp:972
static QCborContainerPrivate * detach(QCborContainerPrivate *d, qsizetype reserved)
Definition: qcborvalue.cpp:959
bool stringEqualsElement(const QtCbor::Element &e, String s) const
Definition: qcborvalue_p.h:395
void removeAt(qsizetype idx)
Definition: qcborvalue_p.h:415
void replaceAt(qsizetype idx, const QCborValue &value, ContainerDisposition disp=CopyContainer)
Definition: qcborvalue_p.h:208
QList< QtCbor::Element > elements
Definition: qcborvalue_p.h:138
void append(QCborTag tag)
Definition: qcborvalue_p.h:233
void compact(qsizetype reserved)
Definition: qcborvalue.cpp:931
void appendAsciiString(const char *str, qsizetype len)
Definition: qcborvalue_p.h:244
QCborValue extractAt(qsizetype idx)
Definition: qcborvalue_p.h:336
int stringCompareElement(const QtCbor::Element &e, String s) const
Definition: qcborvalue_p.h:380
const QtCbor::ByteData * byteData(QtCbor::Element e) const
Definition: qcborvalue_p.h:172
void append(QtCbor::Undefined)
Definition: qcborvalue_p.h:225
QByteArray byteArrayAt(qsizetype idx) const
Definition: qcborvalue_p.h:283
static QCborValue makeValue(QCborValue::Type type, qint64 n, QCborContainerPrivate *d=nullptr, ContainerDisposition disp=CopyContainer)
Definition: qcborvalue_p.h:309
static int compareElement_helper(const QCborContainerPrivate *c1, QtCbor::Element e1, const QCborContainerPrivate *c2, QtCbor::Element e2)
QCborValue extractAt_complex(QtCbor::Element e)
void append(QLatin1String s)
Definition: qcborvalue_p.h:252
void appendAsciiString(const QString &s)
int compareElement(qsizetype idx, const QCborValue &value) const
Definition: qcborvalue_p.h:408
qptrdiff addByteData(const char *block, qsizetype len)
Definition: qcborvalue_p.h:146
static QtCbor::Element elementFromValue(const QCborValue &value)
Definition: qcborvalue_p.h:354
void replaceAt_complex(QtCbor::Element &e, const QCborValue &value, ContainerDisposition disp)
Definition: qcborvalue.cpp:988
static void resetValue(QCborValue &v)
Definition: qcborvalue_p.h:304
bool stringEqualsElement(qsizetype idx, String s) const
Definition: qcborvalue_p.h:401
QCborValue valueAt(qsizetype idx) const
Definition: qcborvalue_p.h:320
void append(qint64 value)
Definition: qcborvalue_p.h:229
static QCborContainerPrivate * clone(QCborContainerPrivate *d, qsizetype reserved=-1)
Definition: qcborvalue.cpp:941
The QCborStreamReader class is a simple CBOR stream decoder, operating on either a QByteArray or QIOD...
The QCborValue class encapsulates a value in CBOR.
Definition: qcborvalue.h:86
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
The QExplicitlySharedDataPointer class represents a pointer to an explicitly shared object.
Definition: qshareddata.h:161
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
qsizetype size() const noexcept
Definition: qlist.h:414
iterator insert(qsizetype i, parameter_type t)
Definition: qlist.h:499
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
void remove(qsizetype i, qsizetype n=1)
Definition: qlist.h:798
iterator begin()
Definition: qlist.h:623
void append(parameter_type t)
Definition: qlist.h:469
The QSharedData class is a base class for shared data objects. \reentrant.
Definition: qshareddata.h:55
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString fromUtf8(QByteArrayView utf8)
Definition: qstring.cpp:5632
static QString fromRawData(const QChar *, qsizetype size)
Definition: qstring.cpp:8938
The QStringView class provides a unified view on UTF-16 strings with a read-only subset of the QStrin...
Definition: qstringview.h:122
QString str
[2]
qSwap(pi, e)
double e
JOCTET JCOEFPTR block
Definition: jsimd.h:109
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isAscii(QLatin1String s) noexcept
Definition: qstring.cpp:713
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION int compareStrings(QStringView lhs, QStringView rhs, Qt::CaseSensitivity cs=Qt::CaseSensitive) noexcept
QImageReader reader("image.png")
[1]
#define QString()
Definition: parse-defines.h:51
QCborTag
Definition: qcborcommon.h:66
Q_DECLARE_TYPEINFO(QtCbor::Element, Q_PRIMITIVE_TYPE)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
#define Q_DECLARE_FLAGS(Flags, Enum)
Definition: qflags.h:210
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags)
Definition: qflags.h:227
unsigned int quint32
Definition: qglobal.h:288
ptrdiff_t qptrdiff
Definition: qglobal.h:307
ptrdiff_t qsizetype
Definition: qglobal.h:308
long long qint64
Definition: qglobal.h:298
GLenum type
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLuint index
[2]
GLfloat GLfloat f
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLint ref
GLfloat n
GLenum GLsizei len
Definition: qopenglext.h:3292
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
QStringView qToStringViewIgnoringNull(const QStringLike &s) noexcept
Definition: qstringview.h:480
@ Q_PRIMITIVE_TYPE
Definition: qtypeinfo.h:155
QtConcurrent::task([]{ qDebug("Hello, world!");}).spawn(FutureResult void increment(QPromise< int > &promise, int i)
[10]
MyCustomStruct c2
The QCborError class holds the error condition found while parsing or validating a CBOR stream.
Definition: qcborcommon.h:99
static int compareUtf8(QByteArrayView utf8, QStringView utf16) noexcept
QString toUtf8String() const
Definition: qcborvalue_p.h:115
const char * byte() const
Definition: qcborvalue_p.h:108
QStringView asStringView() const
Definition: qcborvalue_p.h:119
QString asQStringRaw() const
Definition: qcborvalue_p.h:120
const QChar * utf16() const
Definition: qcborvalue_p.h:110
QString toString() const
Definition: qcborvalue_p.h:114
QLatin1String asLatin1() const
Definition: qcborvalue_p.h:118
QByteArray::size_type len
Definition: qcborvalue_p.h:106
QByteArray asByteArrayView() const
Definition: qcborvalue_p.h:117
QByteArray toByteArray() const
Definition: qcborvalue_p.h:113
double fpvalue() const
Definition: qcborvalue_p.h:94
Element(qint64 v=0, QCborValue::Type t=QCborValue::Undefined, ValueFlags f={})
Definition: qcborvalue_p.h:86
Element(QCborContainerPrivate *d, QCborValue::Type t, ValueFlags f={})
Definition: qcborvalue_p.h:90
QCborValue::Type type
Definition: qcborvalue_p.h:83
ValueFlags flags
Definition: qcborvalue_p.h:84
QCborContainerPrivate * container
Definition: qcborvalue_p.h:81
XmlOutput::xml_output tag(const QString &name)
Definition: xmloutput.h:154