@@ -81,17 +81,63 @@ Packet.prototype.readSInt32 = function ()
81
81
return this . buffer . readInt32LE ( this . offset - 4 , true ) ;
82
82
} ;
83
83
84
- Packet . prototype . readInt64 = function ( ) {
85
- return this . readInt32 ( ) + 0x100000000 * this . readInt32 ( ) ;
84
+ Packet . prototype . readInt64JSNumber = function ( ) {
85
+ var word0 = this . readInt32 ( ) ;
86
+ var word1 = this . readInt32 ( ) ;
87
+ var l = new Long ( word0 , word1 , true ) ;
88
+ return l . toNumber ( ) ;
86
89
} ;
87
90
88
- Packet . prototype . readSInt64 = function ( ) {
91
+ Packet . prototype . readSInt64JSNumber = function ( ) {
89
92
var word0 = this . readInt32 ( ) ;
90
93
var word1 = this . readInt32 ( ) ;
91
94
if ( ! ( word1 & 0x80000000 ) ) {
92
95
return word0 + 0x100000000 * word1 ;
93
96
}
94
- return - ( ( ( ( ~ word1 ) >>> 0 ) * 0x100000000 ) + ( ( ~ word0 ) >>> 0 ) + 1 ) ;
97
+ var l = new Long ( word0 , word1 , false ) ;
98
+ return l . toNumber ( ) ;
99
+ } ;
100
+
101
+ Packet . prototype . readInt64String = function ( ) {
102
+ var word0 = this . readInt32 ( ) ;
103
+ var word1 = this . readInt32 ( ) ;
104
+ var res = new Long ( word0 , word1 , true ) ;
105
+ return res . toString ( ) ;
106
+ } ;
107
+
108
+ Packet . prototype . readSInt64String = function ( ) {
109
+ var word0 = this . readInt32 ( ) ;
110
+ var word1 = this . readInt32 ( ) ;
111
+ var res = new Long ( word0 , word1 , false ) ;
112
+ return res . toString ( ) ;
113
+ } ;
114
+
115
+ Packet . prototype . readInt64 = function ( ) {
116
+ var word0 = this . readInt32 ( ) ;
117
+ var word1 = this . readInt32 ( ) ;
118
+ var res = new Long ( word0 , word1 , true ) ;
119
+ var resNumber = res . toNumber ( )
120
+ , resString = res . toString ( ) ;
121
+
122
+ res = resNumber . toString ( ) === resString
123
+ ? resNumber
124
+ : resString ;
125
+
126
+ return res ;
127
+ } ;
128
+
129
+ Packet . prototype . readSInt64 = function ( ) {
130
+ var word0 = this . readInt32 ( ) ;
131
+ var word1 = this . readInt32 ( ) ;
132
+ var res = new Long ( word0 , word1 , false ) ;
133
+ var resNumber = res . toNumber ( )
134
+ , resString = res . toString ( ) ;
135
+
136
+ res = resNumber . toString ( ) === resString
137
+ ? resNumber
138
+ : resString ;
139
+
140
+ return res ;
95
141
} ;
96
142
97
143
Packet . prototype . isEOF = function ( ) {
@@ -330,15 +376,29 @@ Packet.prototype.readString = function (len) {
330
376
331
377
var minus = '-' . charCodeAt ( 0 ) ;
332
378
var plus = '+' . charCodeAt ( 0 ) ;
333
- // TODO: faster versions of parseInt for smaller types?
334
- // discard overflow checks if we know from type definition it's safe so
335
- Packet . prototype . parseInt = function ( len ) {
379
+
380
+ // The whole reason parse* function below exist
381
+ // is because String creation is relatively expensive, and if we have
382
+ // a buffer with "12345" content ideally we would like to bypass intermediate
383
+ // "12345" string creation and directly build 12345 number out of
384
+ // <Buffer 31 32 33 34 35> data.
385
+ // In my benchmarks "parse" methods
386
+
387
+
388
+ Packet . prototype . parseInt = function ( len , supportBigNumbers ) {
336
389
337
390
if ( len === null ) {
338
391
return null ;
339
392
}
340
393
394
+ if ( len >= 14 && ! supportBigNumbers ) {
395
+ var s = this . buffer . toString ( 'ascii' , this . offset , this . offset + len ) ;
396
+ this . offset += len ;
397
+ return Number ( s ) ;
398
+ }
399
+
341
400
var result = 0 ;
401
+ var start = this . offset ;
342
402
var end = this . offset + len ;
343
403
var sign = 1 ;
344
404
if ( len === 0 ) {
@@ -351,23 +411,62 @@ Packet.prototype.parseInt = function (len) {
351
411
}
352
412
353
413
// max precise int is 9007199254740992
354
- // note that we are here after handling optional +/-
355
- // treat everything above 9000000000000000 as potential overflow
356
414
var str ;
357
415
var numDigits = end - this . offset ;
358
- if ( numDigits == 16 && ( this . buffer [ this . offset ] - 48 ) > 8 ) {
359
- str = this . readString ( end - this . offset ) ;
360
- result = parseInt ( str , 10 ) ;
361
- if ( result . toString ( ) == str ) {
362
- return sign * result ;
363
- } else {
416
+ if ( supportBigNumbers ) {
417
+ if ( numDigits >= 15 ) {
418
+ str = this . readString ( end - this . offset ) ;
419
+ result = parseInt ( str , 10 ) ;
420
+ if ( result . toString ( ) == str ) {
421
+ return sign * result ;
422
+ } else {
423
+ return sign == - 1 ? '-' + str : str ;
424
+ }
425
+ } else if ( numDigits > 16 ) {
426
+ str = this . readString ( end - this . offset ) ;
364
427
return sign == - 1 ? '-' + str : str ;
365
428
}
366
- } else if ( numDigits > 16 ) {
367
- str = this . readString ( end - this . offset ) ;
368
- return sign == - 1 ? '-' + str : str ;
369
429
}
370
430
431
+ if ( this . buffer [ this . offset ] == plus ) {
432
+ this . offset ++ ; // just ignore
433
+ }
434
+ while ( this . offset < end ) {
435
+ result *= 10 ;
436
+ result += this . buffer [ this . offset ] - 48 ;
437
+ this . offset ++ ;
438
+ }
439
+ var num = result * sign ;
440
+ if ( ! supportBigNumbers ) {
441
+ return num ;
442
+ }
443
+ str = this . buffer . toString ( 'ascii' , start , end ) ;
444
+ if ( num . toString ( ) == str ) {
445
+ return num ;
446
+ } else {
447
+ return str ;
448
+ }
449
+ } ;
450
+
451
+ // note that if value of inputNumberAsString is bigger than MAX_SAFE_INTEGER
452
+ // ( or smaller than MIN_SAFE_INTEGER ) the parseIntNoBigCheck result might be
453
+ // different from what you would get from Number(inputNumberAsString)
454
+ // String(parseIntNoBigCheck) <> String(Number(inputNumberAsString)) <> inputNumberAsString
455
+ Packet . prototype . parseIntNoBigCheck = function ( len ) {
456
+ if ( len === null ) {
457
+ return null ;
458
+ }
459
+ var result = 0 ;
460
+ var end = this . offset + len ;
461
+ var sign = 1 ;
462
+ if ( len === 0 ) {
463
+ return 0 ; // TODO: assert? exception?
464
+ }
465
+
466
+ if ( this . buffer [ this . offset ] == minus ) {
467
+ this . offset ++ ;
468
+ sign = - 1 ;
469
+ }
371
470
if ( this . buffer [ this . offset ] == plus ) {
372
471
this . offset ++ ; // just ignore
373
472
}
@@ -515,8 +614,12 @@ Packet.prototype.parseFloat = function (len) {
515
614
return result / factor ;
516
615
} ;
517
616
518
- Packet . prototype . parseLengthCodedInt = function ( ) {
519
- return this . parseInt ( this . readLengthCodedNumber ( ) ) ;
617
+ Packet . prototype . parseLengthCodedIntNoBigCheck = function ( ) {
618
+ return this . parseIntNoBigCheck ( this . readLengthCodedNumber ( ) ) ;
619
+ } ;
620
+
621
+ Packet . prototype . parseLengthCodedInt = function ( supportBigNumbers ) {
622
+ return this . parseInt ( this . readLengthCodedNumber ( ) , supportBigNumbers ) ;
520
623
} ;
521
624
522
625
Packet . prototype . parseLengthCodedIntString = function ( ) {
0 commit comments