@@ -169,9 +169,86 @@ Msg.getRequestId = function() {
169169 return ++ _requestId ;
170170} ;
171171
172+ class BinMsg {
173+ constructor ( bson , message , msgHeader , msgBody , opts ) {
174+ opts = opts || { promoteLongs : true , promoteValues : true , promoteBuffers : false } ;
175+ this . parsed = false ;
176+ this . raw = message ;
177+ this . data = msgBody ;
178+ this . bson = bson ;
179+ this . opts = opts ;
180+
181+ // Read the message header
182+ this . length = msgHeader . length ;
183+ this . requestId = msgHeader . requestId ;
184+ this . responseTo = msgHeader . responseTo ;
185+ this . opCode = msgHeader . opCode ;
186+
187+ // Read response flags
188+ this . responseFlags = msgBody . readInt32LE ( 0 ) ;
189+ this . checksumPresent = ( this . responseFlags & Msg . flags . CHECKSUM_PRESENT ) !== 0 ;
190+ this . moreToCome = ( this . responseFlags & Msg . flags . MORE_TO_COME ) !== 0 ;
191+ this . exhaustAllowed = ( this . responseFlags & Msg . flags . EXHAUST_ALLOWED ) !== 0 ;
192+ this . promoteLongs = typeof opts . promoteLongs === 'boolean' ? opts . promoteLongs : true ;
193+ this . promoteValues = typeof opts . promoteValues === 'boolean' ? opts . promoteValues : true ;
194+ this . promoteBuffers = typeof opts . promoteBuffers === 'boolean' ? opts . promoteBuffers : false ;
195+
196+ this . documents = [ ] ;
197+ }
198+
199+ isParsed ( ) {
200+ return this . parsed ;
201+ }
202+
203+ parse ( options ) {
204+ // Don't parse again if not needed
205+ if ( this . parsed ) return ;
206+ options = options || { } ;
207+
208+ this . index = 4 ;
209+ // Allow the return of raw documents instead of parsing
210+ const raw = options . raw || false ;
211+ const promoteLongs =
212+ typeof options . promoteLongs === 'boolean' ? options . promoteLongs : this . opts . promoteLongs ;
213+ const promoteValues =
214+ typeof options . promoteValues === 'boolean' ? options . promoteValues : this . opts . promoteValues ;
215+ const promoteBuffers =
216+ typeof options . promoteBuffers === 'boolean'
217+ ? options . promoteBuffers
218+ : this . opts . promoteBuffers ;
219+
220+ // Set up the options
221+ const _options = {
222+ promoteLongs : promoteLongs ,
223+ promoteValues : promoteValues ,
224+ promoteBuffers : promoteBuffers
225+ } ;
226+
227+ while ( this . index < this . data . length ) {
228+ const payloadType = this . data . readUInt8 ( this . index ++ ) ;
229+ if ( payloadType === 1 ) {
230+ console . error ( 'TYPE 1' ) ;
231+ } else if ( payloadType === 0 ) {
232+ const bsonSize = this . data . readUInt32LE ( this . index ) ;
233+ const bin = this . data . slice ( this . index , this . index + bsonSize ) ;
234+ this . documents . push ( raw ? bin : this . bson . deserialize ( bin , _options ) ) ;
235+
236+ this . index += bsonSize ;
237+ }
238+ }
239+
240+ this . parsed = true ;
241+ }
242+ }
243+
244+ Msg . flags = {
245+ CHECKSUM_PRESENT : 1 ,
246+ MORE_TO_COME : 2 ,
247+ EXHAUST_ALLOWED : 1 << 16
248+ } ;
249+
172250function writeInt32ListToUint8Buffer ( buffer , int32List , start ) {
173251 let index = start || 0 ;
174-
175252 int32List . forEach ( int32 => {
176253 buffer [ index ] = int32 & 0xff ;
177254 buffer [ index + 1 ] = ( int32 >> 8 ) & 0xff ;
@@ -198,7 +275,8 @@ function getValidSegmentListNamePairs(query) {
198275 }
199276 }
200277 }
278+
201279 return false ;
202280}
203281
204- module . exports = { Msg } ;
282+ module . exports = { Msg, BinMsg } ;
0 commit comments