# var r = new FileReader.open("/tmp/data.bin")
# assert r.read(5) == "hello"
# assert r.read_int64 == 123456789
-# assert r.read_byte == 3u8
+# assert r.read_byte == 3
# assert r.read_float == 1.25
# assert r.read_double == 1.234567
#
# Read a single byte and return `true` if its value is different than 0
#
# Returns `false` when an error is pending (`last_error != null`).
- fun read_bool: Bool do return read_byte != 0u8
+ fun read_bool: Bool do return read_byte > 0
# Get an `Array` of 8 `Bool` by reading a single byte
#
fun read_bits: Array[Bool]
do
var int = read_byte
- if int == null then return new Array[Bool]
+ if int < 0 then return new Array[Bool]
var arr = new Array[Bool]
for i in [7 .. 0].step(-1) do
- arr.push(((int >> i) & 1u8) != 0u8)
+ arr.push(((int >> i) & 1) != 0)
end
return arr
end
var buf = new Bytes.empty
loop
var byte = read_byte
- if byte == null or byte == 0u8 then
+ if byte <= 0 then
return buf.to_s
end
- buf.add byte
+ buf.add byte.to_b
end
end
var b3 = read_byte
# Check for error, `last_error` is set by `read_byte`
- if b0 == null or b1 == null or b2 == null or b3 == null then return 0.0
+ if b0 < 0 or b1 < 0 or b2 < 0 or b3 < 0 then return 0.0
return native_read_float(b0, b1, b2, b3, big_endian)
end
# Utility for `read_float`
- private fun native_read_float(b0, b1, b2, b3: Byte, big_endian: Bool): Float `{
+ private fun native_read_float(b0, b1, b2, b3: Int, big_endian: Bool): Float `{
union {
unsigned char b[4];
float val;
var b7 = read_byte
# Check for error, `last_error` is set by `read_byte`
- if b0 == null or b1 == null or b2 == null or b3 == null or
- b4 == null or b5 == null or b6 == null or b7 == null then return 0.0
+ if b0 < 0 or b1 < 0 or b2 < 0 or b3 < 0 or
+ b4 < 0 or b5 < 0 or b6 < 0 or b7 < 0 then return 0.0
return native_read_double(b0, b1, b2, b3, b4, b5, b6, b7, big_endian)
end
# Utility for `read_double`
- private fun native_read_double(b0, b1, b2, b3, b4, b5, b6, b7: Byte, big_endian: Bool): Float `{
+ private fun native_read_double(b0, b1, b2, b3, b4, b5, b6, b7: Int, big_endian: Bool): Float `{
union {
unsigned char b[8];
double val;
var b7 = read_byte
# Check for error, `last_error` is set by `read_byte`
- if b0 == null or b1 == null or b2 == null or b3 == null or
- b4 == null or b5 == null or b6 == null or b7 == null then return 0
+ if b0 < 0 or b1 < 0 or b2 < 0 or b3 < 0 or
+ b4 < 0 or b5 < 0 or b6 < 0 or b7 < 0 then return 0
return native_read_int64(b0, b1, b2, b3, b4, b5, b6, b7, big_endian)
end
# Utility for `read_int64`
- private fun native_read_int64(b0, b1, b2, b3, b4, b5, b6, b7: Byte, big_endian: Bool): Int `{
+ private fun native_read_int64(b0, b1, b2, b3, b4, b5, b6, b7: Int, big_endian: Bool): Int `{
union {
unsigned char b[8];
int64_t val;
# Convert from simple Json object to Nit object
private fun deserialize_next_object: nullable Object
do
- var kind = stream.read_byte
- assert kind isa Byte else
+ var kindi = stream.read_byte
+ assert kindi >= 0 else
# TODO break even on keep_going
return null
end
+ var kind = kindi.to_b
# After this point, all stream reading errors are caught later
if kind == kind_char then
var bf = char_buf
var b = stream.read_byte
- if b == null then return '�'
- var ln = b.u8len
- bf[0] = b
+ if b < 0 then return '�'
+ var ln = b.to_b.u8len
+ bf[0] = b.to_b
for i in [1 .. ln[ do
b = stream.read_byte
- if b == null then return '�'
- bf[i] = b
+ if b < 0 then return '�'
+ bf[i] = b.to_b
end
return bf.to_s_unsafe(ln, copy=false)[0]
end
# Check for the attributes end marker
loop
- var next_byte = stream.read_byte
+ var next_byte = stream.read_byte.to_b
if next_byte == new_object_end then break
# Fetch an additional attribute, even if it isn't expected
# Reads a character. Returns `null` on EOF or timeout
fun read_char: nullable Char is abstract
- # Reads a byte. Returns `null` on EOF or timeout
- fun read_byte: nullable Byte is abstract
+ # Reads a byte. Returns a negative value on error
+ fun read_byte: Int is abstract
# Reads a String of at most `i` length
fun read(i: Int): String do return read_bytes(i).to_s
# Read at most i bytes
+ #
+ # If i <= 0, an empty buffer will be returned
fun read_bytes(i: Int): Bytes
do
- if last_error != null then return new Bytes.empty
+ if last_error != null or i <= 0 then return new Bytes.empty
var s = new CString(i)
- var buf = new Bytes(s, 0, 0)
+ var buf = new Bytes(s, 0, i)
while i > 0 and not eof do
var c = read_byte
- if c != null then
- buf.add c
- i -= 1
+ if c < 0 then
+ continue
end
+ buf.add c.to_b
+ i -= 1
end
return buf
end
var s = new Bytes.empty
while not eof do
var c = read_byte
- if c != null then s.add(c)
+ if c < 0 then continue
+ s.add(c.to_b)
end
return s
end
redef fun read_byte
do
- if last_error != null then return null
+ if last_error != null then return -1
if eof then
last_error = new IOError("Stream has reached eof")
- return null
+ return -1
end
var c = _buffer[_buffer_pos]
_buffer_pos += 1
- return c
+ return c.to_i
end
# Resets the internal buffer
# ~~~
# var reader = new BytesReader(b"a…b")
# assert reader.read_char == 'a'
-# assert reader.read_byte == 0xE2u8 # 1st byte of '…'
-# assert reader.read_byte == 0x80u8 # 2nd byte of '…'
+# assert reader.read_byte == 0xE2 # 1st byte of '…'
+# assert reader.read_byte == 0x80 # 2nd byte of '…'
# assert reader.read_char == '�' # Reads the last byte as an invalid char
# assert reader.read_all_bytes == b"b"
# ~~~
redef fun read_byte
do
- if cursor >= bytes.length then return null
+ if cursor >= bytes.length then return -1
var c = bytes[cursor]
cursor += 1
- return c
+ return c.to_i
end
redef fun close do bytes = new Bytes.empty
# ~~~
# var reader = new StringReader("a…b")
# assert reader.read_char == 'a'
-# assert reader.read_byte == 0xE2u8 # 1st byte of '…'
-# assert reader.read_byte == 0x80u8 # 2nd byte of '…'
+# assert reader.read_byte == 0xE2 # 1st byte of '…'
+# assert reader.read_byte == 0x80 # 2nd byte of '…'
# assert reader.read_char == '�' # Reads the last byte as an invalid char
# assert reader.read_all == "b"
# ~~~
if last_error != null then return 0
var typ = read_byte
- if typ == null then
+ if typ < 0 then
# Error, return default `null`
return null
- else if typ & 0b1000_0000u8 == 0u8 or typ & 0b1110_0000u8 == 0b1110_0000u8 then
+ else if typ & 0b1000_0000 == 0 or typ & 0b1110_0000 == 0b1110_0000 then
# fixint
var bytes = new Bytes.with_capacity(1)
- bytes.add typ
+ bytes.add typ.to_b
return bytes.to_i(signed=true)
- else if typ & 0b1111_0000u8 == 0b1000_0000u8 then
+ else if typ & 0b1111_0000 == 0b1000_0000 then
# fixmap
- var len = typ & 0b0000_1111u8
+ var len = typ & 0b0000_1111
return read_msgpack_map_data(len.to_i)
- else if typ & 0b1111_0000u8 == 0b1001_0000u8 then
+ else if typ & 0b1111_0000 == 0b1001_0000 then
# fixarray
- var len = typ & 0b0000_1111u8
+ var len = typ & 0b0000_1111
return read_msgpack_array_data(len.to_i)
- else if typ & 0b1110_0000u8 == 0b1010_0000u8 then
+ else if typ & 0b1110_0000 == 0b1010_0000 then
# fixstr
- var len = typ & 0b0001_1111u8
+ var len = typ & 0b0001_1111
return read_bytes(len.to_i).to_s
- else if typ == 0xC0u8 then
+ else if typ == 0xC0 then
return null
- else if typ == 0xC2u8 then
+ else if typ == 0xC2 then
return false
- else if typ == 0xC3u8 then
+ else if typ == 0xC3 then
return true
- else if typ == 0xCCu8 then
+ else if typ == 0xCC then
# uint8
- return (read_byte or else 0u8).to_i
- else if typ == 0xCDu8 then
+ var val = read_byte
+ if val < 0 then return 0
+ return val
+ else if typ == 0xCD then
# uint16
return read_bytes(2).to_i
- else if typ == 0xCEu8 then
+ else if typ == 0xCE then
# uint32
return read_bytes(4).to_i
- else if typ == 0xCFu8 then
+ else if typ == 0xCF then
# uint64
return read_bytes(8).to_i
- else if typ == 0xD0u8 then
+ else if typ == 0xD0 then
# int8
return read_bytes(1).to_i(true)
- else if typ == 0xD1u8 then
+ else if typ == 0xD1 then
# int16
return read_bytes(2).to_i(true)
- else if typ == 0xD2u8 then
+ else if typ == 0xD2 then
# int32
return read_bytes(4).to_i(true)
- else if typ == 0xD3u8 then
+ else if typ == 0xD3 then
# int64
return read_int64
- else if typ == 0xCAu8 then
+ else if typ == 0xCA then
return read_float
- else if typ == 0xCBu8 then
+ else if typ == 0xCB then
return read_double
- else if typ == 0xD9u8 then
+ else if typ == 0xD9 then
# str8
var len = read_byte
- if len == null then return null
+ if len < 0 then return null
return read_bytes(len.to_i).to_s
- else if typ == 0xDAu8 then
+ else if typ == 0xDA then
# str16
var len = read_bytes(2)
return read_bytes(len.to_i).to_s
- else if typ == 0xDBu8 then
+ else if typ == 0xDB then
# str32
var len = read_bytes(4)
return read_bytes(len.to_i).to_s
- else if typ == 0xC4u8 then
+ else if typ == 0xC4 then
# bin8
var len = read_byte
- if len == null then return null
+ if len < 0 then return null
return read_bytes(len.to_i)
- else if typ == 0xC5u8 then
+ else if typ == 0xC5 then
# bin16
var len = read_bytes(2)
return read_bytes(len.to_i)
- else if typ == 0xC6u8 then
+ else if typ == 0xC6 then
# bin32
var len = read_bytes(4)
return read_bytes(len.to_i)
- else if typ == 0xDCu8 then
+ else if typ == 0xDC then
# array16
var len = read_bytes(2)
return read_msgpack_array_data(len.to_i)
- else if typ == 0xDDu8 then
+ else if typ == 0xDD then
# array32
var len = read_bytes(4)
return read_msgpack_array_data(len.to_i)
- else if typ == 0xDEu8 then
+ else if typ == 0xDE then
# map16
var len = read_bytes(2)
return read_msgpack_map_data(len.to_i)
- else if typ == 0xDFu8 then
+ else if typ == 0xDF then
# map32
var len = read_bytes(4)
return read_msgpack_map_data(len.to_i)
- else if typ == 0xD4u8 then
+ else if typ == 0xD4 then
# fixext1
return read_msgpack_fixext_data(1)
- else if typ == 0xD5u8 then
+ else if typ == 0xD5 then
# fixext2
return read_msgpack_fixext_data(2)
- else if typ == 0xD6u8 then
+ else if typ == 0xD6 then
# fixext4
return read_msgpack_fixext_data(4)
- else if typ == 0xD7u8 then
+ else if typ == 0xD7 then
# fixext8
return read_msgpack_fixext_data(8)
- else if typ == 0xD8u8 then
+ else if typ == 0xD8 then
# fixext16
return read_msgpack_fixext_data(16)
- else if typ == 0xC7u8 then
+ else if typ == 0xC7 then
# ext1
return read_msgpack_ext_data(1)
- else if typ == 0xC8u8 then
+ else if typ == 0xC8 then
# ext2
return read_msgpack_ext_data(2)
- else if typ == 0xC9u8 then
+ else if typ == 0xC9 then
# ext4
return read_msgpack_ext_data(4)
end
- print_error "MessagePack Warning: Found no match for typ {typ} / 0b{typ.to_i.to_base(2)}"
+ print_error "MessagePack Warning: Found no match for typ {typ} / 0b{typ.to_base(2)}"
return null
end
# ~~~
private fun read_msgpack_fixext_data(len: Int): MsgPackExt
do
- var exttyp = read_byte or else 0u8
+ var exttyp = read_byte
+ if exttyp < 0 then exttyp = 0
var data = read_bytes(len)
- return new MsgPackExt(exttyp, data)
+ return new MsgPackExt(exttyp.to_b, data)
end
# Read the content of a dynamic *ext* including the length on `len_len` bytes
end
var s = input.read_byte
- if s == null then
+ if s < 0 then
last_char = -1
return
end
if was_cr and last_char == '\n'.code_point then
# EOL already reported. => Skip this byte.
s = input.read_byte
- if s == null then
+ if s < 0 then
last_char = -1
else
- last_char = s.to_i
+ last_char = s
end
end
was_cr = last_char == '\r'.code_point
while not fin do
var fst_byte = client.read_byte
var snd_byte = client.read_byte
- if fst_byte == null or snd_byte == null then
+ if fst_byte < 0 or snd_byte < 0 then
last_error = new IOError("Error: bad frame")
client.close
return
# %x9 denotes a ping
# %xA denotes a pong
# %xB-F are reserved for further control frames
- var fin_flag = fst_byte & 0b1000_0000u8
+ var fin_flag = fst_byte & 0b1000_0000
if fin_flag != 0 then fin = true
- var opcode = fst_byte & 0b0000_1111u8
+ var opcode = fst_byte & 0b0000_1111
if opcode == 9 then
bf.add(138u8)
bf.add(0u8)
# |(mask - 1bit)|(payload length - 7 bits)
# As specified, if the payload length is 126 or 127
# The next 16 or 64 bits contain an extended payload length
- var mask_flag = snd_byte & 0b1000_0000u8
- var len = (snd_byte & 0b0111_1111u8).to_i
+ var mask_flag = snd_byte & 0b1000_0000
+ var len = snd_byte & 0b0111_1111
var payload_ext_len = 0
if len == 126 then
var tmp = client.read_bytes(2)
no error
hello
-0x4d
+77
1.235
1.235
123456789
no error
hello
-0x4d
+77
144545136640.0
0.0
1571011930645069824
no error
hello
-0x4d
+77
144545136640.0
0.0
1571011930645069824
no error
hello
-0x4d
+77
1.235
1.235
123456789
#alt2# reader.big_endian = false
#alt3# reader.big_endian = false
print reader.read(5)
-print reader.read_byte or else "null"
+var b = reader.read_byte
+if b >= 0 then
+ print b
+else
+ print "null"
+end
print reader.read_float
print reader.read_double
print reader.read_int64