class QCborStreamWriter#

QCborStreamWriter类是一个在单向流上运行的简单CBOR编码器。更多

概述#

方法#

备注

本文档可能包含从C++自动转换为Python的代码片段。我们始终欢迎对代码片段的翻译做出贡献。如果您发现翻译存在问题,也可以通过在https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述#

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

此类可用于将CBOR内容流快速编码为QByteArrayQIODevice。CBOR(Concise Binary Object Representation,紧凑的二进制对象表示)是一种非常紧凑的二进制数据编码形式,与JSON兼容。它是IETF Constrained RESTful Environments (CoRE)工作组创建的,该工作组已将其用于许多新的RFC中。它旨在与CoAP协议一起使用。

QCborStreamWriter提供了一个类似StAX的API,类似于QXmlStreamWriter。它相当低级,需要一定的CBOR编码知识。对于更简单的API,请参阅QCborValue类,特别是编码函数toCbor()

《QCborStreamWriter》的典型使用方式是在目标QByteArrayQIODevice上创建对象,然后调用相应的append()重载方法,对需要编码的类型进行编码。为了创建数组和映射,QCborStreamWriter提供了startArray()startMap()重载方法,这些方法必须通过相应的endArray()endMap()函数来终止。

以下示例是对应JSON内容的编码:

{ “label”: “journald”, “autoDetect”: false, “condition”: “libs.journald”, “output”: [ “privateFeature” ] }

writer.startMap(4) # 4 elements in the map
writer.append("label")
writer.append("journald")
writer.append("autoDetect")
writer.append(False)
writer.append("condition")
writer.append("libs.journald")
writer.append("output")
writer.startArray(1)
writer.append("privateFeature")
writer.endArray()
writer.endMap()

CBOR支持#

《QCborStreamWriter》支持创建规范和严格流所需的所有 CBOR 功能,实现了 RFC 7049 中指定的几乎所有功能。

以下表格列出了《QCborStreamWriter》所支持的 CBOR 功能。

功能

支持

无符号数

是(全范围)

负数

是(全范围)

字节字符串

文本字符串

分块字符串

标签

是(任意)

布尔值

空值

未定义

任意简单值

半精度浮点数(16位)

单精度浮点数(32位)

双精度浮点数(64位)

无穷大和NaN浮点数

确定长度的数组和映射

不确定长度的数组和映射

除了字符串和整数之外的其他映射键类型

是(任意)

规范CBOR编码#

规范CBOR编码由 RFC 7049 的第 3.9 节定义。规范编码不是 Qt 的 CBOR 解码功能的必要条件,但对于某些协议可能是必需的。特别是,需要能够一致复制同一流的协议可能需要这一功能。

为了被认为是“规范”的,CBOR 流必须满足以下要求:

  • 整数必须尽可能小。《QCborStreamWriter》总是这样做(不需要用户操作,而且无法写入超长整数)。

  • 数组、映射和字符串长度必须尽可能短。如上所述,QCborStreamWriter 会自动执行此操作。

  • 数组、映射和字符串必须使用显式长度。对于字符串,QCborStreamWriter 会始终执行此操作;对于数组和映射,确保调用带有显式长度的 startArray()startMap() 重载。

  • 映射中的键必须按升序排序。在此方面,QCborStreamWriter 并不提供帮助:开发人员必须确保在调用映射对 append() 之前进行排序。

  • 浮点数值应尽可能小。在此,QCborStreamWriter 不会转换浮点数值;检查此问题将归咎于开发人员,需要在调用 append() 之前执行此检查(请参阅那些函数的示例)。

严格CBOR模式

严格模式是由RFC 7049的第3.10节定义的。关于上面的规范编码,QCborStreamWriter 使创建严格CBOR流成为可能,但它不要求必须如此或验证输出是否如此。

  • 映射中的键必须唯一。在此,QCborStreamWriter 不验证映射键。

  • 根据规格,标签可能只能与正确的类型配对。在此方面,QCborStreamWriter 不验证标签的使用。

  • 文本字符串必须是正确编码的UTF-8。在此,QCborStreamWriter 始终为使用 append() 添加的字符串写入正确的UTF-8,但不会对使用 appendTextString() 添加的字符串进行验证。

无效CBOR流

还可能错误使用 QCborStreamWriter 并生成无效的CBOR流,接收者无法对其进行解码。以下操作将生成无效流

  • 追加标签但不追加对应的标记值(QCborStreamWriter 不产生诊断信息)。

  • 向具有显式长度的数组或映射中追加过多或过少的条目(endMap()endArray() 将返回 false,且 QCborStreamWriter 将使用 qWarning() 记录日志)。

