Module docstring
{}
{}
ByteArray
structure
ByteArray.emptyWithCapacity
definition
(c : @& Nat) : ByteArray
@[extern "lean_mk_empty_byte_array"]
def emptyWithCapacity (c : @& Nat) : ByteArray :=
{ data := #[] }
ByteArray.mkEmpty
abbrev
@[deprecated emptyWithCapacity (since := "2025-03-12")]
abbrev mkEmpty := emptyWithCapacity
ByteArray.empty
definition
: ByteArray
def empty : ByteArray := emptyWithCapacity 0
ByteArray.instInhabited
instance
: Inhabited ByteArray
ByteArray.instEmptyCollection
instance
: EmptyCollection ByteArray
instance : EmptyCollection ByteArray where
emptyCollection := ByteArray.empty
ByteArray.push
definition
: ByteArray → UInt8 → ByteArray
ByteArray.size
definition
: (@& ByteArray) → Nat
ByteArray.usize
definition
(a : @& ByteArray) : USize
ByteArray.uget
definition
: (a : @& ByteArray) → (i : USize) → (h : i.toNat < a.size := by get_elem_tactic) → UInt8
@[extern "lean_byte_array_uget"]
def uget : (a : @& ByteArray) → (i : USize) → (h : i.toNat < a.size := by get_elem_tactic) → UInt8
| ⟨bs⟩, i, h => bs[i]
ByteArray.get!
definition
: (@& ByteArray) → (@& Nat) → UInt8
ByteArray.get
definition
: (a : @& ByteArray) → (i : @& Nat) → (h : i < a.size := by get_elem_tactic) → UInt8
@[extern "lean_byte_array_fget"]
def get : (a : @& ByteArray) → (i : @& Nat) → (h : i < a.size := by get_elem_tactic) → UInt8
| ⟨bs⟩, i, _ => bs[i]
ByteArray.instGetElemNatUInt8LtSize
instance
: GetElem ByteArray Nat UInt8 fun xs i => i < xs.size
ByteArray.instGetElemUSizeUInt8LtNatValToFinSize
instance
: GetElem ByteArray USize UInt8 fun xs i => i.toFin < xs.size
ByteArray.set!
definition
: ByteArray → (@& Nat) → UInt8 → ByteArray
ByteArray.set
definition
: (a : ByteArray) → (i : @& Nat) → UInt8 → (h : i < a.size := by get_elem_tactic) → ByteArray
@[extern "lean_byte_array_fset"]
def set : (a : ByteArray) → (i : @& Nat) → UInt8 → (h : i < a.size := by get_elem_tactic) → ByteArray
| ⟨bs⟩, i, b, h => ⟨bs.set i b h⟩
ByteArray.uset
definition
: (a : ByteArray) → (i : USize) → UInt8 → (h : i.toNat < a.size := by get_elem_tactic) → ByteArray
@[extern "lean_byte_array_uset"]
def uset : (a : ByteArray) → (i : USize) → UInt8 → (h : i.toNat < a.size := by get_elem_tactic) → ByteArray
| ⟨bs⟩, i, v, h => ⟨bs.uset i v h⟩
ByteArray.hash
opaque
(a : @& ByteArray) : UInt64
ByteArray.instHashable
instance
: Hashable ByteArray
instance : Hashable ByteArray where
hash := ByteArray.hash
ByteArray.isEmpty
definition
(s : ByteArray) : Bool
ByteArray.extract
definition
(a : ByteArray) (b e : Nat) : ByteArray
ByteArray.append
definition
(a : ByteArray) (b : ByteArray) : ByteArray
ByteArray.instAppend
instance
: Append ByteArray
instance : Append ByteArray := ⟨ByteArray.append⟩
ByteArray.toList
definition
(bs : ByteArray) : List UInt8
ByteArray.forIn
definition
{β : Type v} {m : Type v → Type w} [Monad m] (as : ByteArray) (b : β) (f : UInt8 → β → m (ForInStep β)) : m β
/-- Reference implementation for `forIn` -/
@[implemented_by ByteArray.forInUnsafe]
protected def forIn {β : Type v} {m : Type v → Type w} [Monad m] (as : ByteArray) (b : β) (f : UInt8 → β → m (ForInStep β)) : m β :=
let rec loop (i : Nat) (h : i ≤ as.size) (b : β) : m β := do
match i, h with
| 0, _ => pure b
| i+1, h =>
have h' : i < as.size := Nat.lt_of_lt_of_le (Nat.lt_succ_self i) h
have : as.size - 1 < as.size := Nat.sub_lt (Nat.zero_lt_of_lt h') (by decide)
have : as.size - 1 - i < as.size := Nat.lt_of_le_of_lt (Nat.sub_le (as.size - 1) i) this
match (← f as[as.size - 1 - i] b) with
| ForInStep.done b => pure b
| ForInStep.yield b => loop i (Nat.le_of_lt h') b
loop as.size (Nat.le_refl _) b
ByteArray.instForInUInt8
instance
: ForIn m ByteArray UInt8
instance : ForIn m ByteArray UInt8 where
forIn := ByteArray.forIn
ByteArray.Iterator
structure
/-- Iterator over the bytes (`UInt8`) of a `ByteArray`.
Typically created by `arr.iter`, where `arr` is a `ByteArray`.
An iterator is *valid* if the position `i` is *valid* for the array `arr`, meaning `0 ≤ i ≤ arr.size`
Most operations on iterators return arbitrary values if the iterator is not valid. The functions in
the `ByteArray.Iterator` API should rule out the creation of invalid iterators, with two exceptions:
- `Iterator.next iter` is invalid if `iter` is already at the end of the array (`iter.atEnd` is
`true`)
- `Iterator.forward iter n`/`Iterator.nextn iter n` is invalid if `n` is strictly greater than the
number of remaining bytes.
-/
structure Iterator where
/-- The array the iterator is for. -/
array : ByteArray
/-- The current position.
This position is not necessarily valid for the array, for instance if one keeps calling
`Iterator.next` when `Iterator.atEnd` is true. If the position is not valid, then the
current byte is `(default : UInt8)`. -/
idx : Nat
deriving Inhabited
ByteArray.instInhabitedIterator
instance
: Inhabited✝ (@ByteArray.Iterator)
Inhabited
ByteArray.mkIterator
definition
(arr : ByteArray) : Iterator
/-- Creates an iterator at the beginning of an array. -/
def mkIterator (arr : ByteArray) : Iterator :=
⟨arr, 0⟩
ByteArray.iter
abbrev
@[inherit_doc mkIterator]
abbrev iter := mkIterator
ByteArray.instSizeOfIterator
instance
: SizeOf Iterator
ByteArray.Iterator.sizeOf_eq
theorem
(i : Iterator) : sizeOf i = i.array.size - i.idx
ByteArray.Iterator.remainingBytes
definition
: Iterator → Nat
/-- Number of bytes remaining in the iterator. -/
def remainingBytes : Iterator → Nat
| ⟨arr, i⟩ => arr.size - i
ByteArray.Iterator.pos
definition
@[inherit_doc Iterator.idx]
def pos := Iterator.idx
ByteArray.Iterator.curr
definition
: Iterator → UInt8
ByteArray.Iterator.next
definition
: Iterator → Iterator
/-- Moves the iterator's position forward by one byte, unconditionally.
It is only valid to call this function if the iterator is not at the end of the array, *i.e.*
`Iterator.atEnd` is `false`; otherwise, the resulting iterator will be invalid. -/
@[inline]
def next : Iterator → Iterator
| ⟨arr, i⟩ => ⟨arr, i + 1⟩
ByteArray.Iterator.prev
definition
: Iterator → Iterator
ByteArray.Iterator.atEnd
definition
: Iterator → Bool
ByteArray.Iterator.hasNext
definition
: Iterator → Bool
ByteArray.Iterator.curr'
definition
(it : Iterator) (h : it.hasNext) : UInt8
ByteArray.Iterator.next'
definition
(it : Iterator) (_h : it.hasNext) : Iterator
/-- Moves the iterator's position forward by one byte. --/
@[inline]
def next' (it : Iterator) (_h : it.hasNext) : Iterator :=
match it with
| ⟨arr, i⟩ => ⟨arr, i + 1⟩
ByteArray.Iterator.hasPrev
definition
: Iterator → Bool
ByteArray.Iterator.toEnd
definition
: Iterator → Iterator
ByteArray.Iterator.forward
definition
: Iterator → Nat → Iterator
ByteArray.Iterator.nextn
definition
: Iterator → Nat → Iterator
ByteArray.Iterator.prevn
definition
: Iterator → Nat → Iterator
List.toByteArray
definition
(bs : List UInt8) : ByteArray
/--
Converts a list of bytes into a `ByteArray`.
-/
def List.toByteArray (bs : List UInt8) : ByteArray :=
let rec loop
| [], r => r
| b::bs, r => loop bs (r.push b)
loop bs ByteArray.empty
instToStringByteArray
instance
: ToString ByteArray
instance : ToString ByteArray := ⟨fun bs => bs.toList.toString⟩
ByteArray.toUInt64LE!
definition
(bs : ByteArray) : UInt64
/-- Interpret a `ByteArray` of size 8 as a little-endian `UInt64`. -/
def ByteArray.toUInt64LE! (bs : ByteArray) : UInt64 :=
assert! bs.size == 8
(bs.get! 7).toUInt64 <<< 0x38 |||
(bs.get! 6).toUInt64 <<< 0x30 |||
(bs.get! 5).toUInt64 <<< 0x28 |||
(bs.get! 4).toUInt64 <<< 0x20 |||
(bs.get! 3).toUInt64 <<< 0x18 |||
(bs.get! 2).toUInt64 <<< 0x10 |||
(bs.get! 1).toUInt64 <<< 0x8 |||
(bs.get! 0).toUInt64
ByteArray.toUInt64BE!
definition
(bs : ByteArray) : UInt64
/-- Interpret a `ByteArray` of size 8 as a big-endian `UInt64`. -/
def ByteArray.toUInt64BE! (bs : ByteArray) : UInt64 :=
assert! bs.size == 8
(bs.get! 0).toUInt64 <<< 0x38 |||
(bs.get! 1).toUInt64 <<< 0x30 |||
(bs.get! 2).toUInt64 <<< 0x28 |||
(bs.get! 3).toUInt64 <<< 0x20 |||
(bs.get! 4).toUInt64 <<< 0x18 |||
(bs.get! 5).toUInt64 <<< 0x10 |||
(bs.get! 6).toUInt64 <<< 0x8 |||
(bs.get! 7).toUInt64