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]
|
## [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
|
## [0.2.1] - 2020-09-29
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -54,7 +54,7 @@ house = House.from_cbor(cbor)
|
||||||
house.address # => "Crystal Road 1234"
|
house.address # => "Crystal Road 1234"
|
||||||
house.location # => #<Location:0x10cd93d80 @latitude=12.3, @longitude=34.5>
|
house.location # => #<Location:0x10cd93d80 @latitude=12.3, @longitude=34.5>
|
||||||
bytes = house.to_cbor # => Bytes[...]
|
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]
|
data_array = [data]
|
||||||
cbor_array = data_array.to_cbor # => Bytes[...]
|
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 = Array(House).from_cbor(cbor_array)
|
||||||
houses.size # => 1
|
houses.size # => 1
|
||||||
bytes = houses.to_cbor # => Bytes[...]
|
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
|
## Installation
|
||||||
|
@ -158,7 +158,7 @@ end
|
||||||
|
|
||||||
a = A.from_cbor({"a" => 1, "b" => 2}.to_cbor) # => A(@cbor_unmapped={"b" => 2}, @a=1)
|
a = A.from_cbor({"a" => 1, "b" => 2}.to_cbor) # => A(@cbor_unmapped={"b" => 2}, @a=1)
|
||||||
bytes = a.to_cbor # => Bytes[...]
|
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`
|
### Class annotation `CBOR::Serializable::Options`
|
||||||
|
|
|
@ -66,7 +66,7 @@ end
|
||||||
|
|
||||||
describe CBOR::Serializable do
|
describe CBOR::Serializable do
|
||||||
describe "rfc examples" 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
|
it "decodes from cbor" do
|
||||||
result = ExampleA.from_cbor(Bytes[0xbf, 0x61, 0x61, 0x01, 0x61, 0x62, 0x9f, 0x02, 0x03, 0xff, 0xff])
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe %(example {_ "Fun": true, "Amt": -2}) do
|
describe %(example {"Fun": true, "Amt": -2}) do
|
||||||
it "decodes from cbor" do
|
it "decodes from cbor" do
|
||||||
result = ExampleB.from_cbor(Bytes[0xbf, 0x63, 0x46, 0x75, 0x6e, 0xf5, 0x63, 0x41, 0x6d, 0x74, 0x21, 0xff])
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe %(example ["a", {_ "b": "c"}]) do
|
describe %(example ["a", {"b": "c"}]) do
|
||||||
it "decodes from cbor" do
|
it "decodes from cbor" do
|
||||||
result = Array(String | ExampleC).from_cbor(Bytes[0x82, 0x61, 0x61, 0xbf, 0x61, 0x62, 0x61, 0x63, 0xff])
|
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
|
it "encodes to CBOR" do
|
||||||
cbor = House.from_cbor(bytes).to_cbor
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ describe CBOR::Serializable do
|
||||||
it "encodes to CBOR" do
|
it "encodes to CBOR" do
|
||||||
cbor = Array(House).from_cbor(bytes).to_cbor
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ describe CBOR::Serializable do
|
||||||
res.a.should eq(1)
|
res.a.should eq(1)
|
||||||
res.cbor_unmapped.should eq({"b" => 2})
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -243,6 +243,10 @@ module CBOR
|
||||||
raise ::CBOR::SerializationError.new("Unknown CBOR attribute: #{key}", self.class.to_s, nil)
|
raise ::CBOR::SerializationError.new("Unknown CBOR attribute: #{key}", self.class.to_s, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected def get_cbor_unmapped
|
||||||
|
{} of String => ::CBOR::Type
|
||||||
|
end
|
||||||
|
|
||||||
protected def on_to_cbor(cbor : ::CBOR::Encoder)
|
protected def on_to_cbor(cbor : ::CBOR::Encoder)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -268,7 +272,26 @@ module CBOR
|
||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
cbor.object do
|
# 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 %}
|
{% for name, value in properties %}
|
||||||
_{{name}} = @{{name}}
|
_{{name}} = @{{name}}
|
||||||
|
|
||||||
|
@ -294,7 +317,7 @@ module CBOR
|
||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
on_to_cbor(cbor)
|
on_to_cbor(cbor)
|
||||||
end
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -310,6 +333,10 @@ module CBOR
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected def get_cbor_unmapped
|
||||||
|
cbor_unmapped
|
||||||
|
end
|
||||||
|
|
||||||
protected def on_to_cbor(cbor : ::CBOR::Encoder)
|
protected def on_to_cbor(cbor : ::CBOR::Encoder)
|
||||||
cbor_unmapped.each do |key, value|
|
cbor_unmapped.each do |key, value|
|
||||||
cbor.write(key)
|
cbor.write(key)
|
||||||
|
|
Loading…
Reference in New Issue