1- import type { BSONSerializeOptions , Document , Long } from '../bson' ;
2- import * as BSON from '../bson' ;
1+ import {
2+ allocateBuffer ,
3+ allocateUnsafeBuffer ,
4+ BSON ,
5+ type BSONSerializeOptions ,
6+ concatBuffers ,
7+ type Document ,
8+ type Long ,
9+ readInt32LE ,
10+ utf8ByteLength ,
11+ writeInt32LE
12+ } from '../bson' ;
313import { MongoInvalidArgumentError , MongoRuntimeError } from '../error' ;
414import { type ReadPreference } from '../read_preference' ;
515import type { ClientSession } from '../sessions' ;
@@ -30,7 +40,7 @@ const QUERY_FAILURE = 2;
3040const SHARD_CONFIG_STALE = 4 ;
3141const AWAIT_CAPABLE = 8 ;
3242
33- const encodeUTF8Into = BSON . BSON . onDemand . ByteUtils . encodeUTF8Into ;
43+ const encodeUTF8Into = BSON . onDemand . ByteUtils . encodeUTF8Into ;
3444
3545/** @internal */
3646export type WriteProtocolMessageType = OpQueryRequest | OpMsgRequest ;
@@ -182,10 +192,10 @@ export class OpQueryRequest {
182192 if ( this . batchSize !== this . numberToReturn ) this . numberToReturn = this . batchSize ;
183193
184194 // Allocate write protocol header buffer
185- const header = Buffer . alloc (
195+ const header = allocateBuffer (
186196 4 * 4 + // Header
187197 4 + // Flags
188- Buffer . byteLength ( this . ns ) +
198+ utf8ByteLength ( this . ns ) +
189199 1 + // namespace
190200 4 + // numberToSkip
191201 4 // numberToReturn
@@ -256,7 +266,7 @@ export class OpQueryRequest {
256266 index = index + 4 ;
257267
258268 // Write collection name
259- index = index + header . write ( this . ns , index , 'utf8' ) + 1 ;
269+ index = index + encodeUTF8Into ( header , this . ns , index ) + 1 ;
260270 header [ index - 1 ] = 0 ;
261271
262272 // Write header information flags numberToSkip
@@ -364,10 +374,10 @@ export class OpReply {
364374 this . index = 20 ;
365375
366376 // Read the message body
367- this . responseFlags = this . data . readInt32LE ( 0 ) ;
368- this . cursorId = new BSON . Long ( this . data . readInt32LE ( 4 ) , this . data . readInt32LE ( 8 ) ) ;
369- this . startingFrom = this . data . readInt32LE ( 12 ) ;
370- this . numberReturned = this . data . readInt32LE ( 16 ) ;
377+ this . responseFlags = readInt32LE ( this . data , 0 ) ;
378+ this . cursorId = new BSON . Long ( readInt32LE ( this . data , 4 ) , readInt32LE ( this . data , 8 ) ) ;
379+ this . startingFrom = readInt32LE ( this . data , 12 ) ;
380+ this . numberReturned = readInt32LE ( this . data , 16 ) ;
371381
372382 if ( this . numberReturned < 0 || this . numberReturned > 2 ** 32 - 1 ) {
373383 throw new RangeError (
@@ -446,7 +456,7 @@ export class DocumentSequence {
446456 this . serializedDocumentsLength = 0 ;
447457 // Document sequences starts with type 1 at the first byte.
448458 // Field strings must always be UTF-8.
449- const buffer = Buffer . allocUnsafe ( 1 + 4 + this . field . length + 1 ) ;
459+ const buffer = allocateUnsafeBuffer ( 1 + 4 + this . field . length + 1 ) ;
450460 buffer [ 0 ] = 1 ;
451461 // Third part is the field name at offset 5 with trailing null byte.
452462 encodeUTF8Into ( buffer , `${ this . field } \0` , 5 ) ;
@@ -482,7 +492,7 @@ export class DocumentSequence {
482492 * @returns The section bytes.
483493 */
484494 toBin ( ) : Uint8Array {
485- return Buffer . concat ( this . chunks ) ;
495+ return concatBuffers ( this . chunks ) ;
486496 }
487497}
488498
@@ -547,7 +557,7 @@ export class OpMsgRequest {
547557 flags |= OPTS_EXHAUST_ALLOWED ;
548558 }
549559
550- const header = Buffer . alloc (
560+ const header = allocateBuffer (
551561 4 * 4 + // Header
552562 4 // Flags
553563 ) ;
@@ -558,11 +568,11 @@ export class OpMsgRequest {
558568 const command = this . command ;
559569 totalLength += this . makeSections ( buffers , command ) ;
560570
561- header . writeInt32LE ( totalLength , 0 ) ; // messageLength
562- header . writeInt32LE ( this . requestId , 4 ) ; // requestID
563- header . writeInt32LE ( 0 , 8 ) ; // responseTo
564- header . writeInt32LE ( OP_MSG , 12 ) ; // opCode
565- header . writeUInt32LE ( flags , 16 ) ; // flags
571+ writeInt32LE ( header , 0 , totalLength ) ; // messageLength
572+ writeInt32LE ( header , 4 , this . requestId ) ; // requestID
573+ writeInt32LE ( header , 8 , 0 ) ; // responseTo
574+ writeInt32LE ( header , 12 , OP_MSG ) ; // opCode
575+ writeInt32LE ( header , 16 , flags ) ; // flags
566576 return buffers ;
567577 }
568578
@@ -571,7 +581,7 @@ export class OpMsgRequest {
571581 */
572582 makeSections ( buffers : Uint8Array [ ] , document : Document ) : number {
573583 const sequencesBuffer = this . extractDocumentSequences ( document ) ;
574- const payloadTypeBuffer = Buffer . allocUnsafe ( 1 ) ;
584+ const payloadTypeBuffer = allocateUnsafeBuffer ( 1 ) ;
575585 payloadTypeBuffer [ 0 ] = 0 ;
576586
577587 const documentBuffer = this . serializeBson ( document ) ;
@@ -606,11 +616,11 @@ export class OpMsgRequest {
606616 }
607617 }
608618 if ( chunks . length > 0 ) {
609- return Buffer . concat ( chunks ) ;
619+ return concatBuffers ( chunks ) ;
610620 }
611621 // If we have no document sequences we return an empty buffer for nothing to add
612622 // to the payload.
613- return Buffer . alloc ( 0 ) ;
623+ return allocateBuffer ( 0 ) ;
614624 }
615625
616626 serializeBson ( document : Document ) : Uint8Array {
@@ -676,7 +686,7 @@ export class OpMsgResponse {
676686 this . fromCompressed = msgHeader . fromCompressed ;
677687
678688 // Read response flags
679- this . responseFlags = msgBody . readInt32LE ( 0 ) ;
689+ this . responseFlags = readInt32LE ( msgBody , 0 ) ;
680690 this . checksumPresent = ( this . responseFlags & OPTS_CHECKSUM_PRESENT ) !== 0 ;
681691 this . moreToCome = ( this . responseFlags & OPTS_MORE_TO_COME ) !== 0 ;
682692 this . exhaustAllowed = ( this . responseFlags & OPTS_EXHAUST_ALLOWED ) !== 0 ;
@@ -700,9 +710,9 @@ export class OpMsgResponse {
700710 this . index = 4 ;
701711
702712 while ( this . index < this . data . length ) {
703- const payloadType = this . data . readUInt8 ( this . index ++ ) ;
713+ const payloadType = this . data [ this . index ++ ] ;
704714 if ( payloadType === 0 ) {
705- const bsonSize = this . data . readUInt32LE ( this . index ) ;
715+ const bsonSize = readInt32LE ( this . data , this . index ) ;
706716 const bin = this . data . subarray ( this . index , this . index + bsonSize ) ;
707717
708718 this . sections . push ( bin ) ;
@@ -759,30 +769,31 @@ export class OpCompressedRequest {
759769 }
760770
761771 async toBin ( ) : Promise < Buffer [ ] > {
762- const concatenatedOriginalCommandBuffer = Buffer . concat ( this . command . toBin ( ) ) ;
772+ const concatenatedOriginalCommandBuffer = concatBuffers ( this . command . toBin ( ) ) ;
763773 // otherwise, compress the message
764774 const messageToBeCompressed = concatenatedOriginalCommandBuffer . slice ( MESSAGE_HEADER_SIZE ) ;
765775
766776 // Extract information needed for OP_COMPRESSED from the uncompressed message
767- const originalCommandOpCode = concatenatedOriginalCommandBuffer . readInt32LE ( 12 ) ;
777+ const originalCommandOpCode = readInt32LE ( concatenatedOriginalCommandBuffer , 12 ) ;
768778
769779 // Compress the message body
770780 const compressedMessage = await compress ( this . options , messageToBeCompressed ) ;
771781 // Create the msgHeader of OP_COMPRESSED
772- const msgHeader = Buffer . alloc ( MESSAGE_HEADER_SIZE ) ;
773- msgHeader . writeInt32LE (
774- MESSAGE_HEADER_SIZE + COMPRESSION_DETAILS_SIZE + compressedMessage . length ,
775- 0
782+ const msgHeader = allocateBuffer ( MESSAGE_HEADER_SIZE ) ;
783+ writeInt32LE (
784+ msgHeader ,
785+ 0 ,
786+ MESSAGE_HEADER_SIZE + COMPRESSION_DETAILS_SIZE + compressedMessage . length
776787 ) ; // messageLength
777- msgHeader . writeInt32LE ( this . command . requestId , 4 ) ; // requestID
778- msgHeader . writeInt32LE ( 0 , 8 ) ; // responseTo (zero)
779- msgHeader . writeInt32LE ( OP_COMPRESSED , 12 ) ; // opCode
788+ writeInt32LE ( msgHeader , 4 , this . command . requestId ) ; // requestID
789+ writeInt32LE ( msgHeader , 8 , 0 ) ; // responseTo (zero)
790+ writeInt32LE ( msgHeader , 12 , OP_COMPRESSED ) ; // opCode
780791
781792 // Create the compression details of OP_COMPRESSED
782- const compressionDetails = Buffer . alloc ( COMPRESSION_DETAILS_SIZE ) ;
783- compressionDetails . writeInt32LE ( originalCommandOpCode , 0 ) ; // originalOpcode
784- compressionDetails . writeInt32LE ( messageToBeCompressed . length , 4 ) ; // Size of the uncompressed compressedMessage, excluding the MsgHeader
785- compressionDetails . writeUInt8 ( Compressor [ this . options . agreedCompressor ] , 8 ) ; // compressorID
793+ const compressionDetails = allocateBuffer ( COMPRESSION_DETAILS_SIZE ) ;
794+ writeInt32LE ( compressionDetails , 0 , originalCommandOpCode ) ; // originalOpcode
795+ writeInt32LE ( compressionDetails , 4 , messageToBeCompressed . length ) ; // Size of the uncompressed compressedMessage, excluding the MsgHeader
796+ writeInt32LE ( compressionDetails , 8 , Compressor [ this . options . agreedCompressor ] ) ; // compressorID
786797 return [ msgHeader , compressionDetails , compressedMessage ] ;
787798 }
788799}
0 commit comments