Fix BytesArray functioning

dev
Alberto Restifo 2020-04-21 22:48:27 +02:00
parent 154876403e
commit 37677a40ad
6 changed files with 56 additions and 52 deletions

View File

@ -0,0 +1,29 @@
require "../spec_helper"
describe CBOR::BytesArray do
describe "#to_bytes" do
it "converts to bytes" do
arr = CBOR::BytesArray.new
arr << Bytes[0xff, 0xff]
arr << Bytes[0xee, 0xee]
bytes = arr.to_bytes
bytes.size.should eq(4)
bytes.should eq(Bytes[0xff, 0xff, 0xee, 0xee])
end
it "can be called more than ocne" do
arr = CBOR::BytesArray.new
arr << Bytes[0xff, 0xff]
arr << Bytes[0xee, 0xee]
bytes1 = arr.to_bytes
bytes1.size.should eq(4)
bytes1.should eq(Bytes[0xff, 0xff, 0xee, 0xee])
bytes2 = arr.to_bytes
bytes2.size.should eq(4)
bytes2.should eq(Bytes[0xff, 0xff, 0xee, 0xee])
end
end
end

View File

@ -19,5 +19,6 @@ module CBOR
UInt32 |
Int64 |
UInt64 |
Int128
Int128 |
BytesArray
end

View File

@ -16,7 +16,7 @@ class CBOR::Diagnostic
def to_s : String
result = ""
while value = next_value
result << value
result += value
end
result
end
@ -26,10 +26,14 @@ class CBOR::Diagnostic
return nil unless token
case token[:kind]
when Kind::Int
token[:value].to_s
when Kind::Bytes
"h'#{token[:value].as(Bytes).hexstring}'"
when Kind::BytesArray
BytesArray.new(token[:value]).to_diagnostics
token[:value].as(BytesArray).to_diagnostic
else
Token.do_diagnostics(token)
token[:kind].to_s
end
end
end

View File

@ -51,7 +51,7 @@ class CBOR::Lexer
end
# Consumes the bytes array until it reaches a break
def read_bytes_array : Bytes
def read_bytes_array : CBOR::BytesArray
bytes = BytesArray.new
loop do
@ -59,10 +59,10 @@ class CBOR::Lexer
raise ParseError.new("Unexpected EOF while reading bytes array") unless token
break if token[:kind] == Kind::BytesArrayEnd
raise ParseError.new("Illegal token #{token.class} while reading bytes array") unless token[:kind] == Kind::Bytes
bytes << token[:value].as(UInt8)
bytes << token[:value].as(Bytes)
end
bytes.to_bytes
bytes
end
private def next_token : Token?

View File

@ -13,38 +13,6 @@ enum CBOR::Kind
Array
ArrayEnd
Map
def to_diagnostic : String
case self
when Int
token.value.to_s
when Bytes
return %(h'') if token.value.empty?
"h'#{token.value.hexstring}'"
when Null
"null"
when Undefined
"undefined"
when BoolT
token.value.to_s
when BytesArray
"(_ "
when BytesArrayEnd
")"
when Float
"TODO"
when String
"TODO"
when StringArray
"TODO"
when Map
"TODO"
when Array
"TODO"
else
raise "Uknown diagnostics representation for #{self.to_s}"
end
end
end
alias CBOR::Token = NamedTuple(kind: Kind, value: Type)

View File

@ -1,21 +1,23 @@
class CBOR::BytesArray < Array(UInt8)
def self.new(bytes : Bytes)
new(bytes.to_a)
end
def to_a : Array(UInt8)
self.as(Array(UInt8))
end
class CBOR::BytesArray < Array(Bytes)
def to_bytes : Bytes
Bytes.new(self.to_unsafe, self.size)
size = reduce(0) { |acc, chunk| acc + chunk.size }
bytes = Bytes.new(size)
# Copy each chunk into the new bytes slice
ptr = bytes.to_unsafe
each do |chunk|
chunk.copy_to(ptr, chunk.size)
ptr += chunk.size
end
bytes
end
def to_diagnostic : String
"(_ #{map(&to_byte_diagnostic).join(", ")})"
"(_ #{map { |chunk| to_byte_diagnostic(chunk) }.join(", ")})"
end
private def to_byte_diagnostic(i : UInt8) : String
"h'#{i.hexstring}'"
private def to_byte_diagnostic(chunk : Bytes) : String
"h'#{chunk.hexstring}'"
end
end