@@ -54,6 +54,38 @@ public class JSTypedArray<Element>: JSBridgedClass, ExpressibleByArrayLiteral wh
5454 public convenience init < S: Sequence > ( _ sequence: S ) where S. Element == Element {
5555 self . init ( Array ( sequence) )
5656 }
57+
58+ /// Length (in bytes) of the typed array.
59+ /// The value is established when a TypedArray is constructed and cannot be changed.
60+ /// If the TypedArray is not specifying a `byteOffset` or a `length`, the `length` of the referenced `ArrayBuffer` will be returned.
61+ public var lengthInBytes : Int {
62+ Int ( jsObject [ " byteLength " ] . number!)
63+ }
64+
65+ /// Calls the given closure with a pointer to a copy of the underlying bytes of the
66+ /// array's storage.
67+ ///
68+ /// - Note: The pointer passed as an argument to `body` is valid only for the
69+ /// lifetime of the closure. Do not escape it from the closure for later
70+ /// use.
71+ ///
72+ /// - Parameter body: A closure with an `UnsafeBufferPointer` parameter
73+ /// that points to the contiguous storage for the array.
74+ /// If `body` has a return value, that value is also
75+ /// used as the return value for the `withUnsafeBytes(_:)` method. The
76+ /// argument is valid only for the duration of the closure's execution.
77+ /// - Returns: The return value, if any, of the `body` closure parameter.
78+ public func withUnsafeBytes< R> ( _ body: ( UnsafeBufferPointer < Element > ) throws -> R ) rethrows -> R {
79+ let bytesLength = lengthInBytes
80+ let rawBuffer = malloc ( bytesLength) !
81+ defer { free ( rawBuffer) }
82+ _load_typed_array ( jsObject. id, rawBuffer. assumingMemoryBound ( to: UInt8 . self) )
83+ let length = lengthInBytes / MemoryLayout< Element> . size
84+ let boundPtr = rawBuffer. bindMemory ( to: Element . self, capacity: length)
85+ let bufferPtr = UnsafeBufferPointer < Element > ( start: boundPtr, count: length)
86+ let result = try body ( bufferPtr)
87+ return result
88+ }
5789}
5890
5991// MARK: - Int and UInt support
0 commit comments