crystal-cbor/src/cbor/lexer.cr

68 lines
1.4 KiB
Crystal
Raw Normal View History

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