Implement floats

dev
Alberto Restifo 2020-04-24 00:05:50 +02:00
parent e7f4426062
commit a78d06f33a
5 changed files with 43 additions and 20 deletions

View File

@ -9,9 +9,16 @@ in Crystal.
- Full RFC7049 support
- Full support for diagnostic notation
- Assign a field to a type base on the CBOR tag
- Support for a wide range of IANA CBOR Tags
## Limitations
### Half-precision floating point is not supported
Crystal doesn't have a `Float16` type, so half-precision floating point numbers
are not supported for the time being.
### Maximum Array/String array/Bytes array length
The spec allows for the maximum length of arrays, string arrays and bytes array

View File

@ -1,14 +1,6 @@
require "./spec_helper"
# All those tests have been exported from the RFC7049 appendix A.
#
# Some test results have been modified as the tool doesn't support
# the full diagnostic notation as per RFC.
#
# Specifically:
#
# * Removed the undescore marking the start of infinite stirngs, bytes and
# array. This implementation doesn't expose the difference between the two.
tests = [
{ %(0), "00" },
@ -32,25 +24,25 @@ tests = [
# { %(0.0), "f9 00 00" },
# { %(-0.0), "f9 80 00" },
# { %(1.0), "f9 3c 00" },
# { %(1.1), "fb 3f f1 99 99 99 99 99 9a" },
{ %(1.1), "fb 3f f1 99 99 99 99 99 9a" },
# { %(1.5), "f9 3e 00" },
# { %(65504.0), "f9 7b ff" },
# { %(100000.0), "fa 47 c3 50 00" },
# { %(3.4028234663852886e+38), "fa 7f 7f ff ff" },
# { %(1.0e+300), "fb 7e 37 e4 3c 88 00 75 9c" },
{ %(100000.0), "fa 47 c3 50 00" },
# { %(3.4028234663852886e+38), "fa 7f 7f ff ff" }, TODO: Not precise enough?
{ %(1.0e+300), "fb 7e 37 e4 3c 88 00 75 9c" },
# { %(5.960464477539063e-8), "f9 00 01" },
# { %(0.00006103515625), "f9 04 00" },
# { %(-4.0), "f9 c4 00" },
# { %(-4.1), "fb c0 10 66 66 66 66 66 66" },
{ %(-4.1), "fb c0 10 66 66 66 66 66 66" },
# { %(Infinity), "f9 7c 00" },
# { %(NaN), "f9 7e 00" },
# { %(-Infinity), "f9 fc 00" },
# { %(Infinity), "fa 7f 80 00 00" },
# { %(NaN), "fa 7f c0 00 00" },
# { %(-Infinity), "fa ff 80 00 00" },
# { %(Infinity), "fb 7f f0 00 00 00 00 00 00" },
# { %(NaN), "fb 7f f8 00 00 00 00 00 00" },
# { %(-Infinity), "fb ff f0 00 00 00 00 00 00" },
{ %(Infinity), "fa 7f 80 00 00" },
{ %(NaN), "fa 7f c0 00 00" },
{ %(-Infinity), "fa ff 80 00 00" },
{ %(Infinity), "fb 7f f0 00 00 00 00 00 00" },
{ %(NaN), "fb 7f f8 00 00 00 00 00 00" },
{ %(-Infinity), "fb ff f0 00 00 00 00 00 00" },
{ %(false), "f4" },
{ %(true), "f5" },
{ %(null), "f6" },

View File

@ -54,6 +54,20 @@ class CBOR::Diagnostic
token.value.to_diagnostic
when Token::TagT
"#{token.value.value.to_s}(#{next_value})"
when Token::FloatT
return "NaN" if token.value.nan?
return token.value.to_s if token.value.finite?
case value = token.value
when Float32
return "Infinity" if value == Float32::INFINITY
"-Infinity"
when Float64
return "Infinity" if value == Float64::INFINITY
"-Infinity"
else
token.value.to_s
end
else
token.inspect
end

View File

@ -81,9 +81,14 @@ class CBOR::Lexer
Token::MapT.new
when 0xc0..0xdb
consume_tag(read_size(byte - 0xc0))
##################
when 0xe0..0xf8
consume_simple_value(read_size(byte - 0xe0))
when 0xf9
raise ParseError.new("Half-precision floating points are not supported")
when 0xfa
Token::FloatT.new(value: read(Float32))
when 0xfb
Token::FloatT.new(value: read(Float64))
else
raise ParseError.new("Unexpected first byte 0x#{byte.to_s(16)}")
end

View File

@ -6,6 +6,10 @@ enum CBOR::Tag : UInt32
Decimal
BigFloat
CSOEEnCrypt = 16
CSOEMac
CSOESign
ConvertBase64URL = 21
ConvertBase64
ConvertBase16
@ -16,6 +20,7 @@ enum CBOR::Tag : UInt32
Base64
RegularExpression
MimeMessage
UUID
CBORMarker = 55799
end