From 5f838d36cc75b57fac847da56ef8fdd9b9462a7b Mon Sep 17 00:00:00 2001 From: Karchnu Date: Tue, 10 Nov 2020 20:14:50 +0100 Subject: [PATCH] Compute the number of object properties to serialize. --- src/cbor/serializable.cr | 51 +++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/cbor/serializable.cr b/src/cbor/serializable.cr index 7ebd7d2..77d0689 100644 --- a/src/cbor/serializable.cr +++ b/src/cbor/serializable.cr @@ -136,6 +136,7 @@ module CBOR end private def self.new_from_cbor_decoder(decoder : ::CBOR::Decoder) + # puts "self.new_from_cbor_decoder" instance = allocate instance.initialize(__decoder_for_cbor_serializable: decoder) GC.add_finalizer(instance) if instance.responds_to?(:finalize) @@ -268,9 +269,27 @@ 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 %} # macro unless value[:emit_null] + {% end %} # macro for properties + + + + {% 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,23 +298,23 @@ 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 %} # macro if value[:converter] + _{{name}}.to_cbor(cbor) + {% end %} # macro if value[:converter] {% unless value[:emit_null] %} - end - {% end %} - {% end %} + end # unless _{{name}}.nil? + {% end %} # macro unless value[:emit_null] + {% end %} # macro for properties on_to_cbor(cbor) - end - {% end %} + {% end %} # macro if properties.size > 0 + {% end %} # begin end module Unmapped