{解析和显示 CBOR 数据},{序列化和转换器},{保存和加载游戏}

__init__(device)#
参数:

deviceQIODevice

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

创建一个将流写入 deviceQCborStreamWriter 对象。在执行第一个 append() 调用之前,设备必须已打开。此构造函数可以与任何从 QIODevice 派生的类一起使用,例如 QFileQProcess 或 QTcpSocket。

QCborStreamWriter 没有缓冲区,因此每次 append() 调用都将导致对设备 write() 方法的调用一次或多次。

以下示例将空映射写入文件

f = QFile("output", QIODevice.WriteOnly)
writer = QCborStreamWriter(f)
writer.startMap(0)
writer.endMap()

QCborStreamWriter 不拥有 device

另请参阅

device() setDevice()

__init__(data)
参数:

dataQByteArray

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

创建一个将流附加到 dataQCborStreamWriter 对象。所有流操作都将立即写入字节数组,无需刷新任何缓冲区。

以下示例将数字写入字节数组然后返回它。

def encodedNumber(value):

    ba = QByteArray()
    writer = QCborStreamWriter(ba)
    writer.append(value)
    return ba

QCborStreamWriter 不会拥有 data

append(u)#
参数:

u – int

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将 64 位无符号值 u 附加到 CBOR 流,创建一个 CBOR 无符号整数值。在以下示例中,我们写入值 0、2^32 和 UINT64_MAX

writer.append(0U)
writer.append(Q_UINT64_C(4294967296))
writer.append(std.numeric_limits<quint64>.max())
append(u)
参数:

u – int

append(i)
参数:

i – int

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将 64 位有符号值 i 附加到 CBOR 流。根据参数的符号,这将创建一个 CBOR 无符号整数或 CBOR 负整数值。在以下示例中,我们写入值 0、-1、2^32 和 INT64_MAX

writer.append(0)
writer.append(-1)
writer.append(Q_INT64_C(4294967296))
writer.append(std.numeric_limits<qint64>.max())

另请参阅

isInteger() toInteger()

append(i)
参数:

i – int

append(f)
参数:

f – float

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将浮点数 f 附加到流,创建一个 CBOR 32 位单精度浮点数值。如果精度没有损失,则可以使用以下代码将 C++ double 转换为 float 并将其附加,或者直接附加 double

   def writeFloat(writer, d):

       f = d
       if qIsNaN(d) or d == f:
           writer.append(f)
else:
           writer.append(d)

另请参阅

isFloat() toFloat()

append(d)
参数:

d – 浮点数

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将浮点数 d 添加到流中,创建一个 CBOR 64 位双精度浮点值。QCborStreamWriter 总是按照原样添加数字,不会检查该数字是否是 NaN、无穷、非规格化或者是否能用更短的格式表示。

以下代码执行所有这些检查,除了非规格化检查,这由系统的 FPU 或浮点数模拟直接考虑。

   def writeDouble(writer, d):

       f = float()
       if qIsNaN(d):
           writer.append(qfloat16(qQNaN()))
        elif qIsInf(d):
           writer.append(d < 0 if -qInf() else qInf())
        elif (f = d) == d:
           f16 = f
           if f16 == f:
               writer.append(f16)
else:
               writer.append(f)
       else:
           writer.append(d)

将双精度转换为不带精度损失的整数的判断留给读者练习。

另请参阅

isDouble() toDouble()

append(str)
参数:
  • str – 字符串

  • size – int

这是一个重载函数。

将来自 strsize 字节的文本添加到流中,创建一个 CBOR 文本字符串值。QCborStreamWriter 将尝试一次性写入整个字符串。如果 size 为 -1,此函数将写入 strlen(str) 字节。

指向 str 的字符串应正确编码为 UTF-8。QCborStreamWriter 不会对此进行验证。

QCborStreamWriterQLatin1StringView 重载不同,此函数不受 2 GB 的限制。然而,请注意,QCborStreamReaderQCborValue 都不支持读取大于 2 GB 的文本字符串的 CBOR 流。

另请参阅

append(QLatin1StringView) append(QStringView) isString() readString()

append(b)
参数:

b – bool

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将布尔值b追加到流中,创建CBOR的False值或True值。此函数等同于(并作为)

writer.append(b if QCborSimpleType.True else QCborSimpleType.False)
append(str)
参数:

