From 7a2ab85f1c86e7256c5b45672b2fe8f157e35c9a Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 30 May 2021 11:48:28 -0400 Subject: lux/data/binary.slice now works in the offset+length style. --- stdlib/source/lux/control/parser/binary.lux | 7 ++- stdlib/source/lux/data/binary.lux | 59 ++++++++++------------ stdlib/source/lux/data/format/tar.lux | 2 +- .../source/program/aedifex/repository/remote.lux | 2 +- stdlib/source/test/lux/data/binary.lux | 27 +++++----- stdlib/source/test/lux/world/file.lux | 4 +- 6 files changed, 48 insertions(+), 53 deletions(-) diff --git a/stdlib/source/lux/control/parser/binary.lux b/stdlib/source/lux/control/parser/binary.lux index 423cff74f..7221f5c65 100644 --- a/stdlib/source/lux/control/parser/binary.lux +++ b/stdlib/source/lux/control/parser/binary.lux @@ -147,10 +147,9 @@ (function (_ [offset binary]) (case size 0 (#try.Success [[offset binary] (/.create 0)]) - _ (do try.monad - [#let [end (n.+ size offset)] - output (/.slice offset (.dec end) binary)] - (wrap [[end binary] output]))))) + _ (|> binary + (/.slice offset size) + (\ try.monad map (|>> [[(n.+ size offset) binary]])))))) (template [ ] [(def: #export diff --git a/stdlib/source/lux/data/binary.lux b/stdlib/source/lux/data/binary.lux index ce8deb1d2..c706ec4cb 100644 --- a/stdlib/source/lux/data/binary.lux +++ b/stdlib/source/lux/data/binary.lux @@ -26,16 +26,11 @@ ["Size" (%.nat size)] ["Index" (%.nat index)])) -(template [] - [(exception: #export ( {size Nat} {from Nat} {to Nat}) - (exception.report - ["Size" (%.nat size)] - ["From" (%.nat from)] - ["To" (%.nat to)]))] - - [slice_out_of_bounds] - [inverted_slice] - ) +(exception: #export (slice_out_of_bounds {size Nat} {offset Nat} {length Nat}) + (exception.report + ["Size" (%.nat size)] + ["Offset" (%.nat offset)] + ["Length" (%.nat length)])) (with_expansions [ (as_is (type: #export Binary (ffi.type [byte])) @@ -328,32 +323,30 @@ (#try.Success target))) (exception.throw ..cannot_copy_bytes [bytes source_input target_output])))))) -(def: #export (slice from to binary) +(def: #export (slice offset length binary) (-> Nat Nat Binary (Try Binary)) - (let [size (..!size binary)] - (if (n.<= to from) - (if (and (n.< size from) - (n.< size to)) - (with_expansions [ (as_is (#try.Success (java/util/Arrays::copyOfRange binary (.int from) (.int (inc to)))))] - (for {@.old - @.jvm } - - ## Default - (let [how_many (inc (n.- from to))] - (..copy how_many from binary 0 (..create how_many))))) - (exception.throw ..slice_out_of_bounds [size from to])) - (exception.throw ..inverted_slice [size from to])))) - -(def: #export (drop from binary) + (let [size (..!size binary) + limit (n.+ length offset)] + (if (n.<= size limit) + (with_expansions [ (as_is (#try.Success (java/util/Arrays::copyOfRange binary (.int offset) (.int limit))))] + (for {@.old + @.jvm } + + ## Default + (..copy length offset binary 0 (..create length)))) + (exception.throw ..slice_out_of_bounds [size offset length])))) + +(def: #export (drop offset binary) (-> Nat Binary Binary) - (case from + (case offset 0 binary - _ (case (..slice from (dec (..!size binary)) binary) - (#try.Success slice) - slice - - (#try.Failure _) - (..create 0)))) + _ (let [distance (n.- offset (..!size binary))] + (case (..slice offset distance binary) + (#try.Success slice) + slice + + (#try.Failure _) + (..create 0))))) (structure: #export monoid (Monoid Binary) diff --git a/stdlib/source/lux/data/format/tar.lux b/stdlib/source/lux/data/format/tar.lux index 598b52be6..f796b7a6c 100644 --- a/stdlib/source/lux/data/format/tar.lux +++ b/stdlib/source/lux/data/format/tar.lux @@ -235,7 +235,7 @@ (recur (dec end)) _ - (binary.slice 0 end string)))))))) + (binary.slice 0 (dec end) string)))))))) (template [ ] [(abstract: #export diff --git a/stdlib/source/program/aedifex/repository/remote.lux b/stdlib/source/program/aedifex/repository/remote.lux index fd0d65d6f..eb285bb67 100644 --- a/stdlib/source/program/aedifex/repository/remote.lux +++ b/stdlib/source/program/aedifex/repository/remote.lux @@ -111,7 +111,7 @@ _ (if (n.= ..buffer_size bytes_read) (recur (\ binary.monoid compose output buffer)) (do ! - [chunk (\ io.monad wrap (binary.slice 0 (dec (.nat bytes_read)) buffer))] + [chunk (\ io.monad wrap (binary.slice 0 (.nat bytes_read) buffer))] (recur (\ binary.monoid compose output chunk)))))))] (wrap output))) diff --git a/stdlib/source/test/lux/data/binary.lux b/stdlib/source/test/lux/data/binary.lux index 89237babc..11d4a8889 100644 --- a/stdlib/source/test/lux/data/binary.lux +++ b/stdlib/source/test/lux/data/binary.lux @@ -84,8 +84,8 @@ sample (..random size) value random.nat #let [gen_idx (|> random.nat (\ ! map (n.% size)))] - [from to] (random.and gen_idx gen_idx) - #let [[from to] [(n.min from to) (n.max from to)]]] + offset gen_idx + length (\ ! map (n.% (n.- offset size)) random.nat)] (_.for [/.Binary] ($_ _.and (_.for [/.equivalence] @@ -113,12 +113,15 @@ (_.cover [/.read/64 /.write/64] (..binary_io 3 /.read/64 /.write/64 value)))) (_.cover [/.slice] - (let [slice_size (|> to (n.- from) inc) - random_slice (try.assume (/.slice from to sample)) - idxs (enum.range n.enum 0 (dec slice_size)) - reader (function (_ binary idx) (/.read/8 idx binary))] - (and (n.= slice_size (/.size random_slice)) - (case [(monad.map try.monad (|>> (n.+ from) (reader sample)) idxs) + (let [random_slice (try.assume (/.slice offset length sample)) + idxs (: (List Nat) + (case length + 0 (list) + _ (enum.range n.enum 0 (dec length)))) + reader (function (_ binary idx) + (/.read/8 idx binary))] + (and (n.= length (/.size random_slice)) + (case [(monad.map try.monad (|>> (n.+ offset) (reader sample)) idxs) (monad.map try.monad (reader random_slice) idxs)] [(#try.Success binary_vals) (#try.Success slice_vals)] (\ (list.equivalence n.equivalence) = binary_vals slice_vals) @@ -127,10 +130,10 @@ #0)))) (_.cover [/.slice_out_of_bounds] (and (throws? /.slice_out_of_bounds (/.slice size size sample)) - (throws? /.slice_out_of_bounds (/.slice from size sample)))) - (_.cover [/.inverted_slice] - (or (throws? /.inverted_slice (/.slice to from sample)) - (n.= to from))) + (let [verdict (throws? /.slice_out_of_bounds (/.slice offset size sample))] + (case offset + 0 (not verdict) + _ verdict)))) (_.cover [/.drop] (and (\ /.equivalence = sample (/.drop 0 sample)) (\ /.equivalence = (/.create 0) (/.drop size sample)) diff --git a/stdlib/source/test/lux/world/file.lux b/stdlib/source/test/lux/world/file.lux index 002d76c42..c7f546a1b 100644 --- a/stdlib/source/test/lux/world/file.lux +++ b/stdlib/source/test/lux/world/file.lux @@ -110,10 +110,10 @@ ## (wrap (and (n.= (n.* 2 file_size) read_size) ## (\ binary.equivalence = ## dataL - ## (try.assume (binary.slice 0 (dec file_size) content))) + ## (try.assume (binary.slice 0 file_size content))) ## (\ binary.equivalence = ## dataR - ## (try.assume (binary.slice file_size (dec read_size) content)))))))] + ## (try.assume (binary.slice file_size (n.- file_size read_size) content)))))))] ## (_.assert "Can append to files." ## (try.default #0 result)))) ## (wrap (do promise.monad -- cgit v1.2.3