Implement simple values

dev
Alberto Restifo 2020-04-23 23:25:28 +02:00
parent 4872fc4471
commit e7f4426062
6 changed files with 72 additions and 49 deletions

View File

@ -51,19 +51,19 @@ tests = [
# { %(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" },
# { %(undefined), "f7" },
# { %(simple(16)), "f0" },
# { %(simple(24)), "f8 18" },
# { %(simple(255)), "f8 ff" },
# { %(0("2013-03-21T20:04:00Z")), "c0 74 32 30 31 33 2d 30 33 2d 32 31 54 32 30 3a 30 34 3a 30 30 5a" },
# { %(1(1363896240)), "c1 1a 51 4b 67 b0" },
{ %(false), "f4" },
{ %(true), "f5" },
{ %(null), "f6" },
{ %(undefined), "f7" },
{ %(simple(16)), "f0" },
{ %(simple(24)), "f8 18" },
{ %(simple(255)), "f8 ff" },
{ %(0("2013-03-21T20:04:00Z")), "c0 74 32 30 31 33 2d 30 33 2d 32 31 54 32 30 3a 30 34 3a 30 30 5a" },
{ %(1(1363896240)), "c1 1a 51 4b 67 b0" },
# { %(1(1363896240.5)), "c1 fb 41 d4 52 d9 ec 20 00 00" },
# { %(23(h'01020304')), "d7 44 01 02 03 04" },
# { %(24(h'6449455446')), "d8 18 45 64 49 45 54 46" },
# { %(32("http://www.example.com")), "d8 20 76 68 74 74 70 3a 2f 2f 77 77 77 2e 65 78 61 6d 70 6c 65 2e 63 6f 6d" },
{ %(23(h'01020304')), "d7 44 01 02 03 04" },
{ %(24(h'6449455446')), "d8 18 45 64 49 45 54 46" },
{ %(32("http://www.example.com")), "d8 20 76 68 74 74 70 3a 2f 2f 77 77 77 2e 65 78 61 6d 70 6c 65 2e 63 6f 6d" },
{ %(h''), "40" },
{ %(h'01020304'), "44 01 02 03 04" },
{ %(""), "60" },

View File

@ -50,9 +50,10 @@ class CBOR::Diagnostic
hash_body = read_hash(token.size).join(", ")
return "{#{hash_body}}" if token.size
"{_ #{hash_body}}"
when Token::BoolT
return "true" if token.value
"false"
when Token::SimpleValueT
token.value.to_diagnostic
when Token::TagT
"#{token.value.value.to_s}(#{next_value})"
else
token.inspect
end

View File

@ -82,10 +82,8 @@ class CBOR::Lexer
when 0xc0..0xdb
consume_tag(read_size(byte - 0xc0))
##################
when 0xf4
Token::BoolT.new(value: false)
when 0xf5
Token::BoolT.new(value: true)
when 0xe0..0xf8
consume_simple_value(read_size(byte - 0xe0))
else
raise ParseError.new("Unexpected first byte 0x#{byte.to_s(16)}")
end
@ -172,9 +170,14 @@ class CBOR::Lexer
Token::MapT.new(size: size.to_i32)
end
private def consume_tag(size) : Token::TagT
raise ParseError.new("Maximum size for tag exceeded") if size > UInt32::MAX
Token::TagT.new(id: size.to_u32)
private def consume_tag(id) : Token::TagT
raise ParseError.new("Maximum size for tag ID exceeded") if id > UInt32::MAX
Token::TagT.new(value: Tag.new(id.to_u32))
end
private def consume_simple_value(id) : Token::SimpleValueT
raise ParseError.new("Invalid simple value #{id.to_s}") if id > 255
Token::SimpleValueT.new(value: SimpleValue.new(id.to_u8))
end
# Creates a method overloaded for each UInt sizes to convert the UInt into

21
src/cbor/simple_value.cr Normal file
View File

@ -0,0 +1,21 @@
enum CBOR::SimpleValue : UInt8
False = 20
True
Null
Undefined
def to_diagnostic : String
case self
when False
"false"
when True
"true"
when Null
"null"
when Undefined
"undefined"
else
"simple(#{self.value.to_s})"
end
end
end

View File

@ -1,21 +1,21 @@
module CBOR::Tag
enum Kind
Unassigned
RFC3339Time
EpochTime
PositiveBigNum
NegativeBigNum
DecimalFraction
BigFloat
ExpectBase64URLConversion
ExpectBase64Conversion
ExpectBase16Conversion
EncodedCBOR
URI
Base64URL
Base64
RegularExpresion
MIME
SelfDescribeCBOR
end
enum CBOR::Tag : UInt32
RFC3339Time
EpochTime
PositiveBigNum
NegativeBigNum
Decimal
BigFloat
ConvertBase64URL = 21
ConvertBase64
ConvertBase16
CBOREncoded
URI = 32
Base64URL
Base64
RegularExpression
MimeMessage
CBORMarker = 55799
end

View File

@ -1,21 +1,19 @@
module CBOR::Token
record NullT, undefined : Bool = false
record BoolT, value : Bool
record IntT, value : Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Int128
record FloatT, value : Float32 | Float64
record BytesT, value : Bytes, chunks : Array(Int32)? = nil
record StringT, value : String, chunks : Array(Int32)? = nil
record ArrayT, size : Int32? = nil
record MapT, size : Int32? = nil
record TagT, id : UInt32
record TagT, value : Tag
record SimpleValueT, value : SimpleValue
alias T = NullT |
BoolT |
IntT |
alias T = IntT |
FloatT |
BytesT |
StringT |
ArrayT |
MapT |
TagT
TagT |
SimpleValueT
end