Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add record function tag definition #11

Closed
wants to merge 5 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 76 additions & 7 deletions draft-ietf-cbor-packed.md
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ their expansions.
Function tags that occur in an argument or a rump supply the semantics
for reconstructing a data item from their tag content and the
non-dominating rump or argument, respectively.
The present specification defines a pair of function tags.
The present specification defines three function tags.

## Join Function Tags {#join}

Expand Down Expand Up @@ -655,6 +655,52 @@ from the same place could be:
])
~~~

## Record Function Tag {#record}

Tag 114 ('r') defines the "record" function, which combines
an array of keys with an array of values into a map.

The record function expects an array as its left-hand side,
whose items are treated as key items for the resulting map,
and an array of equal or shorter length as its right-hand side,
whose items are treated as value items for the resulting map.

The map is constructed by grouping key and value items
with equal position in the provided arrays into pairs that constitute the resulting map.

If the matching value item for a given key item is either >undefined< (simple value 23)
mguetschow marked this conversation as resolved.
Show resolved Hide resolved
or does not exist (because the value item array is shorter than the key item array),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, maybe there is no resulting pair if the value doesn't exist?
Maybe we can factor absence and "undefined" together, as in "in the value array, items of value "undefined" are treated as absent"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about

The value item array may be shorter than the key item array, in which case one or more value items towards the end are absent.
Additionally, value items that are undefined (0xf7) are treated as absent.
Key items whose matching value items are absent are not included in the resulting map.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put in a slightly edited version of this.

We don't say yet what happpens if the value item array is longer than the key item array.
Should this be a "MUST NOT"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put in a slightly edited version of this.

Reads good to me, thanks!

We don't say yet what happens if the value item array is longer than the key item array.
Should this be a "MUST NOT"?

Yes, I would say so.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I pushed this MUST NOT directly to main, as the merge is now confused...
0b4dbfa

the resulting pair is not included in the resulting map.

For an example, we assume this unpacked data item:

~~~ cbor-diag
[{"key0": false, "key1": "value 1", "key2": 2},
{"key0": true, "key1": "value -1", "key2": -2},
{"key1": "", "key2": 0}]
~~~

A straightforward packed form of this using the record function tag could be:

~~~ cbor-diag
113([[114(["key0", "key1", "key2"])],
[6([false, "value 1", 2]),
6([true, "value -1", -2]),
6([undefined, "", 0])]
])
~~~

A slightly more concise packed form can be achieved by manipulating the key item order
(recall that the order of key/value pairs in maps carries no semantics):

~~~ cbor-diag
113([[114(["key1", "key2", "key0"])],
[6(["value 1", 2, false]),
6(["value -1", -2, true]),
6(["", 0])]
])
~~~

Tag Validity: Tag Equivalence Principle
===================================

Expand Down Expand Up @@ -779,6 +825,7 @@ IANA is requested to allocate the tags defined in {{tab-tag-values}}.
| 105 | text string, byte string, array, map, tag | Packed CBOR: ijoin function | draft-ietf-cbor-packed |
| 106 | text string, byte string, array, map, tag | Packed CBOR: join function | draft-ietf-cbor-packed |
| 113 | array (shared-and-argument-items, rump) | Packed CBOR: table setup | draft-ietf-cbor-packed |
| 114 | array | Packed CBOR: record function | draft-ietf-cbor-packed |
| 224..255 | text string, byte string, array, map, tag | Packed CBOR: straight | draft-ietf-cbor-packed |
| 1112 | undefined (0xf7) | Packed CBOR: reference error | draft-ietf-cbor-packed |
| 1113 | array (shared-items, argument-items, rump) | Packed CBOR: table setup | draft-ietf-cbor-packed |
Expand Down Expand Up @@ -817,11 +864,13 @@ this requires additional consideration.)
Examples
========

The (JSON-compatible) CBOR data structure depicted in
{{fig-example-in}}, 400 bytes of binary CBOR, could lead to a packed
CBOR data item depicted in {{fig-example-out}}, ~309 bytes. Note that
this particular example does not lend itself to prefix compression, so
it uses the simple common-table setup form (tag 113).
The (JSON-compatible) CBOR data structure depicted in {{fig-example-in}},
400 bytes of binary CBOR, could be packed into the CBOR data item depicted
in {{fig-example-out}}, ~309 bytes, only employing item sharing.
mguetschow marked this conversation as resolved.
Show resolved Hide resolved
With support for argument sharing and the record function tag 114,
the data item can be packed into 298 bytes as depicted in {{fig-example-out-record}}.
Note that this particular example does not lend itself to prefix compression,
so it uses the simple common-table setup form (tag 113).

~~~ json
{ "store": {
Expand Down Expand Up @@ -876,7 +925,27 @@ it uses the simple common-table setup form (tag 113).
simple(6): "0-395-19395-8", simple(0): 22.99}],
"bicycle": {"color": "red", simple(0): 19.95}}}])
~~~
{: #fig-example-out title="Example packed CBOR data item"}
{: #fig-example-out title="Example packed CBOR data item with item sharing only"}

~~~ cbor-diag
113([[114(["category", "author",
"title", simple(1), "isbn"]),
mguetschow marked this conversation as resolved.
Show resolved Hide resolved
/ 0 /
"price", "fiction", 8.95],
/ 1 2 3 /
{"store": {
"book": [
6(["reference", "Nigel Rees",
"Sayings of the Century", simple(3)]),
6([simple(2), "Evelyn Waugh",
"Sword of Honour", 12.99]),
6([simple(2), "Herman Melville",
"Moby Dick", simple(3), "0-553-21311-3"]),
6([simple(2), "J. R. R. Tolkien",
"The Lord of the Rings", 22.99, "0-395-19395-8"])],
"bicycle": {"color": "red", simple(0): 19.95}}}])
~~~
{: #fig-example-out-record title="Example packed CBOR data item with item and argument sharing"}
mguetschow marked this conversation as resolved.
Show resolved Hide resolved


The (JSON-compatible) CBOR data structure below has been packed with shared
Expand Down
Loading