Complete basic int conversion
parent
9d1c255c2c
commit
a956794f4e
|
@ -2,33 +2,35 @@ require "../spec_helper"
|
|||
|
||||
describe CBOR::Lexer do
|
||||
describe "examples from the RFC7049 Appendix A" do
|
||||
tests : Array(Tuple(String, Bytes)) = [
|
||||
{"0", [0x00]},
|
||||
{"1", [0x01]},
|
||||
# {"10", "0a"},
|
||||
# {"23", "17"},
|
||||
# {"24", "18 18"},
|
||||
# {"25", "18 19"},
|
||||
# {"100", "18 64"},
|
||||
# {"1000", "19 03 e8"},
|
||||
# {"1000000", "1a 00 0f 42 40"},
|
||||
# {"1000000000000", "1b 00 00 00 e8 d4 a5 10 00"},
|
||||
# {"18446744073709551615", "1b ff ff ff ff ff ff ff ff"},
|
||||
tests = [
|
||||
{"0", "00"},
|
||||
{"1", "01"},
|
||||
{"10", "0a"},
|
||||
{"23", "17"},
|
||||
{"24", "18 18"},
|
||||
{"25", "18 19"},
|
||||
{"100", "18 64"},
|
||||
{"1000", "19 03 e8"},
|
||||
{"1000000", "1a 00 0f 42 40"},
|
||||
{"1000000000000", "1b 00 00 00 e8 d4 a5 10 00"},
|
||||
{"18446744073709551615", "1b ff ff ff ff ff ff ff ff"},
|
||||
# {"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"},
|
||||
# {"-1", "20"},
|
||||
# {"-10", "29"},
|
||||
# {"-100", "38 63"},
|
||||
# {"-1000", "39 03 e7"},
|
||||
{"-1", "20"},
|
||||
{"-10", "29"},
|
||||
{"-100", "38 63"},
|
||||
{"-1000", "39 03 e7"},
|
||||
]
|
||||
|
||||
tests.each do |tt|
|
||||
it "Reads #{tt[1].inspect} as #{tt[0]}" do
|
||||
lexer = CBOR::Lexer.new(tt[1])
|
||||
debug, hex = tt
|
||||
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
|
||||
CBOR::Token.to_s(token).should eq(tt[0])
|
||||
CBOR::Token.to_s(token).should eq(debug)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,8 +2,4 @@ require "./spec_helper"
|
|||
|
||||
describe CBOR do
|
||||
# TODO: Write tests
|
||||
|
||||
it "works" do
|
||||
false.should eq(true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,27 +51,31 @@ class CBOR::Lexer
|
|||
when 0x00..0x17
|
||||
consume_int(current_byte)
|
||||
when 0x18
|
||||
consume_int(read(Uint8))
|
||||
consume_int(read(UInt8))
|
||||
when 0x19
|
||||
consume_int(read(Uint16))
|
||||
consume_int(read(UInt16))
|
||||
when 0x1a
|
||||
consume_int(read(Uint32))
|
||||
consume_int(read(UInt32))
|
||||
when 0x1b
|
||||
consume_int(read(Uint64))
|
||||
consume_int(read(UInt64))
|
||||
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
|
||||
consume_int(flip(read(Uint8).to_i8))
|
||||
consume_int(to_negative_int(read(UInt8)))
|
||||
when 0x39
|
||||
consume_int(flip(read(Uint16).to_i16))
|
||||
consume_int(to_negative_int(read(UInt16)))
|
||||
when 0x3a
|
||||
consume_int(flip(read(Uint32).to_i32))
|
||||
consume_int(to_negative_int(read(UInt32)))
|
||||
when 0x3b
|
||||
consume_int(flip(read(Uint64).to_i64))
|
||||
consume_int(to_negative_int(read(UInt64)))
|
||||
else
|
||||
fail
|
||||
end
|
||||
end
|
||||
|
||||
private def next_byte : Uint8
|
||||
private def next_byte : UInt8
|
||||
byte = @io.read_byte
|
||||
@byte_number += 1
|
||||
fail unless byte
|
||||
|
@ -82,10 +86,25 @@ class CBOR::Lexer
|
|||
Token::IntT.new(@current_byte_number, value)
|
||||
end
|
||||
|
||||
private def flip(value)
|
||||
-1 - value
|
||||
{% begin %}
|
||||
{% uints = %w(UInt8 UInt16 UInt32 UInt64) %}
|
||||
{% 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
|
||||
@byte_number += sizeof(T)
|
||||
@io.read_bytes(T, IO::ByteFormat::NetworkEndian)
|
||||
|
|
|
@ -3,7 +3,7 @@ class CBOR::Token
|
|||
record BoolT, byte_number : Int32, value : Bool
|
||||
record ArrayT, 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 StringT, byte_number : Int32, value : String
|
||||
record BytesT, byte_number : Int32, value : Bytes
|
||||
|
|
Loading…
Reference in New Issue