Complete basic int conversion

dev
Alberto Restifo 2020-04-19 12:16:05 +02:00
parent 9d1c255c2c
commit a956794f4e
4 changed files with 56 additions and 39 deletions

View File

@ -2,33 +2,35 @@ require "../spec_helper"
describe CBOR::Lexer do describe CBOR::Lexer do
describe "examples from the RFC7049 Appendix A" do describe "examples from the RFC7049 Appendix A" do
tests : Array(Tuple(String, Bytes)) = [ tests = [
{"0", [0x00]}, {"0", "00"},
{"1", [0x01]}, {"1", "01"},
# {"10", "0a"}, {"10", "0a"},
# {"23", "17"}, {"23", "17"},
# {"24", "18 18"}, {"24", "18 18"},
# {"25", "18 19"}, {"25", "18 19"},
# {"100", "18 64"}, {"100", "18 64"},
# {"1000", "19 03 e8"}, {"1000", "19 03 e8"},
# {"1000000", "1a 00 0f 42 40"}, {"1000000", "1a 00 0f 42 40"},
# {"1000000000000", "1b 00 00 00 e8 d4 a5 10 00"}, {"1000000000000", "1b 00 00 00 e8 d4 a5 10 00"},
# {"18446744073709551615", "1b ff ff ff ff ff ff ff ff"}, {"18446744073709551615", "1b ff ff ff ff ff ff ff ff"},
# {"18446744073709551616", "c2 49 01 00 00 00 00 00 00 0000"}, # {"18446744073709551616", "c2 49 01 00 00 00 00 00 00 00 00"},
# {"-18446744073709551616", "3b ff ff ff ff ff ff ff ff"}, {"-18446744073709551616", "3b ff ff ff ff ff ff ff ff"},
# {"-18446744073709551617", "c3 49 01 00 00 00 00 00 00 00 00"}, # {"-18446744073709551617", "c3 49 01 00 00 00 00 00 00 00 00"},
# {"-1", "20"}, {"-1", "20"},
# {"-10", "29"}, {"-10", "29"},
# {"-100", "38 63"}, {"-100", "38 63"},
# {"-1000", "39 03 e7"}, {"-1000", "39 03 e7"},
] ]
tests.each do |tt| tests.each do |tt|
it "Reads #{tt[1].inspect} as #{tt[0]}" do debug, hex = tt
lexer = CBOR::Lexer.new(tt[1]) it "Reads #{hex} as #{debug}" do
bytes = hex.split.map(&.to_u8(16))
lexer = CBOR::Lexer.new(Slice.new(bytes.to_unsafe, bytes.size))
token = lexer.read_token token = lexer.read_token
CBOR::Token.to_s(token).should eq(tt[0]) CBOR::Token.to_s(token).should eq(debug)
end end
end end
end end

View File

@ -2,8 +2,4 @@ require "./spec_helper"
describe CBOR do describe CBOR do
# TODO: Write tests # TODO: Write tests
it "works" do
false.should eq(true)
end
end end

View File

@ -51,27 +51,31 @@ class CBOR::Lexer
when 0x00..0x17 when 0x00..0x17
consume_int(current_byte) consume_int(current_byte)
when 0x18 when 0x18
consume_int(read(Uint8)) consume_int(read(UInt8))
when 0x19 when 0x19
consume_int(read(Uint16)) consume_int(read(UInt16))
when 0x1a when 0x1a
consume_int(read(Uint32)) consume_int(read(UInt32))
when 0x1b when 0x1b
consume_int(read(Uint64)) consume_int(read(UInt64))
when 0x20..0x37 when 0x20..0x37
consume_int(flip(current_byte.to_i8)) # This range represents values from -1..-24 so we subtract 0x20
# from the uint8 value to
consume_int(to_negative_int(current_byte.to_u8 - 0x20))
when 0x38 when 0x38
consume_int(flip(read(Uint8).to_i8)) consume_int(to_negative_int(read(UInt8)))
when 0x39 when 0x39
consume_int(flip(read(Uint16).to_i16)) consume_int(to_negative_int(read(UInt16)))
when 0x3a when 0x3a
consume_int(flip(read(Uint32).to_i32)) consume_int(to_negative_int(read(UInt32)))
when 0x3b when 0x3b
consume_int(flip(read(Uint64).to_i64)) consume_int(to_negative_int(read(UInt64)))
else
fail
end end
end end
private def next_byte : Uint8 private def next_byte : UInt8
byte = @io.read_byte byte = @io.read_byte
@byte_number += 1 @byte_number += 1
fail unless byte fail unless byte
@ -82,9 +86,24 @@ class CBOR::Lexer
Token::IntT.new(@current_byte_number, value) Token::IntT.new(@current_byte_number, value)
end end
private def flip(value) {% begin %}
-1 - value {% uints = %w(UInt8 UInt16 UInt32 UInt64) %}
end {% conv = %w(to_i8 to_i16 to_i32 to_i64 to_i128) %}
{% for uint, index in uints %}
# Reads the `{{uint.id}}` as a negative integer, returning the samllest
# integer capable of containing the value.
def to_negative_int(value : {{uint.id}})
int = begin
-value.{{conv[index].id}}
rescue OverflowError
-value.{{conv[index + 1].id}}
end
int - 1
end
{% end %}
{% end %}
private def read(type : T.class) forall T private def read(type : T.class) forall T
@byte_number += sizeof(T) @byte_number += sizeof(T)

View File

@ -3,7 +3,7 @@ class CBOR::Token
record BoolT, byte_number : Int32, value : Bool record BoolT, byte_number : Int32, value : Bool
record ArrayT, byte_number : Int32, size : UInt32 record ArrayT, byte_number : Int32, size : UInt32
record MapT, byte_number : Int32, size : UInt32 record MapT, byte_number : Int32, size : UInt32
record IntT, byte_number : Int32, value : Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 record IntT, byte_number : Int32, value : Int8 | UInt8 | Int16 | UInt16 | Int32 | UInt32 | Int64 | UInt64 | Int128
record FloatT, byte_number : Int32, value : Float64 record FloatT, byte_number : Int32, value : Float64
record StringT, byte_number : Int32, value : String record StringT, byte_number : Int32, value : String
record BytesT, byte_number : Int32, value : Bytes record BytesT, byte_number : Int32, value : Bytes