2. CBOR 数据模型
CBOR 明确定义了其通用数据模型 (generic data model), 该模型定义了 CBOR 可表示的所有数据项集合. 其基本通用数据模型可通过注册 "simple values" 和标签进行扩展. 应用随后可以从得到的扩展通用数据模型中创建一个子集, 用于构建自身的特定数据模型.
在能够表示通用数据模型中数据项的环境内, 可以实现通用 CBOR 编码器和解码器. 这通常涉及为那些在该环境中尚无自然表示的数据项定义额外实现数据类型. 提供通用编码器和解码器的能力是 CBOR 的明确设计目标; 不过, 许多应用会提供自己的应用特定编码器和/或解码器.
在第 3 节定义的基本 (未扩展) 通用数据模型中, 数据项是以下之一:
-
范围为 -2^(64)..2^(64)-1 (含端点) 的整数
-
简单值 (simple value), 由 0 到 255 之间的数字标识, 但不同于该数字本身
-
浮点值, 不同于整数, 取自 IEEE 754 binary64 可表示的集合 (包括非有限值) [IEEE754]
-
零个或多个字节组成的序列 ("byte string")
-
零个或多个 Unicode 码点组成的序列 ("text string")
-
零个或多个数据项组成的序列 ("array")
-
从零个或多个数据项 ("keys") 到相应数据项 ("values") 的映射 (数学函数), 即 "map"
-
带标签数据项 ("tag"), 由标签号 (范围为 0..2^(64)-1 的整数) 和标签内容 (一个数据项) 组成
注意, 在此模型中整数值和浮点值是不同的, 即使它们具有相同数值.
还要注意, 序列化变体在通用数据模型层面不可见. 这种刻意的不可见性包括已编码浮点值的字节数. 它还包括 "argument" (见第 3 节) 的编码选择, 例如整数的编码、文本字符串或字节字符串长度的编码、数组中元素数量或映射中键值对数量的编码, 或标签号的编码.
2.1. 扩展通用数据模型
本文档通过注册若干简单值和标签号扩展了该基本通用数据模型, 例如:
-
"false", "true", "null" 和 "undefined" (由 20..23 标识的简单值, 第 3.3 节)
-
范围和精度大于上述值的整数和浮点值 (标签号 2 到 5, 第 3.4 节)
-
应用数据类型, 例如 RFC 3339 中定义的时间点或日期/时间字符串 (标签号 1 和 0, 第 3.4 节)
扩展通用数据模型的附加元素可以 (并且已经) 通过为 CBOR 创建的 IANA 注册表定义. 即使通用编码器或解码器不知道某个扩展, 使用该扩展的数据项仍可通过在应用接口处用基本通用数据模型表示它们来传入或传出应用, 即表示为通用简单值或通用标签.
换句话说, 基本通用数据模型按本文档定义保持稳定, 而扩展通用数据模型会通过注册新的简单值或标签号而扩展, 但永不收缩.
虽然强烈预期通用编码器和解码器能够以适合其编程环境的形式表示 "false", "true" 和 "null" ("undefined" 被有意省略), 但由标签创建的数据模型扩展的实现确实是可选的, 并取决于实现质量.
2.2. 特定数据模型
基于 CBOR 的协议的特定数据模型通常取扩展通用数据模型的一个子集, 并为该子集及其组件内的数据项分配应用语义. 记录这类特定数据模型并指定数据项类型时, 最好使用其通用数据模型名称 ("negative integer", "array") 来标识类型, 而不是引用其 CBOR 表示的方面 ("major type 1", "major type 4").
特定数据模型还可以为映射键和编码器自由度指定值等价性 (包括不同类型的值). 例如, 在通用数据模型中, 有效映射 MAY 同时以 "0" 和 "0.0" 作为键, 并且编码器 MUST NOT 将 "0.0" 编码为整数 (major type 0, 第 3.1 节). 然而, 如果某个特定数据模型声明整数值的浮点表示和整数表示等价, 则在单个映射中同时使用映射键 "0" 和 "0.0" 会被视为重复, 即使它们编码为不同 major type, 因而无效; 并且编码器可以将整数值浮点数编码为整数, 或反之, 也许是为了节省编码字节.