str – 字符串

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将文本字符串str追加到流中,创建CBOR文本字符串值。QCborStreamWriter会尝试一次性写入整个字符串。

以下示例将任意的QString写入流中

def writeString(writer, str):

    writer.append(str)

另请参阅

isString() readString()

append(str)
参数:

strQLatin1String

append(标签)
参数:

标签QCborTag

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将CBOR标签标签追加到流中,创建CBOR Tag值。所有标签都必须跟随一个类型,为它们提供意义。

以下示例中,我们将CBOR Tag 36(正则表达式)和QRegularExpression的模板追加到流中

def writeRxPattern(writer, rx):

    writer.append(QCborTag(36))
    writer.append(rx.pattern())

另请参阅

isTag() toTag()

append(st)
参数:

stQCborSimpleType

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将 CBOR 简单类型 st 添加到流中,创建一个 CBOR 简单类型值。在以下示例中,我们将 Null 的简单类型以及 Qt 不支持的类型 32 写入流中。

writer.append(QCborSimpleType.Null)
writer.append(QCborSimpleType(32))

备注

使用没有规定的简单类型可能导致远程接收方验证错误。此外,简单类型值 24 至 31(包含)已被保留,不得使用。

append(标签)
参数:

tagQCborKnownTags

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将CBOR标签标签追加到流中,创建CBOR Tag值。所有标签都必须跟随一个类型,为它们提供意义。

以下示例中,我们将 CBOR 标签 1(Unix time_t)以及代表当前时间的整数添加到流中,使用了 time() 函数。

def writeCurrentTime(writer):

    writer.append(QCborKnownTags.UnixTime_t)
    writer.append(time(None))

另请参阅

isTag() toTag()

append(ba)
参数:

baQByteArray

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

将字节数组 ba 添加到流中,创建一个 CBOR 字节字符串值。 QCborStreamWriter 试图一次性写入整个字符串。

以下示例将文件内容加载并追加到流中。

def writeFile(writer, fileName):

    f = QFile(fileName)
    if f.open(QIODevice.ReadOnly):
        writer.append(f.readAll())

如示例所示,与 JSON 不同,CBOR 对二进制内容无需转义。

appendByteString(data, len)#
参数:
  • data – str

  • len – int

将起始于 datalen 个字节追加到流中,创建一个 CBOR 字节字符串值。 QCborStreamWriter 试图一次性写入整个字符串。

QByteArray 覆载的 append() 不同,此函数不受 QByteArray 大小限制。但是请注意,readByteArray()QCborValue 都不支持读取大于2 GB的字节数组的CBOR流。

appendNull()#

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

将一个CBOR Null值追加到流中。此函数等同于(并且以以下方式实现)

writer.append(QCborSimpleType.Null)

另请参阅

nullptr_t) append(QCborSimpleType) isNull()

appendTextString(utf8, len)#
参数:
  • utf8 – 字符串

  • len – int

len 个从 utf8 开始的文本字节追加到流中,创建一个CBOR文本字符串值。 QCborStreamWriter 将尝试一次性写入整个字符串。

指向 utf8 的字符串预计是正确编码的UTF-8。 QCborStreamWriter 不会验证这一点。

append()QLatin1StringView 覆载不同,此函数不受2 GB的限制。但是请注意, neither readString() nor QCborValue support reading CBOR streams with text strings larger than 2 GB.

另请参阅

append(QLatin1StringView) append(QStringView) isString() readString()

appendUndefined()#

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

将 CBOR 未定义值追加到流中。此函数等同于(并且作为)以下函数实现:

writer.append(QCborSimpleType.Undefined)

另请参阅

append(QCborSimpleType) isUndefined()

device()#
返回类型:

QIODevice

返回此类 QIODevice 正在写入的对象。该设备必须已经通过构造函数或通过 setDevice() 设置。

如果此对象是通过写入 QByteArray 创建的,则此函数将返回一个内部的 QBuffer 实例,该实例由 QCborStreamWriter 拥有。

另请参阅

setDevice()

endArray()#
返回类型:

bool

终止由 startArray() 的任一重载开始创建的数组,如果数组中添加了正确的元素数量,则返回 true。必须为每个使用的 startArray() 调用此函数。

返回 false 表示应用程序中的错误以及此流中无法恢复的错误。如果发生这种情况,QCborStreamWriter 还会使用 qWarning() 写入警告。

当当前容器不是数组时调用此函数也是错误,尽管 QCborStreamWriter 目前无法检测此条件。

另请参阅

