Compute the number of object properties to serialize.
parent
3ab21c9616
commit
307c57879a
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- The length of objects is now pre-computed, reducing the size of the encoded
|
||||
object and speeding up the decoing process. Thanks to Karchnu for his contribution.
|
||||
|
||||
## [0.2.1] - 2020-09-29
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -54,7 +54,7 @@ house = House.from_cbor(cbor)
|
|||
house.address # => "Crystal Road 1234"
|
||||
house.location # => #<Location:0x10cd93d80 @latitude=12.3, @longitude=34.5>
|
||||
bytes = house.to_cbor # => Bytes[...]
|
||||
CBOR::Diagnostic.to_s(bytes) # => {_ "address": "Crystal Road 1234", "location": {_ "lat": 12.3, "lng": 34.5}}
|
||||
CBOR::Diagnostic.to_s(bytes) # => {"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}
|
||||
|
||||
data_array = [data]
|
||||
cbor_array = data_array.to_cbor # => Bytes[...]
|
||||
|
@ -63,7 +63,7 @@ CBOR::Diagnostic.to_s(cbor) # => [{"address": "Crystal Road 1234", "location
|
|||
houses = Array(House).from_cbor(cbor_array)
|
||||
houses.size # => 1
|
||||
bytes = houses.to_cbor # => Bytes[...]
|
||||
CBOR::Diagnostic.to_s(bytes) # => [{_ "address": "Crystal Road 1234", "location": {_ "lat": 12.3, "lng": 34.5}}]
|
||||
CBOR::Diagnostic.to_s(bytes) # => [{"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}]
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
@ -158,7 +158,7 @@ end
|
|||
|
||||
a = A.from_cbor({"a" => 1, "b" => 2}.to_cbor) # => A(@cbor_unmapped={"b" => 2}, @a=1)
|
||||
bytes = a.to_cbor # => Bytes[...]
|
||||
CBOR::Diagnostic.to_s(bytes) # => {_ "a": 1, "b": 2}
|
||||
CBOR::Diagnostic.to_s(bytes) # => {"a": 1, "b": 2}
|
||||
```
|
||||
|
||||
### Class annotation `CBOR::Serializable::Options`
|
||||
|
|
|
@ -66,7 +66,7 @@ end
|
|||
|
||||
describe CBOR::Serializable do
|
||||
describe "rfc examples" do
|
||||
describe %(example {_ "a": 1, "b": [_ 2, 3]}) do
|
||||
describe %(example {"a": 1, "b": [2, 3]}) do
|
||||
it "decodes from cbor" do
|
||||
result = ExampleA.from_cbor(Bytes[0xbf, 0x61, 0x61, 0x01, 0x61, 0x62, 0x9f, 0x02, 0x03, 0xff, 0xff])
|
||||
|
||||
|
@ -75,7 +75,7 @@ describe CBOR::Serializable do
|
|||
end
|
||||
end
|
||||
|
||||
describe %(example {_ "Fun": true, "Amt": -2}) do
|
||||
describe %(example {"Fun": true, "Amt": -2}) do
|
||||
it "decodes from cbor" do
|
||||
result = ExampleB.from_cbor(Bytes[0xbf, 0x63, 0x46, 0x75, 0x6e, 0xf5, 0x63, 0x41, 0x6d, 0x74, 0x21, 0xff])
|
||||
|
||||
|
@ -84,7 +84,7 @@ describe CBOR::Serializable do
|
|||
end
|
||||
end
|
||||
|
||||
describe %(example ["a", {_ "b": "c"}]) do
|
||||
describe %(example ["a", {"b": "c"}]) do
|
||||
it "decodes from cbor" do
|
||||
result = Array(String | ExampleC).from_cbor(Bytes[0x82, 0x61, 0x61, 0xbf, 0x61, 0x62, 0x61, 0x63, 0xff])
|
||||
|
||||
|
@ -137,7 +137,7 @@ describe CBOR::Serializable do
|
|||
|
||||
it "encodes to CBOR" do
|
||||
cbor = House.from_cbor(bytes).to_cbor
|
||||
CBOR::Diagnostic.to_s(cbor).should eq(%({_ "address": "Crystal Road 1234", "location": {_ "lat": 12.3, "lng": 34.5}}))
|
||||
CBOR::Diagnostic.to_s(cbor).should eq(%({"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -168,7 +168,7 @@ describe CBOR::Serializable do
|
|||
it "encodes to CBOR" do
|
||||
cbor = Array(House).from_cbor(bytes).to_cbor
|
||||
|
||||
CBOR::Diagnostic.to_s(cbor).should eq(%([{_ "address": "Crystal Road 1234", "location": {_ "lat": 12.3, "lng": 34.5}}]))
|
||||
CBOR::Diagnostic.to_s(cbor).should eq(%([{"address": "Crystal Road 1234", "location": {"lat": 12.3, "lng": 34.5}}]))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -185,7 +185,7 @@ describe CBOR::Serializable do
|
|||
res.a.should eq(1)
|
||||
res.cbor_unmapped.should eq({"b" => 2})
|
||||
|
||||
CBOR::Diagnostic.to_s(res.to_cbor).should eq(%({_ "a": 1, "b": 2}))
|
||||
CBOR::Diagnostic.to_s(res.to_cbor).should eq(%({"a": 1, "b": 2}))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -243,6 +243,10 @@ module CBOR
|
|||
raise ::CBOR::SerializationError.new("Unknown CBOR attribute: #{key}", self.class.to_s, nil)
|
||||
end
|
||||
|
||||
protected def get_cbor_unmapped
|
||||
{} of String => ::CBOR::Type
|
||||
end
|
||||
|
||||
protected def on_to_cbor(cbor : ::CBOR::Encoder)
|
||||
end
|
||||
|
||||
|
@ -268,9 +272,28 @@ module CBOR
|
|||
{% end %}
|
||||
{% end %}
|
||||
|
||||
cbor.object do
|
||||
{% for name, value in properties %}
|
||||
# Compute the size of the final list of properties to serialize.
|
||||
# This allows a more compact encoding, and a faster decoding.
|
||||
nb_properties_to_serialize = 0
|
||||
{% for name, value in properties %}
|
||||
_{{name}} = @{{name}}
|
||||
{% unless value[:emit_null] %}
|
||||
unless _{{name}}.nil?
|
||||
nb_properties_to_serialize += 1
|
||||
end
|
||||
{% else %}
|
||||
nb_properties_to_serialize += 1
|
||||
{% end %}
|
||||
{% end %}
|
||||
|
||||
nb_properties_to_serialize += get_cbor_unmapped.size
|
||||
|
||||
|
||||
{% if properties.size > 0 %}
|
||||
cbor.write_object_start nb_properties_to_serialize
|
||||
|
||||
{% for name, value in properties %}
|
||||
_{{name}} = @{{name}}
|
||||
|
||||
{% unless value[:emit_null] %}
|
||||
unless _{{name}}.nil?
|
||||
|
@ -279,22 +302,22 @@ module CBOR
|
|||
# Write the key of the map
|
||||
cbor.write({{value[:key]}})
|
||||
|
||||
{% if value[:converter] %}
|
||||
if _{{name}}
|
||||
{{ value[:converter] }}.to_cbor(_{{name}}, cbor)
|
||||
else
|
||||
cbor.write(nil, use_undefined: value[:nil_as_undefined])
|
||||
end
|
||||
{% else %}
|
||||
_{{name}}.to_cbor(cbor)
|
||||
{% end %}
|
||||
{% if value[:converter] %}
|
||||
if _{{name}}
|
||||
{{ value[:converter] }}.to_cbor(_{{name}}, cbor)
|
||||
else
|
||||
cbor.write(nil, use_undefined: value[:nil_as_undefined])
|
||||
end
|
||||
{% else %}
|
||||
_{{name}}.to_cbor(cbor)
|
||||
{% end %}
|
||||
|
||||
{% unless value[:emit_null] %}
|
||||
end
|
||||
{% end %}
|
||||
{% end %}
|
||||
on_to_cbor(cbor)
|
||||
end
|
||||
{% end %}
|
||||
{% end %}
|
||||
end
|
||||
|
||||
|
@ -310,6 +333,10 @@ module CBOR
|
|||
end
|
||||
end
|
||||
|
||||
protected def get_cbor_unmapped
|
||||
cbor_unmapped
|
||||
end
|
||||
|
||||
protected def on_to_cbor(cbor : ::CBOR::Encoder)
|
||||
cbor_unmapped.each do |key, value|
|
||||
cbor.write(key)
|
||||
|
|
Loading…
Reference in New Issue