Skip to content

Convert FFI to uncurried functions #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Bugfixes:

Other improvements:
- Format code with `purs-tidy`; enforce in CI (#52 by @JordanMartinez)
- Update FFI to use uncurried functions (#54 by @JordanMartinez)
- Removed `Internal.purs` file (#54 by @JordanMartinez)

## [v8.0.0](https://github.com/purescript-node/purescript-node-buffer/releases/tag/v8.0.0) - 2022-04-27

Expand Down
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
19 changes: 19 additions & 0 deletions src/Node/Buffer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Buffer } from "node: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);
103 changes: 64 additions & 39 deletions src/Node/Buffer.purs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ import Prelude
import Data.ArrayBuffer.Types (ArrayBuffer)
import Data.Maybe (Maybe)
import Effect (Effect)
import Effect.Uncurried (EffectFn1, EffectFn3, EffectFn4, EffectFn5, runEffectFn1, runEffectFn3, runEffectFn4, runEffectFn5)
import Node.Buffer.Class (class MutableBuffer)
import Node.Buffer.Immutable (ImmutableBuffer)
import Node.Buffer.Internal as Internal
import Node.Buffer.Immutable as Immutable
import Node.Buffer.Types (BufferValueType(..), Octet, Offset) as TypesExports
import Node.Buffer.Types (BufferValueType)
import Node.Encoding (Encoding)
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
Expand Down Expand Up @@ -67,71 +69,94 @@ instance mutableBufferEffect :: MutableBuffer Buffer Effect where
copy = copy
fill = 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 = Internal.create
create = usingToImmutable Immutable.create

freeze :: Buffer -> Effect ImmutableBuffer
freeze = Internal.copyAll
freeze = runEffectFn1 freezeImpl

unsafeFreeze :: Buffer -> Effect ImmutableBuffer
unsafeFreeze = Internal.unsafeFreeze
foreign import freezeImpl :: EffectFn1 Buffer ImmutableBuffer

thaw :: ImmutableBuffer -> Effect Buffer
thaw = Internal.copyAll
thaw = runEffectFn1 thawImpl

unsafeThaw :: ImmutableBuffer -> Effect Buffer
unsafeThaw = Internal.unsafeThaw
foreign import thawImpl :: EffectFn1 ImmutableBuffer Buffer

fromArray :: Array Int -> Effect Buffer
fromArray = Internal.fromArray
fromArray :: Array Octet -> Effect Buffer
fromArray = usingToImmutable Immutable.fromArray

fromString :: String -> Encoding -> Effect Buffer
fromString = Internal.fromString
fromString s = usingToImmutable $ Immutable.fromString s

fromArrayBuffer :: ArrayBuffer -> Effect Buffer
fromArrayBuffer = Internal.fromArrayBuffer
fromArrayBuffer = usingToImmutable Immutable.fromArrayBuffer

toArrayBuffer :: Buffer -> Effect ArrayBuffer
toArrayBuffer = Internal.toArrayBuffer
toArrayBuffer = usingFromImmutable Immutable.toArrayBuffer

read :: BufferValueType -> Int -> Buffer -> Effect Number
read = Internal.read
read :: BufferValueType -> Offset -> Buffer -> Effect Number
read t o = usingFromImmutable $ Immutable.read t o

readString :: Encoding -> Int -> Int -> Buffer -> Effect String
readString = Internal.readString
readString :: Encoding -> Offset -> Offset -> Buffer -> Effect String
readString enc o o' = usingFromImmutable $ Immutable.readString enc o o'

toString :: Encoding -> Buffer -> Effect String
toString = Internal.toString
toString enc = usingFromImmutable $ Immutable.toString enc

write :: BufferValueType -> Number -> Offset -> Buffer -> Effect Unit
write ty value offset buf = runEffectFn4 writeInternal (show ty) value offset buf

foreign import writeInternal :: EffectFn4 String Number Offset Buffer Unit

write :: BufferValueType -> Number -> Int -> Buffer -> Effect Unit
write = Internal.write
writeString :: Encoding -> Offset -> Int -> String -> Buffer -> Effect Int
writeString enc offset len value buf =
runEffectFn5 writeStringInternal (encodingToNode enc) offset len value buf

writeString :: Encoding -> Int -> Int -> String -> Buffer -> Effect Int
writeString = Internal.writeString
foreign import writeStringInternal :: EffectFn5 String Offset Int String Buffer Int

toArray :: Buffer -> Effect (Array Int)
toArray = Internal.toArray
toArray :: Buffer -> Effect (Array Octet)
toArray = usingFromImmutable Immutable.toArray

getAtOffset :: Int -> Buffer -> Effect (Maybe Int)
getAtOffset = Internal.getAtOffset
getAtOffset :: Offset -> Buffer -> Effect (Maybe Octet)
getAtOffset o = usingFromImmutable $ Immutable.getAtOffset o

setAtOffset :: Int -> Int -> Buffer -> Effect Unit
setAtOffset = Internal.setAtOffset
setAtOffset :: Octet -> Offset -> Buffer -> Effect Unit
setAtOffset val off buff = runEffectFn3 setAtOffsetImpl val off buff

slice :: Int -> Int -> Buffer -> Buffer
slice = Internal.slice
foreign import setAtOffsetImpl :: EffectFn3 Octet Offset Buffer Unit

slice :: Offset -> Offset -> Buffer -> Buffer
slice = unsafeCoerce Immutable.slice

size :: Buffer -> Effect Int
size = Internal.size
size = usingFromImmutable Immutable.size

concat :: Array Buffer -> Effect Buffer
concat = Internal.concat
concat arrs = unsafeCoerce \_ -> Immutable.concat (unsafeCoerce arrs)

concat' :: Array Buffer -> Int -> Effect Buffer
concat' = Internal.concat'
concat' arrs n = unsafeCoerce \_ -> Immutable.concat' (unsafeCoerce arrs) n

copy :: Offset -> Offset -> Buffer -> Offset -> Buffer -> Effect Int
copy srcStart srcEnd src targStart targ = do
runEffectFn5 copyImpl srcStart srcEnd src targStart targ

foreign import copyImpl :: EffectFn5 Offset Offset Buffer Offset Buffer Int

copy :: Int -> Int -> Buffer -> Int -> Buffer -> Effect Int
copy = Internal.copy
fill :: Octet -> Offset -> Offset -> Buffer -> Effect Unit
fill octet start end buf = do
runEffectFn4 fillImpl octet start end buf

fill :: Int -> Int -> Int -> Buffer -> Effect Unit
fill = Internal.fill
foreign import fillImpl :: EffectFn4 Octet Offset Offset Buffer Unit
95 changes: 18 additions & 77 deletions src/Node/Buffer/Immutable.js
Original file line number Diff line number Diff line change
@@ -1,99 +1,40 @@
/* global Buffer */
import { Buffer } from "node:buffer";

import { inspect } from "util";
export const showImpl = inspect;

export function eqImpl(a) {
return b => {
return a.equals(b);
};
}
export const eqImpl = (a, b) => a.equals(b);

export function compareImpl(a) {
return b => {
return a.compare(b);
};
}
export const compareImpl = (a, b) => a.compare(b);

export function create(size) {
return Buffer.alloc(size);
}
export const create = (size) => 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) {
var json = buff.toJSON();
return json.data || json;
}

export function toArrayBuffer(buff) {
return buff.buffer.slice(buff.byteOffset, buff.byteOffset + buff.byteLength);
}
export const toArrayBuffer = (buff) =>
buff.buffer.slice(buff.byteOffset, buff.byteOffset + buff.byteLength);

export function fromArrayBuffer(ab) {
return Buffer.from(ab);
}
export const fromArrayBuffer = (ab) => Buffer.from(ab);

export function fromStringImpl(str) {
return encoding => {
return Buffer.from(str, encoding);
};
}
export const fromStringImpl = (str, encoding) => Buffer.from(str, encoding);

export function readImpl(ty) {
return offset => {
return buf => {
return buf["read" + ty](offset);
};
};
}
export const readImpl = (ty, offset, buf) => buf["read" + ty](offset);

export function readStringImpl(enc) {
return start => {
return end => {
return buff => {
return buff.toString(enc, start, end);
};
};
};
}
export const readStringImpl = (enc, start, end, buff) => 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 const getAtOffsetImpl = (offset, buff) => buff[offset];

export function toStringImpl(enc) {
return buff => {
return buff.toString(enc);
};
}
export const toStringImpl = (enc, buff) => buff.toString(enc);

export function slice(start) {
return end => {
return buff => {
return buff.slice(start, end);
};
};
}
export const sliceImpl = (start, end, buff) => buff.slice(start, end);

export function concat(buffs) {
return Buffer.concat(buffs);
}
export const concat = (buffs) => Buffer.concat(buffs);

export function concatToLength(buffs) {
return totalLength => {
return Buffer.concat(buffs, totalLength);
};
}
export const concatToLength = (buffs, totalLength) => Buffer.concat(buffs, totalLength);
Loading