Skip to content

Commit 19e49ce

Browse files
authoredJul 5, 2023
Add missing Buffer APIs; update CI: node and actions versions (#55)
* Add missing Buffer APIs * Update CI: Node to latest; actions to v3 * Update changelog
1 parent c6533da commit 19e49ce

File tree

9 files changed

+213
-28
lines changed

9 files changed

+213
-28
lines changed
 

‎.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ jobs:
1010
build:
1111
runs-on: ubuntu-latest
1212
steps:
13-
- uses: actions/checkout@v2
13+
- uses: actions/checkout@v3
1414

1515
- uses: purescript-contrib/setup-purescript@main
1616
with:
1717
purescript: "unstable"
1818
purs-tidy: "latest"
1919

20-
- uses: actions/setup-node@v2
20+
- uses: actions/setup-node@v3
2121
with:
22-
node-version: "14"
22+
node-version: "latest"
2323

2424
- name: Install dependencies
2525
run: |

‎CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,28 @@ Breaking changes:
4444
```
4545

4646
New features:
47+
- Added the following APIs (#55 by @JordanMartinez)
48+
49+
- `Buffer.alloc`, `Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`
50+
- `Buffer.poolSize`, `Buffer.setPoolSize`
51+
- `buffer.swap16`, `buffer.swap32`, `buffer.swap64`
52+
- `buffer.compare`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufcomparetarget-targetstart-targetend-sourcestart-sourceend
53+
- `buffer.toString(encoding, start, end)`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#buftostringencoding-start-end
54+
- `buffer.transcode(buf, from, to)`
55+
- constants:
56+
- `INSPECT_MAX_BYTES`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufferinspect_max_bytes
57+
- `MAX_LENGTH`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufferconstantsmax_length
58+
- `MAX_STRING_LENGTH`: https://nodejs.org/docs/latest-v18.x/api/buffer.html#bufferconstantsmax_string_length
59+
4760

4861
Bugfixes:
4962

5063
Other improvements:
5164
- Format code with `purs-tidy`; enforce in CI (#52 by @JordanMartinez)
5265
- Update FFI to use uncurried functions (#54 by @JordanMartinez)
5366
- Removed `Internal.purs` file (#54 by @JordanMartinez)
67+
- Bumped CI's node version to `latest` (#55 by @JordanMartinez)
68+
- Updated CI `actions/checkout` and `actions/setup-nodee` to `v3` (#55 by @JordanMartinez)
5469

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

‎src/Node/Buffer.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { Buffer } from "node:buffer";
1+
import { Buffer, transcode } from "node:buffer";
2+
3+
export const allocUnsafeImpl = (size) => Buffer.allocUnsafe(size);
4+
export const allocUnsafeSlowImpl = (size) => Buffer.allocUnsafeSlow(size);
25

36
export const freezeImpl = (a) => Buffer.from(a);
47
export const thawImpl = (a) => Buffer.from(a);
@@ -17,3 +20,14 @@ export const copyImpl = (srcStart, srcEnd, src, targStart, targ) =>
1720

1821
export const fillImpl = (octet, start, end, buf) =>
1922
buf.fill(octet, start, end);
23+
24+
export const poolSize = () => Buffer.poolSize;
25+
26+
export const setPoolSizeImpl = (size) => {
27+
Buffer.poolSize = size;
28+
};
29+
30+
export const swap16Impl = (buf) => buf.swap16();
31+
export const swap32Impl = (buf) => buf.swap32();
32+
export const swap64Impl = (buf) => buf.swap64();
33+
export const transcodeImpl = (buf, from, to) => transcode(buf, from, to);

‎src/Node/Buffer.purs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ module Node.Buffer
33
( Buffer
44
, module TypesExports
55
, create
6+
, alloc
7+
, allocUnsafe
8+
, allocUnsafeSlow
9+
, compareParts
610
, freeze
711
, unsafeFreeze
812
, thaw
@@ -14,6 +18,7 @@ module Node.Buffer
1418
, read
1519
, readString
1620
, toString
21+
, toString'
1722
, write
1823
, writeString
1924
, toArray
@@ -25,6 +30,12 @@ module Node.Buffer
2530
, concat'
2631
, copy
2732
, fill
33+
, poolSize
34+
, setPoolSize
35+
, swap16
36+
, swap32
37+
, swap64
38+
, transcode
2839
) where
2940

3041
import Prelude
@@ -81,8 +92,29 @@ usingFromImmutable f buf = f <$> unsafeFreeze buf
8192
usingToImmutable :: forall a. (a -> ImmutableBuffer) -> a -> Effect Buffer
8293
usingToImmutable f x = unsafeThaw $ f x
8394

95+
-- | Creates a new buffer of the specified size. Alias to `alloc`.
8496
create :: Int -> Effect Buffer
85-
create = usingToImmutable Immutable.create
97+
create = alloc
98+
99+
-- | Creates a new buffer of the specified size.
100+
alloc :: Int -> Effect Buffer
101+
alloc = usingToImmutable Immutable.alloc
102+
103+
-- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool
104+
-- | and may contain sensitive data. See the Node docs:
105+
-- | https://nodejs.org/docs/latest-v18.x/api/buffer.html#what-makes-bufferallocunsafe-and-bufferallocunsafeslow-unsafe
106+
allocUnsafe :: Int -> Effect Buffer
107+
allocUnsafe s = runEffectFn1 allocUnsafeImpl s
108+
109+
foreign import allocUnsafeImpl :: EffectFn1 (Int) (Buffer)
110+
111+
-- | Creates a new buffer of the specified size. Unsafe because it reuses memory from a pool
112+
-- | and may contain sensitive data. See the Node docs:
113+
-- | https://nodejs.org/docs/latest-v18.x/api/buffer.html#what-makes-bufferallocunsafe-and-bufferallocunsafeslow-unsafe
114+
allocUnsafeSlow :: Int -> Effect Buffer
115+
allocUnsafeSlow s = runEffectFn1 allocUnsafeSlowImpl s
116+
117+
foreign import allocUnsafeSlowImpl :: EffectFn1 (Int) (Buffer)
86118

87119
freeze :: Buffer -> Effect ImmutableBuffer
88120
freeze = runEffectFn1 freezeImpl
@@ -106,6 +138,12 @@ fromArrayBuffer = usingToImmutable Immutable.fromArrayBuffer
106138
toArrayBuffer :: Buffer -> Effect ArrayBuffer
107139
toArrayBuffer = usingFromImmutable Immutable.toArrayBuffer
108140

141+
compareParts :: Buffer -> Buffer -> Offset -> Offset -> Offset -> Offset -> Effect Ordering
142+
compareParts src target targetSrc targetEnd srcStart srcEnd = do
143+
src' <- unsafeFreeze src
144+
target' <- unsafeFreeze target
145+
Immutable.compareParts src' target' targetSrc targetEnd srcStart srcEnd
146+
109147
read :: BufferValueType -> Offset -> Buffer -> Effect Number
110148
read t o = usingFromImmutable $ Immutable.read t o
111149

@@ -115,6 +153,9 @@ readString enc o o' = usingFromImmutable $ Immutable.readString enc o o'
115153
toString :: Encoding -> Buffer -> Effect String
116154
toString enc = usingFromImmutable $ Immutable.toString enc
117155

156+
toString' :: Encoding -> Offset -> Offset -> Buffer -> Effect String
157+
toString' enc start end = usingFromImmutable $ Immutable.toString' enc start end
158+
118159
write :: BufferValueType -> Number -> Offset -> Buffer -> Effect Unit
119160
write ty value offset buf = runEffectFn4 writeInternal (show ty) value offset buf
120161

@@ -160,3 +201,31 @@ fill octet start end buf = do
160201
runEffectFn4 fillImpl octet start end buf
161202

162203
foreign import fillImpl :: EffectFn4 Octet Offset Offset Buffer Unit
204+
205+
-- | The size (in bytes) of pre-allocated internal Buffer instances used for pooling. This value may be modified.
206+
foreign import poolSize :: Effect (Int)
207+
208+
setPoolSize :: Int -> Effect Unit
209+
setPoolSize sizeInBytes = runEffectFn1 setPoolSizeImpl sizeInBytes
210+
211+
foreign import setPoolSizeImpl :: EffectFn1 (Int) (Unit)
212+
213+
swap16 :: Buffer -> Effect Buffer
214+
swap16 b = runEffectFn1 swap16Impl b
215+
216+
foreign import swap16Impl :: EffectFn1 (Buffer) (Buffer)
217+
218+
swap32 :: Buffer -> Effect Buffer
219+
swap32 b = runEffectFn1 swap32Impl b
220+
221+
foreign import swap32Impl :: EffectFn1 (Buffer) (Buffer)
222+
223+
swap64 :: Buffer -> Effect Buffer
224+
swap64 b = runEffectFn1 swap64Impl b
225+
226+
foreign import swap64Impl :: EffectFn1 (Buffer) (Buffer)
227+
228+
transcode :: Buffer -> Encoding -> Encoding -> Effect Buffer
229+
transcode buf from to = runEffectFn3 transcodeImpl buf (encodingToNode from) (encodingToNode to)
230+
231+
foreign import transcodeImpl :: EffectFn3 (Buffer) (String) (String) (Buffer)

‎src/Node/Buffer/Constants.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import buffer from "node:buffer";
2+
3+
export const inspectMaxBytes = () => buffer.INSPECT_MAX_LENGTH;
4+
export const maxLength = buffer.constants.MAX_LENGTH;
5+
export const maxStringLength = buffer.constants.MAX_STRING_LENGTH;

‎src/Node/Buffer/Constants.purs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Node.Buffer.Constants where
2+
3+
import Effect (Effect)
4+
5+
foreign import inspectMaxBytes :: Effect Int
6+
7+
foreign import maxLength :: Int
8+
9+
foreign import maxStringLength :: Int

‎src/Node/Buffer/Immutable.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ export const eqImpl = (a, b) => a.equals(b);
77

88
export const compareImpl = (a, b) => a.compare(b);
99

10-
export const create = (size) => Buffer.alloc(size);
10+
export const comparePartsImpl = (src, target, targetStart, targetEnd, sourceStart, sourceEnd) =>
11+
src.compare(target, targetStart, targetEnd, sourceStart, sourceEnd);
12+
13+
export const alloc = (size) => Buffer.alloc(size);
1114

1215
export const fromArray = (octets) => Buffer.from(octets);
1316

@@ -33,6 +36,8 @@ export const getAtOffsetImpl = (offset, buff) => buff[offset];
3336

3437
export const toStringImpl = (enc, buff) => buff.toString(enc);
3538

39+
export const toStringSubImpl = (enc, start, end, buff) => buff.toString(enc, start, end);
40+
3641
export const sliceImpl = (start, end, buff) => buff.slice(start, end);
3742

3843
export const concat = (buffs) => Buffer.concat(buffs);

‎src/Node/Buffer/Immutable.purs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
-- | Immutable buffers and associated operations.
22
module Node.Buffer.Immutable
33
( ImmutableBuffer
4+
, compareParts
45
, create
6+
, alloc
57
, fromArray
68
, fromString
79
, fromArrayBuffer
810
, read
911
, readString
1012
, toString
13+
, toString'
1114
, toArray
1215
, toArrayBuffer
1316
, getAtOffset
@@ -23,8 +26,11 @@ import Data.ArrayBuffer.Types (ArrayBuffer)
2326
import Data.Function.Uncurried (Fn2, Fn3, Fn4, runFn2, runFn3, runFn4)
2427
import Data.Maybe (Maybe)
2528
import Data.Nullable (Nullable, toMaybe)
29+
import Effect (Effect)
30+
import Effect.Uncurried (EffectFn6, runEffectFn6)
2631
import Node.Buffer.Types (BufferValueType, Octet, Offset)
2732
import Node.Encoding (Encoding, encodingToNode)
33+
import Partial.Unsafe (unsafeCrashWith)
2834

2935
-- | An immutable buffer that exists independently of any memory region or effect.
3036
foreign import data ImmutableBuffer :: Type
@@ -48,23 +54,35 @@ instance ordBuffer :: Ord ImmutableBuffer where
4854

4955
foreign import compareImpl :: Fn2 ImmutableBuffer ImmutableBuffer Int
5056

57+
-- | Creates a new buffer of the specified size. Alias for `alloc`.
58+
create :: Int -> ImmutableBuffer
59+
create = alloc
60+
5161
-- | Creates a new buffer of the specified size.
52-
foreign import create :: Int -> ImmutableBuffer
62+
foreign import alloc :: Int -> ImmutableBuffer
5363

5464
-- | Creates a new buffer from an array of octets, sized to match the array.
5565
foreign import fromArray :: Array Octet -> ImmutableBuffer
5666

5767
-- | Creates a buffer view from a JS ArrayByffer without copying data.
58-
--
59-
-- Requires Node >= v5.10.0
6068
foreign import fromArrayBuffer :: ArrayBuffer -> ImmutableBuffer
6169

6270
-- | Creates a new buffer from a string with the specified encoding, sized to match the string.
6371
fromString :: String -> Encoding -> ImmutableBuffer
64-
fromString str = runFn2 fromStringImpl str <<< encodingToNode
72+
fromString str enc = runFn2 fromStringImpl str $ encodingToNode enc
6573

6674
foreign import fromStringImpl :: Fn2 String String ImmutableBuffer
6775

76+
compareParts :: ImmutableBuffer -> ImmutableBuffer -> Offset -> Offset -> Offset -> Offset -> Effect Ordering
77+
compareParts src target targetStart targetEnd sourceStart sourceEnd =
78+
runEffectFn6 comparePartsImpl src target targetStart targetEnd sourceStart sourceEnd <#> case _ of
79+
-1 -> LT
80+
0 -> EQ
81+
1 -> GT
82+
x -> unsafeCrashWith $ "Impossible: Invalid value: " <> show x
83+
84+
foreign import comparePartsImpl :: EffectFn6 ImmutableBuffer ImmutableBuffer Int Int Int Int Int
85+
6886
-- | Reads a numeric value from a buffer at the specified offset.
6987
read :: BufferValueType -> Offset -> ImmutableBuffer -> Number
7088
read ty off buf = runFn3 readImpl (show ty) off buf
@@ -83,6 +101,11 @@ toString enc buf = runFn2 toStringImpl (encodingToNode enc) buf
83101

84102
foreign import toStringImpl :: Fn2 String ImmutableBuffer String
85103

104+
toString' :: Encoding -> Offset -> Offset -> ImmutableBuffer -> String
105+
toString' enc start end buf = runFn4 toStringSubImpl enc start end buf
106+
107+
foreign import toStringSubImpl :: Fn4 Encoding Offset Offset ImmutableBuffer String
108+
86109
-- | Creates an array of octets from a buffer's contents.
87110
foreign import toArray :: ImmutableBuffer -> Array Octet
88111

0 commit comments

Comments
 (0)
Please sign in to comment.