Skip to content

Commit 12ff51f

Browse files
committed
add an easy-to-use copyBuffer method
1 parent e649b6f commit 12ff51f

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

src/bson.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,23 @@ export const allocateBuffer = (size: number) =>
6565
ByteUtils.toLocalBufferType(BSON.ByteUtils.allocate(size));
6666
export const allocateUnsafeBuffer = (size: number) =>
6767
ByteUtils.toLocalBufferType(BSON.ByteUtils.allocateUnsafe(size));
68+
export const copyBuffer = (input: {
69+
source: Uint8Array;
70+
target: Uint8Array;
71+
targetStart?: number;
72+
sourceStart?: number;
73+
sourceEnd?: number;
74+
}): number => {
75+
const { source, target, targetStart = 0, sourceStart = 0, sourceEnd } = input;
76+
const sourceEndActual = sourceEnd ?? source.length;
77+
const srcSlice = source.subarray(sourceStart, sourceEndActual);
78+
const maxLen = Math.min(srcSlice.length, target.length - targetStart);
79+
if (maxLen <= 0) {
80+
return 0;
81+
}
82+
target.set(srcSlice.subarray(0, maxLen), targetStart);
83+
return maxLen;
84+
};
6885

6986
// validates buffer inputs, used for read operations
7087
const validateBufferInputs = (buffer: Uint8Array, offset: number, length: number) => {

src/gridfs/upload.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Writable } from 'stream';
22

3-
import { allocateBuffer, ByteUtils, type Document, fromUTF8, ObjectId } from '../bson';
3+
import { allocateBuffer, ByteUtils, copyBuffer, type Document, fromUTF8, ObjectId } from '../bson';
44
import type { Collection } from '../collection';
55
import { CursorTimeoutMode } from '../cursor/abstract_cursor';
66
import {
@@ -426,7 +426,11 @@ function doWrite(
426426

427427
// Input is small enough to fit in our buffer
428428
if (stream.pos + inputBuf.length < stream.chunkSizeBytes) {
429-
inputBuf.set(stream.bufToStore, stream.pos);
429+
copyBuffer({
430+
source: inputBuf,
431+
target: stream.bufToStore,
432+
targetStart: stream.pos
433+
});
430434
stream.pos += inputBuf.length;
431435
queueMicrotask(callback);
432436
return;
@@ -440,7 +444,13 @@ function doWrite(
440444
let outstandingRequests = 0;
441445
while (inputBufRemaining > 0) {
442446
const inputBufPos = inputBuf.length - inputBufRemaining;
443-
inputBuf.set(stream.bufToStore.subarray(inputBufPos, inputBufPos + numToCopy), stream.pos);
447+
copyBuffer({
448+
source: inputBuf,
449+
target: stream.bufToStore,
450+
targetStart: stream.pos,
451+
sourceStart: inputBufPos,
452+
sourceEnd: inputBufPos + numToCopy
453+
});
444454
stream.pos += numToCopy;
445455
spaceRemaining -= numToCopy;
446456
let doc: GridFSChunk;
@@ -499,7 +509,13 @@ function writeRemnant(stream: GridFSBucketWriteStream, callback: Callback): void
499509
// Create a new buffer to make sure the buffer isn't bigger than it needs
500510
// to be.
501511
const remnant = allocateBuffer(stream.pos);
502-
remnant.set(stream.bufToStore.subarray(0, stream.pos), 0);
512+
copyBuffer({
513+
source: stream.bufToStore,
514+
target: remnant,
515+
targetStart: 0,
516+
sourceStart: 0,
517+
sourceEnd: stream.pos
518+
});
503519
const doc = createChunkDoc(stream.id, stream.n, remnant);
504520

505521
// If the stream was aborted, do not write remnant

0 commit comments

Comments
 (0)