2020-04-17 14:32:43 +02:00
|
|
|
require "./token"
|
|
|
|
|
|
|
|
class CBOR::Lexer
|
|
|
|
@current_byte : UInt8
|
|
|
|
|
|
|
|
def initialize(@io : IO)
|
|
|
|
@current_byte = 0x0
|
|
|
|
end
|
|
|
|
|
|
|
|
def next_token : Token?
|
|
|
|
byte = @io.read_byte
|
|
|
|
return nil if byte.nil?
|
|
|
|
|
|
|
|
@current_byte = byte
|
|
|
|
|
|
|
|
# See: RFC7049 Appedix B
|
|
|
|
case @current_byte
|
|
|
|
when .<= 0x17
|
|
|
|
Token.new(kind: Token::Kind::UInt, value: @curren_byte)
|
|
|
|
when 0x18
|
|
|
|
read_uint8
|
2020-04-17 19:50:26 +02:00
|
|
|
when 0x19
|
|
|
|
read_uint16
|
|
|
|
when 0x1a
|
|
|
|
read_uint32
|
|
|
|
when 0x1b
|
|
|
|
read_uint64
|
|
|
|
when .<= 0x37
|
|
|
|
Token.new(kind: Token::Kind::NInt, value: Int8(@curren_byte))
|
2020-04-17 14:32:43 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private def read_uint8
|
|
|
|
byte = @io.read_byte
|
|
|
|
return unexpect_eof if byte.nil?
|
|
|
|
|
|
|
|
Token.new(kind: Token::Kind::UInt, value: byte)
|
|
|
|
end
|
|
|
|
|
2020-04-17 19:50:26 +02:00
|
|
|
private def read_uint16
|
|
|
|
value = UInt16.from_io(read_next(2), IO::ByteFormat::BigEndian)
|
|
|
|
Token.new(kind: Token::Kind::UInt, value: value)
|
|
|
|
end
|
|
|
|
|
|
|
|
private def read_uint32
|
|
|
|
value = UInt32.from_io(read_next(4), IO::ByteFormat::BigEndian)
|
|
|
|
Token.new(kind: Token::Kind::UInt, value: value)
|
|
|
|
end
|
|
|
|
|
|
|
|
private def read_uint64
|
|
|
|
value = UInt64.from_io(read_next(8), IO::ByteFormat::BigEndian)
|
|
|
|
Token.new(kind: Token::Kind::UInt, value: value)
|
|
|
|
end
|
|
|
|
|
|
|
|
private def read_next(n : Int)
|
|
|
|
slice = Bytes.new(n)
|
|
|
|
|
|
|
|
read = @io.read(slice)
|
|
|
|
return unexpect_eof if read == 0
|
|
|
|
|
|
|
|
slice
|
|
|
|
end
|
|
|
|
|
2020-04-17 14:32:43 +02:00
|
|
|
private def unexpected_eof
|
|
|
|
raise "Unexpected EOF"
|
|
|
|
end
|
|
|
|
end
|