Implement Strings decoding

dev
Alberto Restifo 2020-04-21 23:18:56 +02:00
parent 37677a40ad
commit 321b3fd986
3 changed files with 30 additions and 9 deletions

View File

@ -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" },

View File

@ -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

View File

@ -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