startArray() startArray(quint64) endMap()

endMap()#
返回类型:

bool

终止由以下任一重载启动的映射并返回 true,如果数组中添加了正确数量的元素。此函数必须为每个使用的 startMap() 调用而调用。

返回 false 表示应用程序中的错误以及此流中无法恢复的错误。如果发生这种情况,QCborStreamWriter 还会使用 qWarning() 写入警告。

当当前容器不是一个映射时调用此函数也是错误的,尽管目前 QCborStreamWriter 无法检测此条件。

另请参阅

startMap() startMap(quint64) endArray()

setDevice(device)#
参数:

deviceQIODevice

device 替换此 QCborStreamWriter 对象正在写入的设备或字节数组。

另请参阅

device()

startArray()#

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

在 CBOR 流中开始一个不定长的 CBOR 数组。每个 startArray() 调用必须与一个 endArray() 调对配,并且当前的 CBOR 元素扩展到数组的末尾。

此函数创建的数组没有显式长度。相反,其长度隐含于其包含的元素中。但是,请注意,使用不定长数组并不符合规范化的 CBOR 编码。

以下示例将传入字符串列表的元素附加到数组中

def appendList(writer, values):

    writer.startArray()
    for s in values:
        writer.append(s)
    writer.endArray()

另请参阅

startArray(quint64) endArray() startMap() isArray() isLengthKnown()

startArray(count)
参数:

count – int

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

在CBOR流中以显式长度count开始CBOR数组。每个startArray调用都必须与一个endArray()调用配对,并且当前CBOR元素延伸到数组的末尾。

此函数创建的数组具有显式长度,因此必须将 exactly count 个项目添加到CBOR流中。添加的项目较少或较多会导致在调用 endArray() 时失败,并且CBOR流将损坏。然而,标准的CBOR编码需要包含显式长度的数组。

以下示例将输入QStringList中找到的所有字符串附加到数组中

def appendList(writer, list):

    writer.startArray(list.size())
    for s in list:
        writer.append(s)
    writer.endArray()

大小限制:此函数的参数类型为quint64,理论上数组中可达2的64次方减1个元素。然而,QCborStreamWriterQCborStreamReader 都目前限制在32位系统上的2的32次方减2个项目和64位系统上的2的64次方减2个项目。另外请注意,QCborArray 目前在32位平台上的限制是2的27次方个元素,在64位平台上的限制是2的59次方个元素。

另请参阅

startArray() endArray() startMap() isArray() isLengthKnown()

startMap()#

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

在CBOR流中以不确定长度开始CBOR映射。每个startMap()调用都必须与一个endMap()调用配对,并且当前CBOR元素延伸到映射的末尾。

此函数创建的映射没有显式长度。相反,它的长度由其中包含的元素隐式指定。但是请注意,使用不确定长度的映射不符合标准的CBOR编码(标准编码还要求键是唯一的且按顺序排序)。

以下示例将输入作为输入传递的整数和字符串对的列表中的元素附加到映射中

def appendMap(writer, QList<std.pair<int, values):

    writer.startMap()
    for pair in values:
        writer.append(pair.first)
        writer.append(pair.second)

    writer.endMap()

另请参阅

startMap(quint64) endMap() startArray() isMap() isLengthKnown()

startMap(count)
参数:

count – int

警告

本节包含从C++自动转换为Python的代码片段,可能存在错误。

这是一个重载函数。

在CBOR流中启动一个具有明确长度的CBOR映射,包含 count 个元素。每个 startMap 调用一个都必须配备一个 endMap() 调用,并且当前的CBOR元素扩展到映射的末尾。

此函数创建的映射具有明确长度,因此在CBOR流中必须添加恰好 count 对的元素。添加更少或多于元素将导致在 endMap() 期间失败,并且CBOR流将损坏。然而,明确定义长度的映射是标准CBOR编码所必需的。

以下示例将输入的代码 QMap 中找到的所有字符串附加到

def appendMap(writer, QMap<int, map):

    writer.startMap(map.size())
    for it in map:
        writer.append(it.key())
        writer.append(it.value())

    writer.endMap()

大小限制:此函数的参数是 quint64,似乎允许在映射中最多有 2 64-1 对。然而,QCborStreamWriterQCborStreamReader 目前在 32 位系统上限制为 2 31-1 个项目,在 64 位系统上限制为 2 63-1 个项目。还要注意,QCborMap 目前在 32 位平台上限制为 2 26 个元素,在 64 位平台上限制为 2 58 个元素。