From fc522a0ba56764b76b866e29d3cbeeb3ea7f0060 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Mon, 26 Jan 2026 11:12:30 +0100 Subject: [PATCH 1/3] fuxups for usig with `serde` --- mops.toml | 13 +++++++------ src/lib.mo | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/mops.toml b/mops.toml index 59ecfed..1601311 100644 --- a/mops.toml +++ b/mops.toml @@ -3,20 +3,21 @@ name = "byte-utils" version = "0.1.2" license = "MIT" description = "A collection of utilities for byte manipulation and conversion." -keywords = ["encoding", "decoding", "conversion", "uleb128", "sleb128"] +keywords = [ "encoding", "decoding", "conversion", "uleb128", "sleb128" ] repository = "https://github.com/NatLabs/ByteUtils" [dependencies] -'base@0.14.13' = "0.14.13" -'xtended-numbers@2.0.0' = "2.0.0" +"base@0.14.13" = "0.14.13" +"xtended-numbers@2.3.0" = "2.3.0" +buffer = "0.1.0" [dev-dependencies] -test = "2.1.1" -bench = "1.0.0" +test = "2.1.2" +bench = "2.0.0" fuzz = "1.0.0" augmented-btrees = "0.7.1" itertools = "0.2.2" [toolchain] -moc = "0.14.13" +moc = "1.1.0" wasmtime = "33.0.1" diff --git a/src/lib.mo b/src/lib.mo index 0506fe4..02632df 100644 --- a/src/lib.mo +++ b/src/lib.mo @@ -16,7 +16,7 @@ import Nat "mo:base@0.14.13/Nat"; import Debug "mo:base@0.14.13/Debug"; import BInterface "mo:buffer"; -import FloatX "mo:xtended-numbers@2.0.0/FloatX"; +import FloatX "mo:xtended-numbers@2.3.0/FloatX"; module ByteUtils { /// An iterator of bytes. From b38de4dc38d53d42d8e44c85ca20bc51a83ea523 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Wed, 11 Mar 2026 13:25:35 +0100 Subject: [PATCH 2/3] Remove base dependency: migrate to mo:core - Replace all mo:base@0.14.13/* imports with mo:core/* equivalents - Add ListBuffer class backed by mo:core/List as Buffer replacement - Replace B.Buffer(cap) with ListBuffer(), B.toArray with .toArray() - Replace BInterface.fromDeprecatedBuffer(b) with { write = b.add } - Replace Debug.trap with Runtime.trap (mo:core/Debug has no trap) - Replace Iter.range (inclusive) with Nat.range (exclusive upper bound) - Fix Int64.maximumValue -> Int64.maxValue for mo:core API - Update mops.toml: remove base/buffer deps, add core, bump moc to 1.3.0 Co-Authored-By: Claude Sonnet 4.6 --- mops.toml | 5 +- src/lib.mo | 145 +++++++++++++++++++++++++++++------------------------ 2 files changed, 81 insertions(+), 69 deletions(-) diff --git a/mops.toml b/mops.toml index 1601311..99e1c1e 100644 --- a/mops.toml +++ b/mops.toml @@ -7,9 +7,8 @@ keywords = [ "encoding", "decoding", "conversion", "uleb128", "sleb128" ] repository = "https://github.com/NatLabs/ByteUtils" [dependencies] -"base@0.14.13" = "0.14.13" +core = "https://github.com/caffeinelabs/motoko-core#refs/pull/468/head" "xtended-numbers@2.3.0" = "2.3.0" -buffer = "0.1.0" [dev-dependencies] test = "2.1.2" @@ -19,5 +18,5 @@ augmented-btrees = "0.7.1" itertools = "0.2.2" [toolchain] -moc = "1.1.0" +moc = "1.3.0" wasmtime = "33.0.1" diff --git a/src/lib.mo b/src/lib.mo index 02632df..f56546d 100644 --- a/src/lib.mo +++ b/src/lib.mo @@ -1,20 +1,19 @@ import Prim "mo:prim"; -import B "mo:base@0.14.13/Buffer"; -import Iter "mo:base@0.14.13/Iter"; -import Array "mo:base@0.14.13/Array"; -import Nat8 "mo:base@0.14.13/Nat8"; -import Nat16 "mo:base@0.14.13/Nat16"; -import Nat32 "mo:base@0.14.13/Nat32"; -import Nat64 "mo:base@0.14.13/Nat64"; -import Int8 "mo:base@0.14.13/Int8"; -import Int16 "mo:base@0.14.13/Int16"; -import Int32 "mo:base@0.14.13/Int32"; -import Int64 "mo:base@0.14.13/Int64"; -import Int "mo:base@0.14.13/Int"; -import Nat "mo:base@0.14.13/Nat"; -import Debug "mo:base@0.14.13/Debug"; -import BInterface "mo:buffer"; +import Iter "mo:core/Iter"; +import Array "mo:core/Array"; +import List "mo:core/List"; +import Nat8 "mo:core/Nat8"; +import Nat16 "mo:core/Nat16"; +import Nat32 "mo:core/Nat32"; +import Nat64 "mo:core/Nat64"; +import Int8 "mo:core/Int8"; +import Int16 "mo:core/Int16"; +import Int32 "mo:core/Int32"; +import Int64 "mo:core/Int64"; +import Int "mo:core/Int"; +import Nat "mo:core/Nat"; +import Runtime "mo:core/Runtime"; import FloatX "mo:xtended-numbers@2.3.0/FloatX"; @@ -25,7 +24,7 @@ module ByteUtils { func to_nat8(bytes : Bytes) : Nat8 { switch (bytes.next()) { case (?byte) { byte }; - case (_) { Debug.trap("ByteUtils: out of bounds") }; + case (_) { Runtime.trap("ByteUtils: out of bounds") }; }; }; @@ -36,6 +35,20 @@ module ByteUtils { size : () -> Nat; }; + class ListBuffer() { + let list = List.empty(); + public func size() : Nat = List.size(list); + public func add(elem : A) = List.add(list, elem); + public func get(i : Nat) : A { + switch (List.get(list, i)) { + case (?elem) elem; + case (null) Runtime.trap("ByteUtils: ListBuffer index out of bounds"); + }; + }; + public func put(i : Nat, elem : A) = List.put(list, i, elem); + public func toArray() : [A] = List.toArray(list); + }; + public type Functions = module { toNat8 : (Bytes) -> Nat8; toNat16 : (Bytes) -> Nat16; @@ -114,7 +127,7 @@ module ByteUtils { }; public func toFloat(bytes : Bytes) : Float { - let ?fx = FloatX.fromBytes(bytes, #f64, #lsb) else Debug.trap("ByteUtils: failed to decode Float"); + let ?fx = FloatX.fromBytes(bytes, #f64, #lsb) else Runtime.trap("ByteUtils: failed to decode Float"); FloatX.toFloat(fx); }; @@ -158,10 +171,10 @@ module ByteUtils { public func fromFloat(f : Float) : [Nat8] { let fx = FloatX.fromFloat(f, #f64); - let buffer = B.Buffer(8); + let buffer = ListBuffer(); - FloatX.toBytesBuffer(BInterface.fromDeprecatedBuffer(buffer), fx, #lsb); - B.toArray(buffer); + FloatX.toBytesBuffer({ write = buffer.add }, fx, #lsb); + buffer.toArray(); }; }; @@ -219,7 +232,7 @@ module ByteUtils { }; public func toFloat(bytes : Bytes) : Float { - let ?fx = FloatX.fromBytes(bytes, #f64, #msb) else Debug.trap("ByteUtils: failed to decode Float"); + let ?fx = FloatX.fromBytes(bytes, #f64, #msb) else Runtime.trap("ByteUtils: failed to decode Float"); FloatX.toFloat(fx); }; @@ -263,10 +276,10 @@ module ByteUtils { public func fromFloat(f : Float) : [Nat8] { let fx = FloatX.fromFloat(f, #f64); - let buffer = B.Buffer(8); + let buffer = ListBuffer(); - FloatX.toBytesBuffer(BInterface.fromDeprecatedBuffer(buffer), fx, #msb); - B.toArray(buffer); + FloatX.toBytesBuffer({ write = buffer.add }, fx, #msb); + buffer.toArray(); }; }; @@ -327,23 +340,23 @@ module ByteUtils { public func fromFloat(f : Float) : [Nat8] { // IEEE-754 sortable encoding let fx = FloatX.fromFloat(f, #f64); - let buffer = B.Buffer(8); - FloatX.toBytesBuffer(BInterface.fromDeprecatedBuffer(buffer), fx, #msb); // Use big-endian + let buffer = ListBuffer(); + FloatX.toBytesBuffer({ write = buffer.add }, fx, #msb); // Use big-endian - let bytes = B.toArray(buffer); + let bytes = buffer.toArray(); if (f < 0.0) { // For negative numbers, flip all bits - Array.tabulate(buffer.size(), func(i : Nat) : Nat8 { ^(bytes.get(i)) }); + Array.tabulate(buffer.size(), func(i : Nat) : Nat8 { ^(bytes[i]) }); } else { // For positive numbers, flip only the sign bit Array.tabulate( buffer.size(), func(i : Nat) : Nat8 { if (i == 0) { - return bytes.get(i) ^ 0x80; // Flip sign bit only for first byte + return bytes[i] ^ 0x80; // Flip sign bit only for first byte } else { - return bytes.get(i); // Keep other bytes unchanged + return bytes[i]; // Keep other bytes unchanged }; }, ); @@ -447,7 +460,7 @@ module ByteUtils { ); }; - let ?fx = FloatX.fromBytes(decodedBytes.vals(), #f64, #msb) else Debug.trap("ByteUtils: failed to decode Float"); + let ?fx = FloatX.fromBytes(decodedBytes.vals(), #f64, #msb) else Runtime.trap("ByteUtils: failed to decode Float"); FloatX.toFloat(fx); }; }; @@ -457,60 +470,60 @@ module ByteUtils { /// Encodes a `Nat64` into ULEB128 format. public func toLEB128_64(n64 : Nat64) : [Nat8] { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); Buffer.addLEB128_64(buffer, n64); - B.toArray(buffer); + buffer.toArray(); }; /// Decodes a ULEB128-encoded `Nat64` from a byte iterator. /// Traps if end of buffer is reached before value is completely decoded. public func fromLEB128_64(bytes : Bytes) : Nat64 { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); for (byte in bytes) { buffer.add(byte) }; Buffer.readLEB128_64(buffer); }; /// Encodes a `Nat` into ULEB128 format. public func toLEB128(n : Nat) : [Nat8] { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); Buffer.addLEB128_nat(buffer, n); - B.toArray(buffer); + buffer.toArray(); }; /// Decodes a ULEB128-encoded `Nat` from a byte iterator. /// Traps if end of buffer is reached before value is completely decoded. public func fromLEB128(bytes : Bytes) : Nat { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); for (byte in bytes) { buffer.add(byte) }; Buffer.readLEB128_nat(buffer); }; /// Encodes an `Int64` into SLEB128 format. public func toSLEB128_64(n : Int64) : [Nat8] { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); Buffer.addSLEB128_64(buffer, n); - B.toArray(buffer); + buffer.toArray(); }; /// Decodes an SLEB128-encoded `Int64` from a byte iterator. /// Traps if end of buffer is reached before value is completely decoded. public func fromSLEB128_64(bytes : Bytes) : Int64 { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); for (byte in bytes) { buffer.add(byte) }; Buffer.readSLEB128_64(buffer); }; /// Encodes an `Int` into SLEB128 format. public func toSLEB128(n : Int) : [Nat8] { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); Buffer.addSLEB128_int(buffer, n); - B.toArray(buffer); + buffer.toArray(); }; /// Decodes an SLEB128-encoded `Int` from a byte iterator. /// Traps if end of buffer is reached before value is completely decoded. public func fromSLEB128(bytes : Bytes) : Int { - let buffer = B.Buffer(10); + let buffer = ListBuffer(); for (byte in bytes) { buffer.add(byte) }; Buffer.readSLEB128_int(buffer); }; @@ -572,9 +585,9 @@ module ByteUtils { addNat64(buffer, nat64); }; - public func addFloat(buffer : B.Buffer, f : Float) { + public func addFloat(buffer : BufferLike, f : Float) { let fx = FloatX.fromFloat(f, #f64); - FloatX.toBytesBuffer(BInterface.fromDeprecatedBuffer(buffer), fx, #lsb); + FloatX.toBytesBuffer({ write = buffer.add }, fx, #lsb); }; // Add new write methods (write at specific offset) @@ -629,11 +642,11 @@ module ByteUtils { public func writeFloat(buffer : BufferLike, offset : Nat, f : Float) { let fx = FloatX.fromFloat(f, #f64); - let tempBuffer = B.Buffer(8); - FloatX.toBytesBuffer(BInterface.fromDeprecatedBuffer(tempBuffer), fx, #lsb); + let tempBuffer = ListBuffer(); + FloatX.toBytesBuffer({ write = tempBuffer.add }, fx, #lsb); // Copy from temp buffer to target buffer at offset - for (i in Iter.range(0, 7)) { + for (i in Nat.range(0, 8)) { buffer.put(offset + i, tempBuffer.get(i)); }; }; @@ -742,9 +755,9 @@ module ByteUtils { addNat64(buffer, nat64); }; - public func addFloat(buffer : B.Buffer, f : Float) { + public func addFloat(buffer : BufferLike, f : Float) { let fx = FloatX.fromFloat(f, #f64); - FloatX.toBytesBuffer(BInterface.fromDeprecatedBuffer(buffer), fx, #msb); + FloatX.toBytesBuffer({ write = buffer.add }, fx, #msb); }; // Add new write methods (write at specific offset) @@ -797,13 +810,13 @@ module ByteUtils { writeNat64(buffer, offset, nat64); }; - public func writeFloat(buffer : B.Buffer, offset : Nat, f : Float) { + public func writeFloat(buffer : BufferLike, offset : Nat, f : Float) { let fx = FloatX.fromFloat(f, #f64); - let tempBuffer = B.Buffer(8); - FloatX.toBytesBuffer(BInterface.fromDeprecatedBuffer(tempBuffer), fx, #msb); + let tempBuffer = ListBuffer(); + FloatX.toBytesBuffer({ write = tempBuffer.add }, fx, #msb); // Copy from temp buffer to target buffer at offset - for (i in Iter.range(0, 7)) { + for (i in Nat.range(0, 8)) { buffer.put(offset + i, tempBuffer.get(i)); }; }; @@ -912,63 +925,63 @@ module ByteUtils { // Write functions (at specific offset) public func writeNat8(buffer : BufferLike, offset : Nat, n : Nat8) { let bytes = ByteUtils.Sorted.fromNat8(n); - for (i in Iter.range(0, bytes.size() - 1)) { + for (i in Nat.range(0, bytes.size())) { buffer.put(offset + i, bytes[i]); }; }; public func writeNat16(buffer : BufferLike, offset : Nat, n : Nat16) { let bytes = ByteUtils.Sorted.fromNat16(n); - for (i in Iter.range(0, bytes.size() - 1)) { + for (i in Nat.range(0, bytes.size())) { buffer.put(offset + i, bytes[i]); }; }; public func writeNat32(buffer : BufferLike, offset : Nat, n : Nat32) { let bytes = ByteUtils.Sorted.fromNat32(n); - for (i in Iter.range(0, bytes.size() - 1)) { + for (i in Nat.range(0, bytes.size())) { buffer.put(offset + i, bytes[i]); }; }; public func writeNat64(buffer : BufferLike, offset : Nat, n : Nat64) { let bytes = ByteUtils.Sorted.fromNat64(n); - for (i in Iter.range(0, bytes.size() - 1)) { + for (i in Nat.range(0, bytes.size())) { buffer.put(offset + i, bytes[i]); }; }; public func writeInt8(buffer : BufferLike, offset : Nat, i : Int8) { let bytes = ByteUtils.Sorted.fromInt8(i); - for (j in Iter.range(0, bytes.size() - 1)) { + for (j in Nat.range(0, bytes.size())) { buffer.put(offset + j, bytes[j]); }; }; public func writeInt16(buffer : BufferLike, offset : Nat, i : Int16) { let bytes = ByteUtils.Sorted.fromInt16(i); - for (j in Iter.range(0, bytes.size() - 1)) { + for (j in Nat.range(0, bytes.size())) { buffer.put(offset + j, bytes[j]); }; }; public func writeInt32(buffer : BufferLike, offset : Nat, i : Int32) { let bytes = ByteUtils.Sorted.fromInt32(i); - for (j in Iter.range(0, bytes.size() - 1)) { + for (j in Nat.range(0, bytes.size())) { buffer.put(offset + j, bytes[j]); }; }; public func writeInt64(buffer : BufferLike, offset : Nat, i : Int64) { let bytes = ByteUtils.Sorted.fromInt64(i); - for (j in Iter.range(0, bytes.size() - 1)) { + for (j in Nat.range(0, bytes.size())) { buffer.put(offset + j, bytes[j]); }; }; - public func writeFloat(buffer : B.Buffer, offset : Nat, f : Float) { + public func writeFloat(buffer : BufferLike, offset : Nat, f : Float) { let bytes = ByteUtils.Sorted.fromFloat(f); - for (i in Iter.range(0, bytes.size() - 1)) { + for (i in Nat.range(0, bytes.size())) { buffer.put(offset + i, bytes[i]); }; }; @@ -1111,7 +1124,7 @@ module ByteUtils { // Determine if we need more bytes if ( (value == 0 and (byte & 0x40) == 0) or - (is_negative and value == Nat64.fromNat(Int.abs(Int64.toInt(Int64.maximumValue))) and (byte & 0x40) != 0) + (is_negative and value == Nat64.fromNat(Int.abs(Int64.toInt(Int64.maxValue))) and (byte & 0x40) != 0) ) { more := false; } else { @@ -1154,7 +1167,7 @@ module ByteUtils { // Determine if we need more bytes if ( (value == 0 and (byte & 0x40) == 0) or - (is_negative and value == Nat64.fromNat(Int.abs(Int64.toInt(Int64.maximumValue))) and (byte & 0x40) != 0) + (is_negative and value == Nat64.fromNat(Int.abs(Int64.toInt(Int64.maxValue))) and (byte & 0x40) != 0) ) { more := false; } else { From d6f295682dec0e1409368d570ffbbe729eddce2d Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Wed, 11 Mar 2026 14:42:56 +0100 Subject: [PATCH 3/3] Pin core dependency to published version 2.1.0 Co-Authored-By: Claude Sonnet 4.6 --- mops.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mops.toml b/mops.toml index 99e1c1e..a403194 100644 --- a/mops.toml +++ b/mops.toml @@ -7,7 +7,7 @@ keywords = [ "encoding", "decoding", "conversion", "uleb128", "sleb128" ] repository = "https://github.com/NatLabs/ByteUtils" [dependencies] -core = "https://github.com/caffeinelabs/motoko-core#refs/pull/468/head" +core = "2.1.0" "xtended-numbers@2.3.0" = "2.3.0" [dev-dependencies]