nitlanguage
/
nit.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge: Migration from ascii to code_point
[nit.git]
/
lib
/
binary
/
binary.nit
diff --git
a/lib/binary/binary.nit
b/lib/binary/binary.nit
index
28ddf32
..
c15cb52
100644
(file)
--- a/
lib/binary/binary.nit
+++ b/
lib/binary/binary.nit
@@
-12,13
+12,13
@@
# See the License for the specific language governing permissions and
# limitations under the License.
# See the License for the specific language governing permissions and
# limitations under the License.
-# Add reading and writing binary services
+# Read and write binary data with any `Reader` and `Writer`
#
# ~~~
# var w = new FileWriter.open("/tmp/data.bin")
# w.write "hello"
# w.write_int64 123456789
#
# ~~~
# var w = new FileWriter.open("/tmp/data.bin")
# w.write "hello"
# w.write_int64 123456789
-# w.write_byte 3
+# w.write_byte 3u8
# w.write_float 1.25
# w.write_double 1.234567
# w.write_bits(true, false, true)
# w.write_float 1.25
# w.write_double 1.234567
# w.write_bits(true, false, true)
@@
-28,7
+28,7
@@
# var r = new FileReader.open("/tmp/data.bin")
# assert r.read(5) == "hello"
# assert r.read_int64 == 123456789
# var r = new FileReader.open("/tmp/data.bin")
# assert r.read(5) == "hello"
# assert r.read_int64 == 123456789
-# assert r.read_byte == 3
+# assert r.read_byte == 3u8
# assert r.read_float == 1.25
# assert r.read_double == 1.234567
#
# assert r.read_float == 1.25
# assert r.read_double == 1.234567
#
@@
-45,10
+45,13
@@
in "C" `{
#include <endian.h>
// Android compatibility
#include <endian.h>
// Android compatibility
+ #ifndef be32toh
+ #define be32toh(val) betoh32(val)
+ #define le32toh(val) letoh32(val)
+ #endif
+
#ifndef be64toh
#define be64toh(val) betoh64(val)
#ifndef be64toh
#define be64toh(val) betoh64(val)
- #endif
- #ifndef le64toh
#define le64toh(val) letoh64(val)
#endif
`}
#define le64toh(val) letoh64(val)
#endif
`}
@@
-67,7
+70,7
@@
redef abstract class Writer
super BinaryStream
# Write a boolean `value` on a byte, using 0 for `false` and 1 for `true`
super BinaryStream
# Write a boolean `value` on a byte, using 0 for `false` and 1 for `true`
- fun write_bool(value: Bool) do write_byte if value then 1 else 0
+ fun write_bool(value: Bool) do write_byte if value then 1u8 else 0u8
# Write up to 8 `Bool` in a byte
#
# Write up to 8 `Bool` in a byte
#
@@
-78,9
+81,9
@@
redef abstract class Writer
do
assert bits.length <= 8
do
assert bits.length <= 8
- var int = 0
+ var int = 0u8
for b in bits.length.times do
for b in bits.length.times do
- if bits[b] then int += 2**b
+ if bits[b] then int |= 1u8 << (7 - b)
end
write_byte int
end
write_byte int
@@
-94,7
+97,7
@@
redef abstract class Writer
fun write_string(text: Text)
do
write text
fun write_string(text: Text)
do
write text
- write_byte 0x00
+ write_byte 0x00u8
end
# Write the length as a 64 bits integer, then the content of `text`
end
# Write the length as a 64 bits integer, then the content of `text`
@@
-104,7
+107,7
@@
redef abstract class Writer
# Compared to `write_string`, this method supports null bytes in `text`.
fun write_block(text: Text)
do
# Compared to `write_string`, this method supports null bytes in `text`.
fun write_block(text: Text)
do
- write_int64 text.length
+ write_int64 text.bytelen
write text
end
write text
end
@@
-148,45
+151,61
@@
redef abstract class Reader
super BinaryStream
# Read a single byte and return `true` if its value is different than 0
super BinaryStream
# Read a single byte and return `true` if its value is different than 0
- fun read_bool: Bool do return read_byte != 0
+ #
+ # Returns `false` when an error is pending (`last_error != null`).
+ fun read_bool: Bool do return read_byte != 0u8
# Get an `Array` of 8 `Bool` by reading a single byte
#
# To be used with `BinaryWriter::write_bits`.
# Get an `Array` of 8 `Bool` by reading a single byte
#
# To be used with `BinaryWriter::write_bits`.
+ #
+ # Returns an array of `false` when an error is pending (`last_error != null`).
fun read_bits: Array[Bool]
do
var int = read_byte
if int == null then return new Array[Bool]
fun read_bits: Array[Bool]
do
var int = read_byte
if int == null then return new Array[Bool]
- return [for b in 8.times do int.bin_and(2**b) > 0]
+ var arr = new Array[Bool]
+ for i in [7 .. 0].step(-1) do
+ arr.push(((int >> i) & 1u8) != 0u8)
+ end
+ return arr
end
# Read a null terminated string
#
# To be used with `Writer::write_string`.
end
# Read a null terminated string
#
# To be used with `Writer::write_string`.
+ #
+ # Returns a truncated string when an error is pending (`last_error != null`).
fun read_string: String
do
fun read_string: String
do
- var buf = new FlatBuffer
+ var buf = new Bytes.empty
loop
var byte = read_byte
loop
var byte = read_byte
- if byte == 0x00 then return buf.to_s
- buf.chars.add byte.ascii
+ if byte == null or byte == 0u8 then
+ return buf.to_s
+ end
+ buf.add byte
end
end
# Read the length as a 64 bits integer, then the content of the block
#
# To be used with `Writer::write_block`.
end
end
# Read the length as a 64 bits integer, then the content of the block
#
# To be used with `Writer::write_block`.
+ #
+ # Returns a truncated string when an error is pending (`last_error != null`).
fun read_block: String
do
var length = read_int64
if length == 0 then return ""
fun read_block: String
do
var length = read_int64
if length == 0 then return ""
- return read(length)
+ return read_bytes(length).to_s
end
# Read a floating point on 32 bits and return it as a `Float`
#
# Using this format may result in a loss of precision as it uses less bits
# than Nit `Float`.
end
# Read a floating point on 32 bits and return it as a `Float`
#
# Using this format may result in a loss of precision as it uses less bits
# than Nit `Float`.
+ #
+ # Returns `0.0` when an error is pending (`last_error != null`).
fun read_float: Float
do
if last_error != null then return 0.0
fun read_float: Float
do
if last_error != null then return 0.0
@@
-203,7
+222,7
@@
redef abstract class Reader
end
# Utility for `read_float`
end
# Utility for `read_float`
- private fun native_read_float(b0, b1, b2, b3: Int, big_endian: Bool): Float `{
+ private fun native_read_float(b0, b1, b2, b3: Byte, big_endian: Bool): Float `{
union {
unsigned char b[4];
float val;
union {
unsigned char b[4];
float val;
@@
-223,6
+242,8
@@
redef abstract class Reader
`}
# Read a floating point on 64 bits and return it as a `Float`
`}
# Read a floating point on 64 bits and return it as a `Float`
+ #
+ # Returns `0.0` when an error is pending (`last_error != null`).
fun read_double: Float
do
if last_error != null then return 0.0
fun read_double: Float
do
if last_error != null then return 0.0
@@
-244,7
+265,7
@@
redef abstract class Reader
end
# Utility for `read_double`
end
# Utility for `read_double`
- private fun native_read_double(b0, b1, b2, b3, b4, b5, b6, b7: Int, big_endian: Bool): Float `{
+ private fun native_read_double(b0, b1, b2, b3, b4, b5, b6, b7: Byte, big_endian: Bool): Float `{
union {
unsigned char b[8];
double val;
union {
unsigned char b[8];
double val;
@@
-271,6
+292,8
@@
redef abstract class Reader
#
# Using this format may result in a loss of precision as the length of a
# Nit `Int` may be less than 64 bits on some platforms.
#
# Using this format may result in a loss of precision as the length of a
# Nit `Int` may be less than 64 bits on some platforms.
+ #
+ # Returns `0` when an error is pending (`last_error != null`).
fun read_int64: Int
do
if last_error != null then return 0
fun read_int64: Int
do
if last_error != null then return 0
@@
-292,7
+315,7
@@
redef abstract class Reader
end
# Utility for `read_int64`
end
# Utility for `read_int64`
- private fun native_read_int64(b0, b1, b2, b3, b4, b5, b6, b7: Int, big_endian: Bool): Int `{
+ private fun native_read_int64(b0, b1, b2, b3, b4, b5, b6, b7: Byte, big_endian: Bool): Int `{
union {
unsigned char b[8];
int64_t val;
union {
unsigned char b[8];
int64_t val;
@@
-318,14
+341,14
@@
end
redef class Int
# Utility for `BinaryWriter`
redef class Int
# Utility for `BinaryWriter`
- private fun int64_byte_at(index: Int, big_endian: Bool): Int `{
+ private fun int64_byte_at(index: Int, big_endian: Bool): Byte `{
union {
unsigned char bytes[8];
int64_t val;
uint64_t conv;
} u;
union {
unsigned char bytes[8];
int64_t val;
uint64_t conv;
} u;
- u.val = recv;
+ u.val = self;
if (big_endian)
u.conv = htobe64(u.conv);
if (big_endian)
u.conv = htobe64(u.conv);
@@
-337,14
+360,14
@@
end
redef class Float
# Utility for `BinaryWriter`
redef class Float
# Utility for `BinaryWriter`
- private fun float_byte_at(index: Int, big_endian: Bool): Int `{
+ private fun float_byte_at(index: Int, big_endian: Bool): Byte `{
union {
unsigned char bytes[4];
float val;
uint32_t conv;
} u;
union {
unsigned char bytes[4];
float val;
uint32_t conv;
} u;
- u.val = recv;
+ u.val = self;
if (big_endian)
u.conv = htobe32(u.conv);
if (big_endian)
u.conv = htobe32(u.conv);
@@
-354,14
+377,14
@@
redef class Float
`}
# Utility for `BinaryWriter`
`}
# Utility for `BinaryWriter`
- private fun double_byte_at(index: Int, big_endian: Bool): Int `{
+ private fun double_byte_at(index: Int, big_endian: Bool): Byte `{
union {
unsigned char bytes[8];
double val;
uint64_t conv;
} u;
union {
unsigned char bytes[8];
double val;
uint64_t conv;
} u;
- u.val = recv;
+ u.val = self;
if (big_endian)
u.conv = htobe64(u.conv);
if (big_endian)
u.conv = htobe64(u.conv);