Complete basic int conversion
parent
9d1c255c2c
commit
a956794f4e
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,10 +86,25 @@ 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) %}
|
||||||
|
{% 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
|
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)
|
||||||
@io.read_bytes(T, IO::ByteFormat::NetworkEndian)
|
@io.read_bytes(T, IO::ByteFormat::NetworkEndian)
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue