From 8dbf7e8aa4e02a285a082cad9eb3e2f7c72cf811 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 23 Jun 2023 17:46:01 -0500 Subject: [PATCH 01/11] Internal -> Buffer; invert MonadBuffer module dependency - All `Internal` FFI has been moved into `Node.Buffer` and rewritten to use `FnX`/`EffectFnX` code - ST.purs was rewritten to reuse the `Node.Buffer` code, coercing the Effect to ST since they are the same - the `MonadBuffer` class was originally re-exported by ST/Buffer alike. This module dependency has been inverted. The main purpose behind this was to improve type inference for things like `Buffer.toString buf UTF8` --- bower.json | 3 +- src/Node/Buffer.js | 17 ++ src/Node/Buffer.purs | 153 +++++++++++++---- src/Node/Buffer/Class.purs | 54 ++++++ src/Node/Buffer/Immutable.js | 101 ++---------- src/Node/Buffer/Immutable.purs | 46 +++--- src/Node/Buffer/Internal.js | 68 -------- src/Node/Buffer/Internal.purs | 110 ------------- src/Node/Buffer/ST.purs | 130 +++++++++++---- src/Node/Encoding.js | 6 +- src/Node/Encoding.purs | 36 ++-- test/Test/Node/Buffer/Class.purs | 271 ++++++++++++++++--------------- test/Test/Node/Buffer/ST.purs | 3 +- 13 files changed, 499 insertions(+), 499 deletions(-) create mode 100644 src/Node/Buffer.js delete mode 100644 src/Node/Buffer/Internal.js delete mode 100644 src/Node/Buffer/Internal.purs diff --git a/bower.json b/bower.json index 0d182ef..840fb17 100644 --- a/bower.json +++ b/bower.json @@ -17,7 +17,8 @@ "purescript-effect": "^4.0.0", "purescript-maybe": "^6.0.0", "purescript-st": "^6.0.0", - "purescript-unsafe-coerce": "^6.0.0" + "purescript-unsafe-coerce": "^6.0.0", + "purescript-nullable": "^6.0.0" }, "devDependencies": { "purescript-assert": "^6.0.0", diff --git a/src/Node/Buffer.js b/src/Node/Buffer.js new file mode 100644 index 0000000..9a8ab3f --- /dev/null +++ b/src/Node/Buffer.js @@ -0,0 +1,17 @@ +/* global Buffer */ +export const freezeImpl= (a) => Buffer.from(a); + +export const thawImpl = (a) => Buffer.from(a); + +export const writeInternal = (ty, value, offset, buf) => + buf["write" + ty](value, offset); + +export const writeStringInternal = (encoding, offset, length, value, buff) => + buff.write(value, offset, length, encoding); + +export const setAtOffsetImpl = (value, offset, buff) => buff[offset] = value; + +export const copyImpl = (srcStart, srcEnd, src, targStart, targ) => + src.copy(targ, targStart, srcStart, srcEnd); + +export const fillImpl = (octet, start, end, buf) => buf.fill(octet, start, end); diff --git a/src/Node/Buffer.purs b/src/Node/Buffer.purs index 612afd3..35c3253 100644 --- a/src/Node/Buffer.purs +++ b/src/Node/Buffer.purs @@ -1,40 +1,137 @@ -- | Mutable buffers and associated operations. module Node.Buffer ( Buffer + , create + , freeze + , unsafeFreeze + , thaw + , unsafeThaw + , fromArray + , fromString + , fromArrayBuffer + , toArrayBuffer + , read + , readString + , toString + , write + , writeString + , toArray + , getAtOffset + , setAtOffset + , slice + , size + , concat + , concat' + , copy + , fill , module TypesExports - , module Class ) where +import Prelude + +import Data.ArrayBuffer.Types (ArrayBuffer) +import Data.Maybe (Maybe) import Effect (Effect) -import Node.Buffer.Class (class MutableBuffer) -import Node.Buffer.Class (class MutableBuffer, concat, concat', copy, create, fill, freeze, fromArray, fromArrayBuffer, fromString, getAtOffset, read, readString, setAtOffset, size, slice, thaw, toArray, toArrayBuffer, toString, unsafeFreeze, unsafeThaw, write, writeString) as Class -import Node.Buffer.Internal as Internal +import Effect.Uncurried (EffectFn1, EffectFn3, EffectFn4, EffectFn5, runEffectFn1, runEffectFn3, runEffectFn4, runEffectFn5) +import Node.Buffer.Immutable (ImmutableBuffer) +import Node.Buffer.Immutable as Immutable import Node.Buffer.Types (BufferValueType(..), Octet, Offset) as TypesExports +import Node.Buffer.Types (BufferValueType, Octet, Offset) +import Node.Encoding (Encoding, encodingToNode) +import Unsafe.Coerce (unsafeCoerce) -- | A reference to a mutable buffer for use with `Effect` foreign import data Buffer :: Type -instance mutableBufferEffect :: MutableBuffer Buffer Effect where - create = Internal.create - freeze = Internal.copyAll - unsafeFreeze = Internal.unsafeFreeze - thaw = Internal.copyAll - unsafeThaw = Internal.unsafeThaw - fromArray = Internal.fromArray - fromString = Internal.fromString - fromArrayBuffer = Internal.fromArrayBuffer - toArrayBuffer = Internal.toArrayBuffer - read = Internal.read - readString = Internal.readString - toString = Internal.toString - write = Internal.write - writeString = Internal.writeString - toArray = Internal.toArray - getAtOffset = Internal.getAtOffset - setAtOffset = Internal.setAtOffset - slice = Internal.slice - size = Internal.size - concat = Internal.concat - concat' = Internal.concat' - copy = Internal.copy - fill = Internal.fill +unsafeFreeze :: Buffer -> Effect ImmutableBuffer +unsafeFreeze = pure <<< unsafeCoerce + +unsafeThaw :: ImmutableBuffer -> Effect Buffer +unsafeThaw = pure <<< unsafeCoerce + +usingFromImmutable :: forall a. (ImmutableBuffer -> a) -> Buffer -> Effect a +usingFromImmutable f buf = f <$> unsafeFreeze buf + +usingToImmutable :: forall a. (a -> ImmutableBuffer) -> a -> Effect Buffer +usingToImmutable f x = unsafeThaw $ f x + +create :: Int -> Effect Buffer +create = usingToImmutable Immutable.create + +freeze :: Buffer -> Effect ImmutableBuffer +freeze = runEffectFn1 freezeImpl + +thaw :: ImmutableBuffer -> Effect Buffer +thaw = runEffectFn1 thawImpl + +foreign import thawImpl :: EffectFn1 ImmutableBuffer Buffer + +foreign import freezeImpl :: EffectFn1 Buffer ImmutableBuffer + +fromArray :: Array Octet -> Effect Buffer +fromArray = usingToImmutable Immutable.fromArray + +fromString :: String -> Encoding -> Effect Buffer +fromString s = usingToImmutable $ Immutable.fromString s + +fromArrayBuffer :: ArrayBuffer -> Effect Buffer +fromArrayBuffer = usingToImmutable Immutable.fromArrayBuffer + +toArrayBuffer :: Buffer -> Effect ArrayBuffer +toArrayBuffer = usingFromImmutable Immutable.toArrayBuffer + +read :: BufferValueType -> Offset -> Buffer -> Effect Number +read t o = usingFromImmutable $ Immutable.read t o + +readString :: Encoding -> Offset -> Offset -> Buffer -> Effect String +readString m o o' = usingFromImmutable $ Immutable.readString m o o' + +toString :: Encoding -> Buffer -> Effect String +toString m = usingFromImmutable $ Immutable.toString m + +write :: BufferValueType -> Number -> Offset -> Buffer -> Effect Unit +write ty num off buf = runEffectFn4 writeInternal (show ty) num off buf + +foreign import writeInternal :: EffectFn4 String Number Offset Buffer Unit + +writeString :: Encoding -> Offset -> Int -> String -> Buffer -> Effect Int +writeString enc off i s b = + runEffectFn5 writeStringInternal (encodingToNode enc) off i s b + +foreign import writeStringInternal + :: EffectFn5 String Offset Int String Buffer Int + +toArray :: Buffer -> Effect (Array Octet) +toArray = usingFromImmutable Immutable.toArray + +getAtOffset :: Offset -> Buffer -> Effect (Maybe Octet) +getAtOffset o = usingFromImmutable $ Immutable.getAtOffset o + +setAtOffset :: Octet -> Offset -> Buffer -> Effect Unit +setAtOffset s e b = runEffectFn3 setAtOffsetImpl s e b + +foreign import setAtOffsetImpl :: EffectFn3 Octet Offset Buffer Unit + +slice :: Offset -> Offset -> Buffer -> Buffer +slice = unsafeCoerce Immutable.slice + +size :: Buffer -> Effect Int +size = usingFromImmutable Immutable.size + +concat :: Array Buffer -> Effect Buffer +concat arrs = unsafeCoerce \_ -> Immutable.concat (unsafeCoerce arrs) + +concat' :: Array Buffer -> Int -> Effect Buffer +concat' arrs n = unsafeCoerce \_ -> Immutable.concat' (unsafeCoerce arrs) n + +copy :: Offset -> Offset -> Buffer -> Offset -> Buffer -> Effect Int +copy srcStart srcEnd src targStart targ = + runEffectFn5 copyImpl srcStart srcEnd src targStart targ + +foreign import copyImpl :: EffectFn5 Offset Offset Buffer Offset Buffer Int + +fill :: Octet -> Offset -> Offset -> Buffer -> Effect Unit +fill octet start end buf = + runEffectFn4 fillImpl octet start end buf + +foreign import fillImpl :: EffectFn4 Octet Offset Offset Buffer Unit diff --git a/src/Node/Buffer/Class.purs b/src/Node/Buffer/Class.purs index abdc931..4d6aa03 100644 --- a/src/Node/Buffer/Class.purs +++ b/src/Node/Buffer/Class.purs @@ -27,9 +27,13 @@ module Node.Buffer.Class import Prelude +import Control.Monad.ST (ST) import Data.ArrayBuffer.Types (ArrayBuffer) import Data.Maybe (Maybe) +import Effect (Effect) +import Node.Buffer as Buffer import Node.Buffer.Immutable (ImmutableBuffer) +import Node.Buffer.ST as ST import Node.Buffer.Types (BufferValueType, Octet, Offset) import Node.Encoding (Encoding) @@ -113,3 +117,53 @@ class Monad m <= MutableBuffer buf m | buf -> m where -- | Fills a range in a buffer with the specified octet. fill :: Octet -> Offset -> Offset -> buf -> m Unit + +instance mutableBufferEffect :: MutableBuffer Buffer.Buffer Effect where + create = Buffer.create + freeze = Buffer.freeze + unsafeFreeze = Buffer.unsafeFreeze + thaw = Buffer.thaw + unsafeThaw = Buffer.unsafeThaw + fromArray = Buffer.fromArray + fromString = Buffer.fromString + fromArrayBuffer = Buffer.fromArrayBuffer + toArrayBuffer = Buffer.toArrayBuffer + read = Buffer.read + readString = Buffer.readString + toString = Buffer.toString + write = Buffer.write + writeString = Buffer.writeString + toArray = Buffer.toArray + getAtOffset = Buffer.getAtOffset + setAtOffset = Buffer.setAtOffset + slice = Buffer.slice + size = Buffer.size + concat = Buffer.concat + concat' = Buffer.concat' + copy = Buffer.copy + fill = Buffer.fill + +instance mutableBufferST :: MutableBuffer (ST.STBuffer h) (ST h) where + create = ST.create + freeze = ST.freeze + unsafeFreeze = ST.unsafeFreeze + thaw = ST.thaw + unsafeThaw = ST.unsafeThaw + fromArray = ST.fromArray + fromString = ST.fromString + fromArrayBuffer = ST.fromArrayBuffer + toArrayBuffer = ST.toArrayBuffer + read = ST.read + readString = ST.readString + toString = ST.toString + write = ST.write + writeString = ST.writeString + toArray = ST.toArray + getAtOffset = ST.getAtOffset + setAtOffset = ST.setAtOffset + slice = ST.slice + size = ST.size + concat = ST.concat + concat' = ST.concat' + copy = ST.copy + fill = ST.fill diff --git a/src/Node/Buffer/Immutable.js b/src/Node/Buffer/Immutable.js index 48517b7..0d0f5eb 100644 --- a/src/Node/Buffer/Immutable.js +++ b/src/Node/Buffer/Immutable.js @@ -2,98 +2,29 @@ import { inspect } from "util"; export const showImpl = inspect; -export function eqImpl(a) { - return b => { - return a.equals(b); - }; -} - -export function compareImpl(a) { - return b => { - return a.compare(b); - }; -} +export const eqImpl = (a, b) => a.equals(b); +export const compareImpl = (a, b) => a.compare(b); +export const create = (size) => Buffer.alloc(size); -export function create(size) { - return Buffer.alloc(size); -} - -export function fromArray(octets) { - return Buffer.from(octets); -} +export const fromArray = (octets) => Buffer.from(octets); -export function size(buff) { - return buff.length; -} +export const size = (buff) => buff.length; -export function toArray(buff) { +export const toArray = (buff) => { var json = buff.toJSON(); return json.data || json; } -export function toArrayBuffer(buff) { +export const toArrayBuffer = (buff) => { return buff.buffer.slice(buff.byteOffset, buff.byteOffset + buff.byteLength); } -export function fromArrayBuffer(ab) { - return Buffer.from(ab); -} - -export function fromStringImpl(str) { - return encoding => { - return Buffer.from(str, encoding); - }; -} - -export function readImpl(ty) { - return offset => { - return buf => { - return buf["read" + ty](offset); - }; - }; -} - -export function readStringImpl(enc) { - return start => { - return end => { - return buff => { - return buff.toString(enc, start, end); - }; - }; - }; -} - -export function getAtOffsetImpl(just) { - return nothing => { - return offset => { - return buff => { - var octet = buff[offset]; - return octet == null ? nothing : just(octet); - }; - }; - }; -} - -export function toStringImpl(enc) { - return buff => { - return buff.toString(enc); - }; -} - -export function slice(start) { - return end => { - return buff => { - return buff.slice(start, end); - }; - }; -} - -export function concat(buffs) { - return Buffer.concat(buffs); -} - -export function concatToLength(buffs) { - return totalLength => { - return Buffer.concat(buffs, totalLength); - }; -} +export const fromArrayBuffer = (ab) => Buffer.from(ab); +export const fromStringImpl = (str, encoding) => Buffer.from(str, encoding); +export const readImpl = (ty, offset, buf) => buf["read" + ty](offset); +export const readStringImpl = (enc, start, end, buff) => buff.toString(enc, start, end); +export const getAtOffsetImpl = (offset, buff) => buff[offset]; +export const toStringImpl = (enc, buff) => buff.toString(enc); +export const sliceImpl = (start, end, buff) => buff.slice(start, end); +export const concat = (buffs) => Buffer.concat(buffs); +export const concatToLength = (buffs, totalLength) => Buffer.concat(buffs, totalLength); diff --git a/src/Node/Buffer/Immutable.purs b/src/Node/Buffer/Immutable.purs index a284ec3..6fd1832 100644 --- a/src/Node/Buffer/Immutable.purs +++ b/src/Node/Buffer/Immutable.purs @@ -20,8 +20,10 @@ module Node.Buffer.Immutable import Prelude import Data.ArrayBuffer.Types (ArrayBuffer) -import Data.Maybe (Maybe(..)) -import Node.Buffer.Types (BufferValueType, Octet, Offset) +import Data.Function.Uncurried (Fn2, Fn3, Fn4, runFn2, runFn3, runFn4) +import Data.Maybe (Maybe) +import Data.Nullable (Nullable, toMaybe) +import Node.Buffer.Types (BufferValueType, Offset, Octet) import Node.Encoding (Encoding, encodingToNode) -- | An immutable buffer that exists independently of any memory region or effect. @@ -33,18 +35,18 @@ instance showBuffer :: Show ImmutableBuffer where foreign import showImpl :: ImmutableBuffer -> String instance eqBuffer :: Eq ImmutableBuffer where - eq = eqImpl + eq a b = runFn2 eqImpl a b -foreign import eqImpl :: ImmutableBuffer -> ImmutableBuffer -> Boolean +foreign import eqImpl :: Fn2 ImmutableBuffer ImmutableBuffer Boolean instance ordBuffer :: Ord ImmutableBuffer where compare a b = - case compareImpl a b of + case runFn2 compareImpl a b of x | x < 0 -> LT x | x > 0 -> GT _ -> EQ -foreign import compareImpl :: ImmutableBuffer -> ImmutableBuffer -> Int +foreign import compareImpl :: Fn2 ImmutableBuffer ImmutableBuffer Int -- | Creates a new buffer of the specified size. foreign import create :: Int -> ImmutableBuffer @@ -59,28 +61,28 @@ foreign import fromArrayBuffer :: ArrayBuffer -> ImmutableBuffer -- | Creates a new buffer from a string with the specified encoding, sized to match the string. fromString :: String -> Encoding -> ImmutableBuffer -fromString str = fromStringImpl str <<< encodingToNode +fromString str enc = runFn2 fromStringImpl str $ encodingToNode enc -foreign import fromStringImpl :: String -> String -> ImmutableBuffer +foreign import fromStringImpl :: Fn2 String String ImmutableBuffer -- | Reads a numeric value from a buffer at the specified offset. read :: BufferValueType -> Offset -> ImmutableBuffer -> Number -read = readImpl <<< show +read ty offset buf = runFn3 readImpl (show ty) offset buf -foreign import readImpl :: String -> Offset -> ImmutableBuffer -> Number +foreign import readImpl :: Fn3 String Offset ImmutableBuffer Number -- | Reads a section of a buffer as a string with the specified encoding. readString :: Encoding -> Offset -> Offset -> ImmutableBuffer -> String -readString = readStringImpl <<< encodingToNode +readString enc start end buf = runFn4 readStringImpl (encodingToNode enc) start end buf -foreign import readStringImpl :: - String -> Offset -> Offset -> ImmutableBuffer -> String +foreign import readStringImpl + :: Fn4 String Offset Offset ImmutableBuffer String -- | Reads the buffer as a string with the specified encoding. toString :: Encoding -> ImmutableBuffer -> String -toString = toStringImpl <<< encodingToNode +toString enc buf = runFn2 toStringImpl (encodingToNode enc) buf -foreign import toStringImpl :: String -> ImmutableBuffer -> String +foreign import toStringImpl :: Fn2 String ImmutableBuffer String -- | Creates an array of octets from a buffer's contents. foreign import toArray :: ImmutableBuffer -> Array Octet @@ -90,10 +92,9 @@ foreign import toArrayBuffer :: ImmutableBuffer -> ArrayBuffer -- | Reads an octet from a buffer at the specified offset. getAtOffset :: Offset -> ImmutableBuffer -> Maybe Octet -getAtOffset = getAtOffsetImpl Just Nothing +getAtOffset offset buf = toMaybe $ runFn2 getAtOffsetImpl offset buf -foreign import getAtOffsetImpl :: - (Octet -> Maybe Octet) -> Maybe Octet -> Offset -> ImmutableBuffer -> Maybe Octet +foreign import getAtOffsetImpl :: Fn2 Offset ImmutableBuffer (Nullable Octet) -- | Concatenates a list of buffers. foreign import concat :: Array ImmutableBuffer -> ImmutableBuffer @@ -101,12 +102,15 @@ foreign import concat :: Array ImmutableBuffer -> ImmutableBuffer -- | Concatenates a list of buffers, combining them into a new buffer of the -- | specified length. concat' :: Array ImmutableBuffer -> Int -> ImmutableBuffer -concat' = concatToLength +concat' arr i = runFn2 concatToLength arr i -foreign import concatToLength :: Array ImmutableBuffer -> Int -> ImmutableBuffer +foreign import concatToLength :: Fn2 (Array ImmutableBuffer) Int ImmutableBuffer -- | Creates a new buffer slice that shares the memory of the original buffer. -foreign import slice :: Offset -> Offset -> ImmutableBuffer -> ImmutableBuffer +slice :: Offset -> Offset -> ImmutableBuffer -> ImmutableBuffer +slice start end buff = runFn3 sliceImpl start end buff + +foreign import sliceImpl :: Fn3 Offset Offset ImmutableBuffer ImmutableBuffer -- | Returns the size of a buffer. foreign import size :: ImmutableBuffer -> Int diff --git a/src/Node/Buffer/Internal.js b/src/Node/Buffer/Internal.js deleted file mode 100644 index 2af2886..0000000 --- a/src/Node/Buffer/Internal.js +++ /dev/null @@ -1,68 +0,0 @@ -/* global Buffer */ -export function copyAll(a) { - return () => { - return Buffer.from(a); - }; -} - -export function writeInternal(ty) { - return value => { - return offset => { - return buf => { - return () => { - buf["write" + ty](value, offset); - }; - }; - }; - }; -} - -export function writeStringInternal(encoding) { - return offset => { - return length => { - return value => { - return buff => { - return () => { - return buff.write(value, offset, length, encoding); - }; - }; - }; - }; - }; -} - -export function setAtOffset(value) { - return offset => { - return buff => { - return () => { - buff[offset] = value; - }; - }; - }; -} - -export function copy(srcStart) { - return srcEnd => { - return src => { - return targStart => { - return targ => { - return () => { - return src.copy(targ, targStart, srcStart, srcEnd); - }; - }; - }; - }; - }; -} - -export function fill(octet) { - return start => { - return end => { - return buf => { - return () => { - buf.fill(octet, start, end); - }; - }; - }; - }; -} diff --git a/src/Node/Buffer/Internal.purs b/src/Node/Buffer/Internal.purs deleted file mode 100644 index 427b6ac..0000000 --- a/src/Node/Buffer/Internal.purs +++ /dev/null @@ -1,110 +0,0 @@ --- | Functions and types to support the other modules. Not for public use. -module Node.Buffer.Internal - ( unsafeFreeze - , unsafeThaw - , usingFromImmutable - , usingToImmutable - , create - , copyAll - , fromArray - , fromString - , fromArrayBuffer - , toArrayBuffer - , read - , readString - , toString - , write - , writeString - , toArray - , getAtOffset - , setAtOffset - , slice - , size - , concat - , concat' - , copy - , fill - ) where - -import Prelude - -import Data.ArrayBuffer.Types (ArrayBuffer) -import Data.Maybe (Maybe) -import Node.Buffer.Immutable (ImmutableBuffer) -import Node.Buffer.Immutable as Immutable -import Node.Buffer.Types (BufferValueType, Octet, Offset) -import Node.Encoding (Encoding, encodingToNode) -import Unsafe.Coerce (unsafeCoerce) - -unsafeFreeze :: forall buf m. Monad m => buf -> m ImmutableBuffer -unsafeFreeze = pure <<< unsafeCoerce - -unsafeThaw :: forall buf m. Monad m => ImmutableBuffer -> m buf -unsafeThaw = pure <<< unsafeCoerce - -usingFromImmutable :: forall buf m a. Monad m => (ImmutableBuffer -> a) -> buf -> m a -usingFromImmutable f buf = f <$> unsafeFreeze buf - -usingToImmutable :: forall buf m a. Monad m => (a -> ImmutableBuffer) -> a -> m buf -usingToImmutable f x = unsafeThaw $ f x - -create :: forall buf m. Monad m => Int -> m buf -create = usingToImmutable Immutable.create - -foreign import copyAll :: forall a buf m. a -> m buf - -fromArray :: forall buf m. Monad m => Array Octet -> m buf -fromArray = usingToImmutable Immutable.fromArray - -fromString :: forall buf m. Monad m => String -> Encoding -> m buf -fromString s = usingToImmutable $ Immutable.fromString s - -fromArrayBuffer :: forall buf m. Monad m => ArrayBuffer -> m buf -fromArrayBuffer = usingToImmutable Immutable.fromArrayBuffer - -toArrayBuffer :: forall buf m. Monad m => buf -> m ArrayBuffer -toArrayBuffer = usingFromImmutable Immutable.toArrayBuffer - -read :: forall buf m. Monad m => BufferValueType -> Offset -> buf -> m Number -read t o = usingFromImmutable $ Immutable.read t o - -readString :: forall buf m. Monad m => Encoding -> Offset -> Offset -> buf -> m String -readString m o o' = usingFromImmutable $ Immutable.readString m o o' - -toString :: forall buf m. Monad m => Encoding -> buf -> m String -toString m = usingFromImmutable $ Immutable.toString m - -write :: forall buf m. Monad m => BufferValueType -> Number -> Offset -> buf -> m Unit -write = writeInternal <<< show - -foreign import writeInternal :: forall buf m. String -> Number -> Offset -> buf -> m Unit - -writeString :: forall buf m. Monad m => Encoding -> Offset -> Int -> String -> buf -> m Int -writeString = writeStringInternal <<< encodingToNode - -foreign import writeStringInternal :: - forall buf m. String -> Offset -> Int -> String -> buf -> m Int - -toArray :: forall buf m. Monad m => buf -> m (Array Octet) -toArray = usingFromImmutable Immutable.toArray - -getAtOffset :: forall buf m. Monad m => Offset -> buf -> m (Maybe Octet) -getAtOffset o = usingFromImmutable $ Immutable.getAtOffset o - -foreign import setAtOffset :: forall buf m. Octet -> Offset -> buf -> m Unit - -slice :: forall buf. Offset -> Offset -> buf -> buf -slice = unsafeCoerce Immutable.slice - -size :: forall buf m. Monad m => buf -> m Int -size = usingFromImmutable Immutable.size - -concat :: forall buf m. Array buf -> m buf -concat arrs = unsafeCoerce \_ -> Immutable.concat (unsafeCoerce arrs) - -concat' :: forall buf m. Monad m => Array buf -> Int -> m buf -concat' arrs n = unsafeCoerce \_ -> Immutable.concat' (unsafeCoerce arrs) n - -foreign import copy :: forall buf m. Offset -> Offset -> buf -> Offset -> buf -> m Int - -foreign import fill :: forall buf m. Octet -> Offset -> Offset -> buf -> m Unit diff --git a/src/Node/Buffer/ST.purs b/src/Node/Buffer/ST.purs index fc84fec..72bae62 100644 --- a/src/Node/Buffer/ST.purs +++ b/src/Node/Buffer/ST.purs @@ -1,47 +1,119 @@ module Node.Buffer.ST ( STBuffer , run + , create + , freeze + , unsafeFreeze + , thaw + , unsafeThaw + , fromArray + , fromString + , fromArrayBuffer + , toArrayBuffer + , read + , readString + , toString + , write + , writeString + , toArray + , getAtOffset + , setAtOffset + , slice + , size + , concat + , concat' + , copy + , fill ) where import Prelude import Control.Monad.ST (ST, Region) import Control.Monad.ST as ST -import Node.Buffer.Class (class MutableBuffer, unsafeFreeze) +import Data.ArrayBuffer.Types (ArrayBuffer) +import Data.Maybe (Maybe) +import Node.Buffer (BufferValueType, Octet, Offset) +import Node.Buffer as Buffer import Node.Buffer.Immutable (ImmutableBuffer) -import Node.Buffer.Internal as Internal +import Node.Encoding (Encoding) +import Unsafe.Coerce (unsafeCoerce) --- | A reference to a mutable buffer for use with `ST` +-- | A reference to a mutable Buffer for use with `ST` -- | --- | The type parameter represents the memory region which the buffer belongs to. +-- | The type parameter represents the memory region which the (STBuffer h) belongs to. foreign import data STBuffer :: Region -> Type --- | Runs an effect creating an `STBuffer` then freezes the buffer and returns +-- | Runs an ST creating an `STBuffer` then freezes the (STBuffer h) and returns -- | it, without unneccessary copying. run :: (forall h. ST h (STBuffer h)) -> ImmutableBuffer run st = ST.run (st >>= unsafeFreeze) -instance mutableBufferST :: MutableBuffer (STBuffer h) (ST h) where - create = Internal.create - freeze = Internal.copyAll - unsafeFreeze = Internal.unsafeFreeze - thaw = Internal.copyAll - unsafeThaw = Internal.unsafeThaw - fromArray = Internal.fromArray - fromString = Internal.fromString - fromArrayBuffer = Internal.fromArrayBuffer - toArrayBuffer = Internal.toArrayBuffer - read = Internal.read - readString = Internal.readString - toString = Internal.toString - write = Internal.write - writeString = Internal.writeString - toArray = Internal.toArray - getAtOffset = Internal.getAtOffset - setAtOffset = Internal.setAtOffset - slice = Internal.slice - size = Internal.size - concat = Internal.concat - concat' = Internal.concat' - copy = Internal.copy - fill = Internal.fill +unsafeFreeze :: forall h. STBuffer h -> ST h ImmutableBuffer +unsafeFreeze = unsafeCoerce Buffer.unsafeFreeze + +unsafeThaw :: forall h. ImmutableBuffer -> ST h (STBuffer h) +unsafeThaw = unsafeCoerce Buffer.unsafeThaw + +create :: forall h. Int -> ST h (STBuffer h) +create = unsafeCoerce Buffer.create + +freeze :: forall h. (STBuffer h) -> ST h ImmutableBuffer +freeze = unsafeCoerce Buffer.freeze + +thaw :: forall h. ImmutableBuffer -> ST h (STBuffer h) +thaw = unsafeCoerce Buffer.thaw + +fromArray :: forall h. Array Octet -> ST h (STBuffer h) +fromArray = unsafeCoerce Buffer.fromArray + +fromString :: forall h. String -> Encoding -> ST h (STBuffer h) +fromString = unsafeCoerce Buffer.fromString + +fromArrayBuffer :: forall h. ArrayBuffer -> ST h (STBuffer h) +fromArrayBuffer = unsafeCoerce Buffer.fromArrayBuffer + +toArrayBuffer :: forall h. (STBuffer h) -> ST h ArrayBuffer +toArrayBuffer = unsafeCoerce Buffer.toArrayBuffer + +read :: forall h. BufferValueType -> Offset -> (STBuffer h) -> ST h Number +read = unsafeCoerce Buffer.read + +readString :: forall h. Encoding -> Offset -> Offset -> (STBuffer h) -> ST h String +readString = unsafeCoerce Buffer.readString + +toString :: forall h. Encoding -> (STBuffer h) -> ST h String +toString = unsafeCoerce Buffer.toString + +write :: forall h. BufferValueType -> Number -> Offset -> (STBuffer h) -> ST h Unit +write = unsafeCoerce Buffer.write + +writeString :: forall h. Encoding -> Offset -> Int -> String -> (STBuffer h) -> ST h Int +writeString = + unsafeCoerce Buffer.writeString + +toArray :: forall h. (STBuffer h) -> ST h (Array Octet) +toArray = unsafeCoerce Buffer.toArray + +getAtOffset :: forall h. Offset -> (STBuffer h) -> ST h (Maybe Octet) +getAtOffset = unsafeCoerce Buffer.getAtOffset + +setAtOffset :: forall h. Octet -> Offset -> (STBuffer h) -> ST h Unit +setAtOffset = unsafeCoerce Buffer.setAtOffset + +slice :: forall h. Offset -> Offset -> (STBuffer h) -> (STBuffer h) +slice = unsafeCoerce Buffer.slice + +size :: forall h. (STBuffer h) -> ST h Int +size = unsafeCoerce Buffer.size + +concat :: forall h. Array (STBuffer h) -> ST h (STBuffer h) +concat = unsafeCoerce Buffer.concat + +concat' :: forall h. Array (STBuffer h) -> Int -> ST h (STBuffer h) +concat' = unsafeCoerce Buffer.concat' + +copy :: forall h. Offset -> Offset -> (STBuffer h) -> Offset -> (STBuffer h) -> ST h Int +copy = unsafeCoerce Buffer.copy + +fill :: forall h. Octet -> Offset -> Offset -> (STBuffer h) -> ST h Unit +fill = unsafeCoerce Buffer.fill diff --git a/src/Node/Encoding.js b/src/Node/Encoding.js index 608e31d..52f09c1 100644 --- a/src/Node/Encoding.js +++ b/src/Node/Encoding.js @@ -1,6 +1,2 @@ /* global Buffer */ -export function byteLengthImpl(str) { - return enc => { - return Buffer.byteLength(str, enc); - }; -} +export const byteLengthImpl = (str, enc) => Buffer.byteLength(str, enc); diff --git a/src/Node/Encoding.purs b/src/Node/Encoding.purs index b760603..42f4a35 100644 --- a/src/Node/Encoding.purs +++ b/src/Node/Encoding.purs @@ -1,11 +1,13 @@ module Node.Encoding - ( Encoding (..) + ( Encoding(..) , encodingToNode , byteLength ) where import Prelude +import Data.Function.Uncurried (Fn2, runFn2) + data Encoding = ASCII | UTF8 @@ -17,28 +19,28 @@ data Encoding | Hex instance showEncoding :: Show Encoding where - show ASCII = "ASCII" - show UTF8 = "UTF8" + show ASCII = "ASCII" + show UTF8 = "UTF8" show UTF16LE = "UTF16LE" - show UCS2 = "UCS2" - show Base64 = "Base64" - show Latin1 = "Latin1" - show Binary = "Binary" - show Hex = "Hex" + show UCS2 = "UCS2" + show Base64 = "Base64" + show Latin1 = "Latin1" + show Binary = "Binary" + show Hex = "Hex" -- | Convert an `Encoding` to a `String` in the format expected by Node.js -- | APIs. encodingToNode :: Encoding -> String -encodingToNode ASCII = "ascii" -encodingToNode UTF8 = "utf8" +encodingToNode ASCII = "ascii" +encodingToNode UTF8 = "utf8" encodingToNode UTF16LE = "utf16le" -encodingToNode UCS2 = "ucs2" -encodingToNode Base64 = "base64" -encodingToNode Latin1 = "latin1" -encodingToNode Binary = "binary" -encodingToNode Hex = "hex" +encodingToNode UCS2 = "ucs2" +encodingToNode Base64 = "base64" +encodingToNode Latin1 = "latin1" +encodingToNode Binary = "binary" +encodingToNode Hex = "hex" -foreign import byteLengthImpl :: String -> String -> Int +foreign import byteLengthImpl :: Fn2 (String) (String) (Int) byteLength :: String -> Encoding -> Int -byteLength str enc = byteLengthImpl str (encodingToNode enc) +byteLength str enc = runFn2 byteLengthImpl str (encodingToNode enc) diff --git a/test/Test/Node/Buffer/Class.purs b/test/Test/Node/Buffer/Class.purs index be8ca0d..f837951 100644 --- a/test/Test/Node/Buffer/Class.purs +++ b/test/Test/Node/Buffer/Class.purs @@ -7,14 +7,19 @@ import Data.Maybe (Maybe(..)) import Data.Traversable (traverse) import Effect (Effect) import Effect.Console (log) -import Node.Buffer (class MutableBuffer, BufferValueType(..), concat', copy, create, fill, freeze, fromArray, fromArrayBuffer, fromString, getAtOffset, read, readString, setAtOffset, slice, thaw, toArray, toArrayBuffer, toString, write) +import Node.Buffer.Class (class MutableBuffer, concat', copy, create, fill, freeze, fromArray, fromArrayBuffer, fromString, getAtOffset, read, readString, setAtOffset, slice, thaw, toArray, toArrayBuffer, toString, write) +import Node.Buffer (BufferValueType(..)) import Node.Buffer.Immutable as Immutable import Node.Encoding (Encoding(..)) import Test.Assert (assertEqual) import Type.Proxy (Proxy) -testMutableBuffer :: forall buf m. MutableBuffer buf m => - Proxy buf -> (forall a. m a -> Effect a) -> Effect Unit +testMutableBuffer + :: forall buf m + . MutableBuffer buf m + => Proxy buf + -> (forall a. m a -> Effect a) + -> Effect Unit testMutableBuffer _ run = do log " - create" @@ -63,136 +68,136 @@ testMutableBuffer _ run = do testGetAtOffset where - testCreate :: Effect Unit - testCreate = do - buf <- run ((create 3 :: m buf) >>= toArray) - assertEqual {expected: [0, 0, 0], actual: buf} - - testFreeze :: Effect Unit - testFreeze = do - buf <- Immutable.toArray <$> run ((fromArray [1, 2, 3] :: m buf) >>= freeze) - assertEqual {expected: [1, 2, 3], actual: buf} - - testThaw :: Effect Unit - testThaw = do - buf <- run ((thaw (Immutable.fromArray [1, 2, 3]) :: m buf) >>= toArray) - assertEqual {expected: [1, 2, 3], actual: buf} - - testReadWrite :: Effect Unit - testReadWrite = do - let val = 42.0 - readVal <- run do - buf <- create 1 :: m buf - write UInt8 val 0 buf - read UInt8 0 buf - - assertEqual {expected: val, actual: readVal} - - testFromArray :: Effect Unit - testFromArray = do - readVal <- run do - buf <- fromArray [1,2,3,4,5] :: m buf - read UInt8 2 buf - - assertEqual {expected: 3.0, actual: readVal} - - testToArray :: Effect Unit - testToArray = do - let val = [1,2,67,3,3,7,8,3,4,237] - valOut <- run do - buf <- fromArray val :: m buf - toArray buf - - assertEqual {expected: val, actual: valOut} - - testFromString :: Effect Unit - testFromString = do - let str = "hello, world" - val <- run do - buf <- fromString str ASCII :: m buf - read UInt8 6 buf - - assertEqual {expected: 32.0, actual: val} -- ASCII space - - testToFromArrayBuffer :: Effect Unit - testToFromArrayBuffer = do - buf <- run $ - fromArray [1, 2, 3] + testCreate :: Effect Unit + testCreate = do + buf <- run ((create 3 :: m buf) >>= toArray) + assertEqual { expected: [ 0, 0, 0 ], actual: buf } + + testFreeze :: Effect Unit + testFreeze = do + buf <- Immutable.toArray <$> run ((fromArray [ 1, 2, 3 ] :: m buf) >>= freeze) + assertEqual { expected: [ 1, 2, 3 ], actual: buf } + + testThaw :: Effect Unit + testThaw = do + buf <- run ((thaw (Immutable.fromArray [ 1, 2, 3 ]) :: m buf) >>= toArray) + assertEqual { expected: [ 1, 2, 3 ], actual: buf } + + testReadWrite :: Effect Unit + testReadWrite = do + let val = 42.0 + readVal <- run do + buf <- create 1 :: m buf + write UInt8 val 0 buf + read UInt8 0 buf + + assertEqual { expected: val, actual: readVal } + + testFromArray :: Effect Unit + testFromArray = do + readVal <- run do + buf <- fromArray [ 1, 2, 3, 4, 5 ] :: m buf + read UInt8 2 buf + + assertEqual { expected: 3.0, actual: readVal } + + testToArray :: Effect Unit + testToArray = do + let val = [ 1, 2, 67, 3, 3, 7, 8, 3, 4, 237 ] + valOut <- run do + buf <- fromArray val :: m buf + toArray buf + + assertEqual { expected: val, actual: valOut } + + testFromString :: Effect Unit + testFromString = do + let str = "hello, world" + val <- run do + buf <- fromString str ASCII :: m buf + read UInt8 6 buf + + assertEqual { expected: 32.0, actual: val } -- ASCII space + + testToFromArrayBuffer :: Effect Unit + testToFromArrayBuffer = do + buf <- run $ + fromArray [ 1, 2, 3 ] >>= (toArrayBuffer :: buf -> m ArrayBuffer) >>= (fromArrayBuffer :: ArrayBuffer -> m buf) >>= toArray - assertEqual {expected: [1, 2, 3], actual: buf} - - testToString :: Effect Unit - testToString = do - let str = "hello, world" - strOut <- run do - buf <- fromString str ASCII :: m buf - toString ASCII buf - - assertEqual {expected: str, actual: strOut} - - testReadString :: Effect Unit - testReadString = do - let str = "hello, world" - strOut <- run do - buf <- fromString str ASCII :: m buf - readString ASCII 7 12 buf - - assertEqual {expected: "world", actual: strOut} - - testSlice :: Effect Unit - testSlice = do - {bufArr, bufSliceArr} <- run do - buf <- fromArray [1, 2, 3, 4] :: m buf - let bufSlice = slice 1 3 buf - setAtOffset 42 1 bufSlice - bufArr <- toArray buf - bufSliceArr <- toArray bufSlice - pure {bufArr, bufSliceArr} - - assertEqual {expected: [1, 2, 42, 4], actual: bufArr} - assertEqual {expected: [2, 42], actual: bufSliceArr} - - testCopy :: Effect Unit - testCopy = do - {copied, out} <- run do - buf1 <- fromArray [1,2,3,4,5] :: m buf - buf2 <- fromArray [10,9,8,7,6] - copied <- copy 0 3 buf1 2 buf2 - out <- toArray buf2 - pure {copied, out} - - assertEqual {expected: 3, actual: copied} - assertEqual {expected: [10,9,1,2,3], actual: out} - - testFill :: Effect Unit - testFill = do - out <- run do - buf <- fromArray [1,1,1,1,1] :: m buf - fill 42 2 4 buf - toArray buf - - assertEqual {expected: [1,1,42,42,1], actual: out} - - testConcat' :: Effect Unit - testConcat' = do - out <- run do - bufs <- traverse (fromArray :: Array Int -> m buf) $ map (\x -> [x, x+1, x+2]) [0,3,6,9,12] - buf <- concat' bufs 15 - toArray buf - - assertEqual {expected: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14], actual: out} - - testGetAtOffset :: Effect Unit - testGetAtOffset = do - {o1, o4, om1} <- run do - buf <- fromArray [1, 2, 3, 4] :: m buf - o1 <- getAtOffset 1 buf - o4 <- getAtOffset 4 buf - om1 <- getAtOffset (-1) buf - pure {o1, o4, om1} - - assertEqual {expected: Just 2, actual: o1} - assertEqual {expected: Nothing, actual: o4} - assertEqual {expected: Nothing, actual: om1} + assertEqual { expected: [ 1, 2, 3 ], actual: buf } + + testToString :: Effect Unit + testToString = do + let str = "hello, world" + strOut <- run do + buf <- fromString str ASCII :: m buf + toString ASCII buf + + assertEqual { expected: str, actual: strOut } + + testReadString :: Effect Unit + testReadString = do + let str = "hello, world" + strOut <- run do + buf <- fromString str ASCII :: m buf + readString ASCII 7 12 buf + + assertEqual { expected: "world", actual: strOut } + + testSlice :: Effect Unit + testSlice = do + { bufArr, bufSliceArr } <- run do + buf <- fromArray [ 1, 2, 3, 4 ] :: m buf + let bufSlice = slice 1 3 buf + setAtOffset 42 1 bufSlice + bufArr <- toArray buf + bufSliceArr <- toArray bufSlice + pure { bufArr, bufSliceArr } + + assertEqual { expected: [ 1, 2, 42, 4 ], actual: bufArr } + assertEqual { expected: [ 2, 42 ], actual: bufSliceArr } + + testCopy :: Effect Unit + testCopy = do + { copied, out } <- run do + buf1 <- fromArray [ 1, 2, 3, 4, 5 ] :: m buf + buf2 <- fromArray [ 10, 9, 8, 7, 6 ] + copied <- copy 0 3 buf1 2 buf2 + out <- toArray buf2 + pure { copied, out } + + assertEqual { expected: 3, actual: copied } + assertEqual { expected: [ 10, 9, 1, 2, 3 ], actual: out } + + testFill :: Effect Unit + testFill = do + out <- run do + buf <- fromArray [ 1, 1, 1, 1, 1 ] :: m buf + fill 42 2 4 buf + toArray buf + + assertEqual { expected: [ 1, 1, 42, 42, 1 ], actual: out } + + testConcat' :: Effect Unit + testConcat' = do + out <- run do + bufs <- traverse (fromArray :: Array Int -> m buf) $ map (\x -> [ x, x + 1, x + 2 ]) [ 0, 3, 6, 9, 12 ] + buf <- concat' bufs 15 + toArray buf + + assertEqual { expected: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ], actual: out } + + testGetAtOffset :: Effect Unit + testGetAtOffset = do + { o1, o4, om1 } <- run do + buf <- fromArray [ 1, 2, 3, 4 ] :: m buf + o1 <- getAtOffset 1 buf + o4 <- getAtOffset 4 buf + om1 <- getAtOffset (-1) buf + pure { o1, o4, om1 } + + assertEqual { expected: Just 2, actual: o1 } + assertEqual { expected: Nothing, actual: o4 } + assertEqual { expected: Nothing, actual: om1 } diff --git a/test/Test/Node/Buffer/ST.purs b/test/Test/Node/Buffer/ST.purs index 783f835..4e369b6 100644 --- a/test/Test/Node/Buffer/ST.purs +++ b/test/Test/Node/Buffer/ST.purs @@ -2,7 +2,6 @@ module Test.Node.Buffer.ST (test) where import Prelude -import Control.Monad.ST (run) as ST import Effect (Effect) import Effect.Console (log) import Node.Buffer.Class (create) @@ -23,4 +22,4 @@ test = do testRun :: Effect Unit testRun = do let buf = Immutable.toArray $ run (create 3) - assertEqual {expected: [0, 0, 0], actual: buf} + assertEqual { expected: [ 0, 0, 0 ], actual: buf } From fab1be56fed65f6091917cc94d6632d6317ebed7 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 23 Jun 2023 18:00:13 -0500 Subject: [PATCH 02/11] Add missing semicolons --- src/Node/Buffer/Immutable.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Node/Buffer/Immutable.js b/src/Node/Buffer/Immutable.js index 0d0f5eb..879b2c1 100644 --- a/src/Node/Buffer/Immutable.js +++ b/src/Node/Buffer/Immutable.js @@ -13,11 +13,11 @@ export const size = (buff) => buff.length; export const toArray = (buff) => { var json = buff.toJSON(); return json.data || json; -} +}; export const toArrayBuffer = (buff) => { return buff.buffer.slice(buff.byteOffset, buff.byteOffset + buff.byteLength); -} +}; export const fromArrayBuffer = (ab) => Buffer.from(ab); export const fromStringImpl = (str, encoding) => Buffer.from(str, encoding); From f2378fad6442bd77f2ed4051b3494cf5656e60a4 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 23 Jun 2023 18:08:47 -0500 Subject: [PATCH 03/11] Add changelog --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8b5d0c..0c9949b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,29 @@ Notable changes to this project are documented in this file. The format is based ## [Unreleased] Breaking changes: +- Invert module dependency of `Node.Buffer.Class` (#51 by @JordanMartinez) + + The `MonadBuffer` type class was seemingly used to expose an API + for both `Buffer` and `STBuffer` without duplicating FFI. + Members of the class (e.g. `size`, `toString`, etc.) had type inference issues + due to this class-based approach. + + Now, both `Buffer` and `STBuffer` expose the same API but with their + type signatures hard-coded to `Effect` and `ST`, respectively, thereby + improving type inference. `MonadBuffer` instances for both types were + moved into the `Node/Buffer/Class.purs` file. + + One can migrate their code by either removing the usage of `MonadClass` in their code + if it was only used to get the needed API for a given type (e.g. `Buffer`) + or update their module imports from `Node.Buffer`/`Node.Buffer.ST` to `Node.Buffer.Class`. New features: Bugfixes: Other improvements: +- Update all FFI to use uncurried functions (#51 by @JordanMartinez) +- Removal of the `Internal.purs` file (#51 by @JordanMartinez) ## [v8.0.0](https://github.com/purescript-node/purescript-node-buffer/releases/tag/v8.0.0) - 2022-04-27 From 17b0db72b0ce1a58e5029ecb5360b347d9e139cc Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Fri, 23 Jun 2023 18:13:16 -0500 Subject: [PATCH 04/11] Fix more eslint issues --- src/Node/Buffer.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Node/Buffer.js b/src/Node/Buffer.js index 9a8ab3f..44afc3c 100644 --- a/src/Node/Buffer.js +++ b/src/Node/Buffer.js @@ -9,7 +9,9 @@ export const writeInternal = (ty, value, offset, buf) => export const writeStringInternal = (encoding, offset, length, value, buff) => buff.write(value, offset, length, encoding); -export const setAtOffsetImpl = (value, offset, buff) => buff[offset] = value; +export const setAtOffsetImpl = (value, offset, buff) => { + buff[offset] = value; +}; export const copyImpl = (srcStart, srcEnd, src, targStart, targ) => src.copy(targ, targStart, srcStart, srcEnd); From 7bb1160384f5e95fd5a487e68f17c121b1fda2cf Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 28 Jun 2023 18:02:44 -0500 Subject: [PATCH 05/11] Breaking: remove aliases; add Base64Url --- src/Node/Encoding.purs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Node/Encoding.purs b/src/Node/Encoding.purs index 42f4a35..1f9ec4e 100644 --- a/src/Node/Encoding.purs +++ b/src/Node/Encoding.purs @@ -1,3 +1,5 @@ +-- | Note: encodings that are aliases of another one +-- | are not supported below as a way to prevent confusion. module Node.Encoding ( Encoding(..) , encodingToNode @@ -11,21 +13,21 @@ import Data.Function.Uncurried (Fn2, runFn2) data Encoding = ASCII | UTF8 + -- | Note: the `ucs2` and `ucs-2` encodings are aliases to this one. | UTF16LE - | UCS2 | Base64 + | Base64Url + -- | Note: the `binary` encoding is an alias to this one. | Latin1 - | Binary | Hex instance showEncoding :: Show Encoding where show ASCII = "ASCII" show UTF8 = "UTF8" show UTF16LE = "UTF16LE" - show UCS2 = "UCS2" show Base64 = "Base64" + show Base64Url = "Base64Url" show Latin1 = "Latin1" - show Binary = "Binary" show Hex = "Hex" -- | Convert an `Encoding` to a `String` in the format expected by Node.js @@ -34,10 +36,9 @@ encodingToNode :: Encoding -> String encodingToNode ASCII = "ascii" encodingToNode UTF8 = "utf8" encodingToNode UTF16LE = "utf16le" -encodingToNode UCS2 = "ucs2" encodingToNode Base64 = "base64" +encodingToNode Base64Url = "base64url" encodingToNode Latin1 = "latin1" -encodingToNode Binary = "binary" encodingToNode Hex = "hex" foreign import byteLengthImpl :: Fn2 (String) (String) (Int) From 358c21c0bfa8dc6cc328163e3269a855aa1ff6f6 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 28 Jun 2023 18:47:22 -0500 Subject: [PATCH 06/11] Add bindings for missing constants --- src/Node/Buffer/Constants.js | 5 +++++ src/Node/Buffer/Constants.purs | 9 +++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/Node/Buffer/Constants.js create mode 100644 src/Node/Buffer/Constants.purs diff --git a/src/Node/Buffer/Constants.js b/src/Node/Buffer/Constants.js new file mode 100644 index 0000000..8633b1f --- /dev/null +++ b/src/Node/Buffer/Constants.js @@ -0,0 +1,5 @@ +import buffer from "node:buffer"; + +export const inspectMaxBytes = () => buffer.constants.INSPECT_MAX_LENGTH; +export const maxLength = buffer.constants.MAX_LENGTH; +export const maxStringLength = buffer.constants.MAX_STRING_LENGTH; diff --git a/src/Node/Buffer/Constants.purs b/src/Node/Buffer/Constants.purs new file mode 100644 index 0000000..91b628b --- /dev/null +++ b/src/Node/Buffer/Constants.purs @@ -0,0 +1,9 @@ +module Node.Buffer.Constants where + +import Effect (Effect) + +foreign import inspectMaxBytes :: Effect Int + +foreign import maxLength :: Int + +foreign import maxStringLength :: Int From 9bc57103ee5ac59aa14479064bd04a98e2c04a9d Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 28 Jun 2023 18:58:45 -0500 Subject: [PATCH 07/11] Add missing create, compare, toString APIs --- src/Node/Buffer.purs | 26 ++++++++++++++++++++- src/Node/Buffer/Immutable.js | 8 ++++++- src/Node/Buffer/Immutable.purs | 42 ++++++++++++++++++++++++++++++---- src/Node/Buffer/ST.purs | 23 ++++++++++++++++++- 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/src/Node/Buffer.purs b/src/Node/Buffer.purs index 35c3253..9a051f3 100644 --- a/src/Node/Buffer.purs +++ b/src/Node/Buffer.purs @@ -2,6 +2,10 @@ module Node.Buffer ( Buffer , create + , alloc + , allocUnsafe + , allocUnsafeSlow + , compareParts , freeze , unsafeFreeze , thaw @@ -13,6 +17,7 @@ module Node.Buffer , read , readString , toString + , toString' , write , writeString , toArray @@ -55,8 +60,18 @@ usingFromImmutable f buf = f <$> unsafeFreeze buf usingToImmutable :: forall a. (a -> ImmutableBuffer) -> a -> Effect Buffer usingToImmutable f x = unsafeThaw $ f x +-- | Alias to `alloc`. create :: Int -> Effect Buffer -create = usingToImmutable Immutable.create +create = alloc + +alloc :: Int -> Effect Buffer +alloc = usingToImmutable Immutable.alloc + +allocUnsafe :: Int -> Effect Buffer +allocUnsafe = usingToImmutable Immutable.allocUnsafe + +allocUnsafeSlow :: Int -> Effect Buffer +allocUnsafeSlow = usingToImmutable Immutable.allocUnsafeSlow freeze :: Buffer -> Effect ImmutableBuffer freeze = runEffectFn1 freezeImpl @@ -80,6 +95,12 @@ fromArrayBuffer = usingToImmutable Immutable.fromArrayBuffer toArrayBuffer :: Buffer -> Effect ArrayBuffer toArrayBuffer = usingFromImmutable Immutable.toArrayBuffer +compareParts :: Buffer -> Buffer -> Int -> Int -> Int -> Int -> Effect Ordering +compareParts src target targetSrc targetEnd srcStart srcEnd = do + src' <- unsafeFreeze src + target' <- unsafeFreeze target + Immutable.compareParts src' target' targetSrc targetEnd srcStart srcEnd + read :: BufferValueType -> Offset -> Buffer -> Effect Number read t o = usingFromImmutable $ Immutable.read t o @@ -89,6 +110,9 @@ readString m o o' = usingFromImmutable $ Immutable.readString m o o' toString :: Encoding -> Buffer -> Effect String toString m = usingFromImmutable $ Immutable.toString m +toString' :: Encoding -> Offset -> Offset -> Buffer -> Effect String +toString' enc start end = usingFromImmutable $ Immutable.toString' enc start end + write :: BufferValueType -> Number -> Offset -> Buffer -> Effect Unit write ty num off buf = runEffectFn4 writeInternal (show ty) num off buf diff --git a/src/Node/Buffer/Immutable.js b/src/Node/Buffer/Immutable.js index 879b2c1..acff126 100644 --- a/src/Node/Buffer/Immutable.js +++ b/src/Node/Buffer/Immutable.js @@ -4,7 +4,12 @@ export const showImpl = inspect; export const eqImpl = (a, b) => a.equals(b); export const compareImpl = (a, b) => a.compare(b); -export const create = (size) => Buffer.alloc(size); +export const comparePartsImpl = (src, target, targetStart, targetEnd, sourceStart, sourceEnd) => + src.compare(target, targetStart, targetEnd, sourceStart, sourceEnd); + +export const alloc = (size) => Buffer.alloc(size); +export const allocUnsafe = (size) => Buffer.allocUnsafe(size); +export const allocUnsafeSlow = (size) => Buffer.allocUnsafeSlow(size); export const fromArray = (octets) => Buffer.from(octets); @@ -25,6 +30,7 @@ export const readImpl = (ty, offset, buf) => buf["read" + ty](offset); export const readStringImpl = (enc, start, end, buff) => buff.toString(enc, start, end); export const getAtOffsetImpl = (offset, buff) => buff[offset]; export const toStringImpl = (enc, buff) => buff.toString(enc); +export const toStringSubImpl = (enc, start, end, buff) => buff.toString(enc, start, end); export const sliceImpl = (start, end, buff) => buff.slice(start, end); export const concat = (buffs) => Buffer.concat(buffs); export const concatToLength = (buffs, totalLength) => Buffer.concat(buffs, totalLength); diff --git a/src/Node/Buffer/Immutable.purs b/src/Node/Buffer/Immutable.purs index 6fd1832..40f80b1 100644 --- a/src/Node/Buffer/Immutable.purs +++ b/src/Node/Buffer/Immutable.purs @@ -1,13 +1,18 @@ -- | Immutable buffers and associated operations. module Node.Buffer.Immutable ( ImmutableBuffer + , compareParts , create + , alloc + , allocUnsafe + , allocUnsafeSlow , fromArray , fromString , fromArrayBuffer , read , readString , toString + , toString' , toArray , toArrayBuffer , getAtOffset @@ -23,8 +28,11 @@ import Data.ArrayBuffer.Types (ArrayBuffer) import Data.Function.Uncurried (Fn2, Fn3, Fn4, runFn2, runFn3, runFn4) import Data.Maybe (Maybe) import Data.Nullable (Nullable, toMaybe) -import Node.Buffer.Types (BufferValueType, Offset, Octet) +import Effect (Effect) +import Effect.Uncurried (EffectFn6, runEffectFn6) +import Node.Buffer.Types (BufferValueType, Octet, Offset) import Node.Encoding (Encoding, encodingToNode) +import Partial.Unsafe (unsafeCrashWith) -- | An immutable buffer that exists independently of any memory region or effect. foreign import data ImmutableBuffer :: Type @@ -48,15 +56,24 @@ instance ordBuffer :: Ord ImmutableBuffer where foreign import compareImpl :: Fn2 ImmutableBuffer ImmutableBuffer Int --- | Creates a new buffer of the specified size. -foreign import create :: Int -> ImmutableBuffer +-- | Creates a new buffer of the specified size. Alias for `alloc`. +create :: Int -> ImmutableBuffer +create = alloc + +foreign import alloc :: Int -> ImmutableBuffer + +-- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool +-- | and may contain sensitive data. See the Node docs. +foreign import allocUnsafe :: Int -> ImmutableBuffer + +-- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool +-- | and may contain sensitive data. See the Node docs. +foreign import allocUnsafeSlow :: Int -> ImmutableBuffer -- | Creates a new buffer from an array of octets, sized to match the array. foreign import fromArray :: Array Octet -> ImmutableBuffer -- | Creates a buffer view from a JS ArrayByffer without copying data. --- --- Requires Node >= v5.10.0 foreign import fromArrayBuffer :: ArrayBuffer -> ImmutableBuffer -- | Creates a new buffer from a string with the specified encoding, sized to match the string. @@ -65,6 +82,16 @@ fromString str enc = runFn2 fromStringImpl str $ encodingToNode enc foreign import fromStringImpl :: Fn2 String String ImmutableBuffer +compareParts :: ImmutableBuffer -> ImmutableBuffer -> Int -> Int -> Int -> Int -> Effect Ordering +compareParts src target targetStart targetEnd sourceStart sourceEnd = + runEffectFn6 comparePartsImpl src target targetStart targetEnd sourceStart sourceEnd <#> case _ of + -1 -> LT + 0 -> EQ + 1 -> GT + x -> unsafeCrashWith $ "Impossible: Invalid value: " <> show x + +foreign import comparePartsImpl :: EffectFn6 (ImmutableBuffer) (ImmutableBuffer) (Int) (Int) (Int) (Int) (Int) + -- | Reads a numeric value from a buffer at the specified offset. read :: BufferValueType -> Offset -> ImmutableBuffer -> Number read ty offset buf = runFn3 readImpl (show ty) offset buf @@ -84,6 +111,11 @@ toString enc buf = runFn2 toStringImpl (encodingToNode enc) buf foreign import toStringImpl :: Fn2 String ImmutableBuffer String +toString' :: Encoding -> Offset -> Offset -> ImmutableBuffer -> String +toString' enc start end buf = runFn4 toStringSubImpl enc start end buf + +foreign import toStringSubImpl :: Fn4 (Encoding) (Offset) (Offset) (ImmutableBuffer) (String) + -- | Creates an array of octets from a buffer's contents. foreign import toArray :: ImmutableBuffer -> Array Octet diff --git a/src/Node/Buffer/ST.purs b/src/Node/Buffer/ST.purs index 72bae62..b1c35d6 100644 --- a/src/Node/Buffer/ST.purs +++ b/src/Node/Buffer/ST.purs @@ -2,6 +2,10 @@ module Node.Buffer.ST ( STBuffer , run , create + , alloc + , allocUnsafe + , allocUnsafeSlow + , compareParts , freeze , unsafeFreeze , thaw @@ -13,6 +17,7 @@ module Node.Buffer.ST , read , readString , toString + , toString' , write , writeString , toArray @@ -54,8 +59,21 @@ unsafeFreeze = unsafeCoerce Buffer.unsafeFreeze unsafeThaw :: forall h. ImmutableBuffer -> ST h (STBuffer h) unsafeThaw = unsafeCoerce Buffer.unsafeThaw +-- | Creates a new `STBuffer`. Alias of `alloc`. create :: forall h. Int -> ST h (STBuffer h) -create = unsafeCoerce Buffer.create +create = alloc + +alloc :: forall h. Int -> ST h (STBuffer h) +alloc = unsafeCoerce Buffer.alloc + +allocUnsafe :: forall h. Int -> ST h (STBuffer h) +allocUnsafe = unsafeCoerce Buffer.allocUnsafe + +allocUnsafeSlow :: forall h. Int -> ST h (STBuffer h) +allocUnsafeSlow = unsafeCoerce Buffer.allocUnsafeSlow + +compareParts :: forall h. STBuffer h -> STBuffer h -> Int -> Int -> Int -> Int -> ST h Ordering +compareParts = unsafeCoerce Buffer.compareParts freeze :: forall h. (STBuffer h) -> ST h ImmutableBuffer freeze = unsafeCoerce Buffer.freeze @@ -84,6 +102,9 @@ readString = unsafeCoerce Buffer.readString toString :: forall h. Encoding -> (STBuffer h) -> ST h String toString = unsafeCoerce Buffer.toString +toString' :: forall h. Encoding -> Offset -> Offset -> (STBuffer h) -> ST h String +toString' = unsafeCoerce Buffer.toString' + write :: forall h. BufferValueType -> Number -> Offset -> (STBuffer h) -> ST h Unit write = unsafeCoerce Buffer.write From 4246efac5f523f7ba4d8a64b24bf752f65de35d9 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 28 Jun 2023 19:00:32 -0500 Subject: [PATCH 08/11] Add swap & pool size API --- src/Node/Buffer.js | 13 ++++++++++++- src/Node/Buffer.purs | 28 ++++++++++++++++++++++++++++ src/Node/Buffer/ST.purs | 12 ++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Node/Buffer.js b/src/Node/Buffer.js index 44afc3c..0f6e856 100644 --- a/src/Node/Buffer.js +++ b/src/Node/Buffer.js @@ -1,4 +1,5 @@ -/* global Buffer */ +import { Buffer } from "node:buffer"; + export const freezeImpl= (a) => Buffer.from(a); export const thawImpl = (a) => Buffer.from(a); @@ -17,3 +18,13 @@ export const copyImpl = (srcStart, srcEnd, src, targStart, targ) => src.copy(targ, targStart, srcStart, srcEnd); export const fillImpl = (octet, start, end, buf) => buf.fill(octet, start, end); + +export const poolSize = () => Buffer.poolSize; + +export const setPoolSizeImpl = (size) => { + Buffer.poolSize = size; +}; + +export const swap16Impl = (buf) => buf.swap16(); +export const swap32Impl = (buf) => buf.swap32(); +export const swap64Impl = (buf) => buf.swap64(); diff --git a/src/Node/Buffer.purs b/src/Node/Buffer.purs index 9a051f3..277411d 100644 --- a/src/Node/Buffer.purs +++ b/src/Node/Buffer.purs @@ -29,6 +29,11 @@ module Node.Buffer , concat' , copy , fill + , poolSize + , setPoolSize + , swap16 + , swap32 + , swap64 , module TypesExports ) where @@ -159,3 +164,26 @@ fill octet start end buf = runEffectFn4 fillImpl octet start end buf foreign import fillImpl :: EffectFn4 Octet Offset Offset Buffer Unit + +-- | The size (in bytes) of pre-allocated internal Buffer instances used for pooling. This value may be modified. +foreign import poolSize :: Effect (Int) + +setPoolSize :: Int -> Effect Unit +setPoolSize sizeInBytes = runEffectFn1 setPoolSizeImpl sizeInBytes + +foreign import setPoolSizeImpl :: EffectFn1 (Int) (Unit) + +swap16 :: Buffer -> Effect Buffer +swap16 b = runEffectFn1 swap16Impl b + +foreign import swap16Impl :: EffectFn1 (Buffer) (Buffer) + +swap32 :: Buffer -> Effect Buffer +swap32 b = runEffectFn1 swap32Impl b + +foreign import swap32Impl :: EffectFn1 (Buffer) (Buffer) + +swap64 :: Buffer -> Effect Buffer +swap64 b = runEffectFn1 swap64Impl b + +foreign import swap64Impl :: EffectFn1 (Buffer) (Buffer) diff --git a/src/Node/Buffer/ST.purs b/src/Node/Buffer/ST.purs index b1c35d6..92075ae 100644 --- a/src/Node/Buffer/ST.purs +++ b/src/Node/Buffer/ST.purs @@ -29,6 +29,9 @@ module Node.Buffer.ST , concat' , copy , fill + , swap16 + , swap32 + , swap64 ) where import Prelude @@ -138,3 +141,12 @@ copy = unsafeCoerce Buffer.copy fill :: forall h. Octet -> Offset -> Offset -> (STBuffer h) -> ST h Unit fill = unsafeCoerce Buffer.fill + +swap16 :: forall h. STBuffer h -> ST h (STBuffer h) +swap16 = unsafeCoerce Buffer.swap16 + +swap32 :: forall h. STBuffer h -> ST h (STBuffer h) +swap32 = unsafeCoerce Buffer.swap32 + +swap64 :: forall h. STBuffer h -> ST h (STBuffer h) +swap64 = unsafeCoerce Buffer.swap64 From 6c9cdc11d1f8ef53d0e32e381d49fbaeea9e4103 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 28 Jun 2023 19:08:10 -0500 Subject: [PATCH 09/11] Fix inspectMaxBytes --- src/Node/Buffer/Constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Node/Buffer/Constants.js b/src/Node/Buffer/Constants.js index 8633b1f..12bbaa0 100644 --- a/src/Node/Buffer/Constants.js +++ b/src/Node/Buffer/Constants.js @@ -1,5 +1,5 @@ import buffer from "node:buffer"; -export const inspectMaxBytes = () => buffer.constants.INSPECT_MAX_LENGTH; +export const inspectMaxBytes = () => buffer.INSPECT_MAX_LENGTH; export const maxLength = buffer.constants.MAX_LENGTH; export const maxStringLength = buffer.constants.MAX_STRING_LENGTH; From 4b3b238d1ee454dc0143cd8c3eb06d17ee3bd7b3 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 28 Jun 2023 19:09:51 -0500 Subject: [PATCH 10/11] Update changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c9949b..880e644 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,8 +20,24 @@ Breaking changes: One can migrate their code by either removing the usage of `MonadClass` in their code if it was only used to get the needed API for a given type (e.g. `Buffer`) or update their module imports from `Node.Buffer`/`Node.Buffer.ST` to `Node.Buffer.Class`. +- `Encoding` type - dropped encodings that are only aliases (#51 by @JordanMartinez) + + - `Binary`, an alias for `Latin1` was dropped. + - `UCS2`, an alias for `UTF16LE` was dropped. +- `Encoding` type - added `Base64Url` encoding (supported in Node 18) (#51 by @JordanMartinez) New features: +- Added the following APIs + + - `Buffer.alloc`, `Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow` + - `Buffer.poolSize`, `Buffer.setPoolSize` + - `buffer.swap16`, `buffer.swap32`, `buffer.swap64` + - `buffer.compare`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufcomparetarget-targetstart-targetend-sourcestart-sourceend + - `buffer.toString(encoding, start, end)`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#buftostringencoding-start-end + - constants: + - `INSPECT_MAX_BYTES`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufferinspect_max_bytes + - `MAX_LENGTH`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufferconstantsmax_length + - `MAX_STRING_LENGTH`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufferconstantsmax_string_length Bugfixes: From 83a682f4fba0906f7cc58bca06263c46753af40f Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Thu, 29 Jun 2023 10:51:01 -0500 Subject: [PATCH 11/11] Make allocUnsafe* effectful & Buffer --- src/Node/Buffer.js | 3 +++ src/Node/Buffer.purs | 12 ++++++++++-- src/Node/Buffer/Immutable.js | 2 -- src/Node/Buffer/Immutable.purs | 10 ---------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Node/Buffer.js b/src/Node/Buffer.js index 0f6e856..4157d26 100644 --- a/src/Node/Buffer.js +++ b/src/Node/Buffer.js @@ -1,5 +1,8 @@ import { Buffer } from "node:buffer"; +export const allocUnsafeImpl = (size) => Buffer.allocUnsafe(size); +export const allocUnsafeSlowImpl = (size) => Buffer.allocUnsafeSlow(size); + export const freezeImpl= (a) => Buffer.from(a); export const thawImpl = (a) => Buffer.from(a); diff --git a/src/Node/Buffer.purs b/src/Node/Buffer.purs index 277411d..d3724ab 100644 --- a/src/Node/Buffer.purs +++ b/src/Node/Buffer.purs @@ -72,11 +72,19 @@ create = alloc alloc :: Int -> Effect Buffer alloc = usingToImmutable Immutable.alloc +-- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool +-- | and may contain sensitive data. See the Node docs. allocUnsafe :: Int -> Effect Buffer -allocUnsafe = usingToImmutable Immutable.allocUnsafe +allocUnsafe s = runEffectFn1 allocUnsafeImpl s +foreign import allocUnsafeImpl :: EffectFn1 (Int) (Buffer) + +-- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool +-- | and may contain sensitive data. See the Node docs. allocUnsafeSlow :: Int -> Effect Buffer -allocUnsafeSlow = usingToImmutable Immutable.allocUnsafeSlow +allocUnsafeSlow s = runEffectFn1 allocUnsafeSlowImpl s + +foreign import allocUnsafeSlowImpl :: EffectFn1 (Int) (Buffer) freeze :: Buffer -> Effect ImmutableBuffer freeze = runEffectFn1 freezeImpl diff --git a/src/Node/Buffer/Immutable.js b/src/Node/Buffer/Immutable.js index acff126..22a0322 100644 --- a/src/Node/Buffer/Immutable.js +++ b/src/Node/Buffer/Immutable.js @@ -8,8 +8,6 @@ export const comparePartsImpl = (src, target, targetStart, targetEnd, sourceStar src.compare(target, targetStart, targetEnd, sourceStart, sourceEnd); export const alloc = (size) => Buffer.alloc(size); -export const allocUnsafe = (size) => Buffer.allocUnsafe(size); -export const allocUnsafeSlow = (size) => Buffer.allocUnsafeSlow(size); export const fromArray = (octets) => Buffer.from(octets); diff --git a/src/Node/Buffer/Immutable.purs b/src/Node/Buffer/Immutable.purs index 40f80b1..0212e23 100644 --- a/src/Node/Buffer/Immutable.purs +++ b/src/Node/Buffer/Immutable.purs @@ -4,8 +4,6 @@ module Node.Buffer.Immutable , compareParts , create , alloc - , allocUnsafe - , allocUnsafeSlow , fromArray , fromString , fromArrayBuffer @@ -62,14 +60,6 @@ create = alloc foreign import alloc :: Int -> ImmutableBuffer --- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool --- | and may contain sensitive data. See the Node docs. -foreign import allocUnsafe :: Int -> ImmutableBuffer - --- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool --- | and may contain sensitive data. See the Node docs. -foreign import allocUnsafeSlow :: Int -> ImmutableBuffer - -- | Creates a new buffer from an array of octets, sized to match the array. foreign import fromArray :: Array Octet -> ImmutableBuffer