Parse time
parent
5be5e3b20e
commit
f4ad61665c
|
@ -9,7 +9,14 @@ describe "CBOR helpers on basic types" do
|
||||||
{UInt32, Bytes[0x1a, 0x00, 0x0f, 0x42, 0x40], 1000000},
|
{UInt32, Bytes[0x1a, 0x00, 0x0f, 0x42, 0x40], 1000000},
|
||||||
{UInt64, Bytes[0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00], 1000000000000},
|
{UInt64, Bytes[0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00], 1000000000000},
|
||||||
{Int8, Bytes[0x29], -10},
|
{Int8, Bytes[0x29], -10},
|
||||||
|
{Bool, Bytes[0xf4], false},
|
||||||
|
{Bool, Bytes[0xf5], true},
|
||||||
{Bytes, Bytes[0x44, 0x01, 0x02, 0x03, 0x04], Bytes[0x01, 0x02, 0x03, 0x04]},
|
{Bytes, Bytes[0x44, 0x01, 0x02, 0x03, 0x04], Bytes[0x01, 0x02, 0x03, 0x04]},
|
||||||
|
{Time,
|
||||||
|
Bytes[0xc0, 0x74, 0x32, 0x30, 0x31, 0x33, 0x2d, 0x30, 0x33, 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x5a],
|
||||||
|
Time::Format::RFC_3339.parse("2013-03-21T20:04:00Z")},
|
||||||
|
{Time, Bytes[0xc1, 0x1a, 0x51, 0x4b, 0x67, 0xb0], Time.unix(1363896240)},
|
||||||
|
{Time, Bytes[0xc1, 0xfb, 0x41, 0xd4, 0x52, 0xd9, 0xec, 0x20, 0x00, 0x00], Time.unix_ms((1363896240.5 * 1000).to_i)},
|
||||||
]
|
]
|
||||||
|
|
||||||
tests.each do |tt|
|
tests.each do |tt|
|
||||||
|
|
|
@ -24,15 +24,52 @@ class CBOR::Decoder
|
||||||
read_type(Token::IntT) { |token| token.value }
|
read_type(Token::IntT) { |token| token.value }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def read_float
|
||||||
|
read_type(Token::FloatT) { |token| token.value }
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_num
|
||||||
|
case token = @current_token
|
||||||
|
when Token::IntT, Token::FloatT
|
||||||
|
token.value
|
||||||
|
else
|
||||||
|
unexpected_token(token, "Token::IntT or Token::FloatT")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def read_bytes
|
def read_bytes
|
||||||
read_type(Token::BytesT) { |token| token.value }
|
read_type(Token::BytesT) { |token| token.value }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def read_tag : Tag
|
||||||
|
read_type(Token::TagT) { |token| token.value }
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_bool : Bool
|
||||||
|
read_type(Token::SimpleValueT) do |token|
|
||||||
|
case token.value
|
||||||
|
when SimpleValue::False
|
||||||
|
false
|
||||||
|
when SimpleValue::True
|
||||||
|
true
|
||||||
|
else
|
||||||
|
unexpected_token(token, "SimpleValue::True or SimpleValue::False")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private def finish_token!
|
private def finish_token!
|
||||||
@current_token = @lexer.next_token
|
@current_token = @lexer.next_token
|
||||||
end
|
end
|
||||||
|
|
||||||
private macro read_type(type, finish_token = true, &block)
|
private macro read_type(type, finish_token = true, ignore_tag = true, &block)
|
||||||
|
# Skip the tag unless the token we want to read is a tag
|
||||||
|
{% if type != Token::TagT && ignore_tag %}
|
||||||
|
if @current_token.is_a?(Token::TagT)
|
||||||
|
finish_token!
|
||||||
|
end
|
||||||
|
{% end %}
|
||||||
|
|
||||||
case token = @current_token
|
case token = @current_token
|
||||||
when {{type}}
|
when {{type}}
|
||||||
{% if finish_token %}finish_token!{% end %}
|
{% if finish_token %}finish_token!{% end %}
|
||||||
|
|
|
@ -19,6 +19,30 @@ end
|
||||||
|
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
|
def Bool.new(decoder : CBOR::Decoder)
|
||||||
|
decoder.read_bool
|
||||||
|
end
|
||||||
|
|
||||||
def Slice.new(decoder : CBOR::Decoder)
|
def Slice.new(decoder : CBOR::Decoder)
|
||||||
decoder.read_bytes.to_slice
|
decoder.read_bytes.to_slice
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Reads the CBOR values a time. The value must be surrounded by a time tag as
|
||||||
|
# specified by [Section 2.4.1 of RFC 7049][1].
|
||||||
|
#
|
||||||
|
# [1]: https://tools.ietf.org/html/rfc7049#section-2.4.1
|
||||||
|
def Time.new(decoder : CBOR::Decoder)
|
||||||
|
case tag = decoder.read_tag
|
||||||
|
when CBOR::Tag::RFC3339Time
|
||||||
|
Time::Format::RFC_3339.parse(decoder.read_string)
|
||||||
|
when CBOR::Tag::EpochTime
|
||||||
|
case num = decoder.read_num
|
||||||
|
when Int
|
||||||
|
Time.unix(num)
|
||||||
|
when Float
|
||||||
|
Time.unix_ms((num * 1000).to_i)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise CBOR::ParseError.new("Expected tag to have value 0 or 1, got #{tag.value.to_s}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in New Issue