diff --git a/spec/rfc_spec.cr b/spec/rfc_spec.cr index ed8c4ee..3dccb55 100644 --- a/spec/rfc_spec.cr +++ b/spec/rfc_spec.cr @@ -56,13 +56,13 @@ tests = [ # { %(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" }, - # { %("a"), "61 61" }, - # { %("IETF"), "64 49 45 54 46" }, - # { %(""\\"), "62 22 5c" }, - # { %("\u00fc"), "62 c3 bc" }, - # { %("\u6c34"), "63 e6 b0 b4" }, - # { %("\ud800\udd51"), "64 f0 90 85 91" }, + { %(""), "60" }, + { %("a"), "61 61" }, + { %("IETF"), "64 49 45 54 46" }, + { %(""\\"), "62 22 5c" }, + { %("\u00fc"), "62 c3 bc" }, + { %("\u6c34"), "63 e6 b0 b4" }, + # { %("\ud800\udd51"), "64 f0 90 85 91" }, TODO: Maybe there is a problem with unicode escaping? Or maybe it's just the diagnostics # { %([]), "80" }, # { %([1, 2, 3]), "83 01 02 03" }, # { %([1, [2, 3], [4, 5]]), "83 01 82 02 03 82 04 05" }, diff --git a/src/cbor/diagnostic.cr b/src/cbor/diagnostic.cr index 4eaaa33..9774374 100644 --- a/src/cbor/diagnostic.cr +++ b/src/cbor/diagnostic.cr @@ -28,6 +28,8 @@ class CBOR::Diagnostic case token[:kind] when Kind::Int token[:value].to_s + when Kind::String + %("#{token[:value].as(String)}") when Kind::Bytes "h'#{token[:value].as(Bytes).hexstring}'" when Kind::BytesArray diff --git a/src/cbor/lexer.cr b/src/cbor/lexer.cr index 58b81bb..850cc0d 100644 --- a/src/cbor/lexer.cr +++ b/src/cbor/lexer.cr @@ -108,6 +108,16 @@ class CBOR::Lexer consume_binary(read(UInt64)) when 0x5f {kind: open_token(Kind::BytesArray), value: nil} + when 0x60..0x77 + consume_string(current_byte - 0x60) + when 0x78 + consume_string(read(UInt8)) + when 0x79 + consume_string(read(UInt16)) + when 0x7a + consume_string(read(UInt32)) + when 0x7b + consume_string(read(UInt16)) when 0xff {kind: finish_token, value: nil} else @@ -130,11 +140,14 @@ class CBOR::Lexer end private def consume_binary(size) - bytes = Bytes.new(size) - @io.read_fully(bytes) + bytes = read_bytes(size) {kind: Kind::Bytes, value: bytes} end + private def consume_string(size) + {kind: Kind::String, value: @io.read_string(size)} + end + private def open_token(kind : Kind) : Kind @open_tokens << kind kind @@ -177,6 +190,12 @@ class CBOR::Lexer {% end %} {% end %} + private def read_bytes(size) + bytes = Bytes.new(size) + @io.read_fully(bytes) + bytes + end + private def read(type : T.class) forall T @io.read_bytes(T, IO::ByteFormat::NetworkEndian) end