15
15
*/
16
16
17
17
const stringToByteArray = function ( str ) {
18
- var output = [ ] ,
18
+ // TODO(user): Use native implementations if/when available
19
+ var out = [ ] ,
19
20
p = 0 ;
20
21
for ( var i = 0 ; i < str . length ; i ++ ) {
21
22
var c = str . charCodeAt ( i ) ;
22
- while ( c > 255 ) {
23
- output [ p ++ ] = c & 255 ;
24
- c >>= 8 ;
23
+ if ( c < 128 ) {
24
+ out [ p ++ ] = c ;
25
+ } else if ( c < 2048 ) {
26
+ out [ p ++ ] = ( c >> 6 ) | 192 ;
27
+ out [ p ++ ] = ( c & 63 ) | 128 ;
28
+ } else if (
29
+ ( c & 0xfc00 ) == 0xd800 &&
30
+ i + 1 < str . length &&
31
+ ( str . charCodeAt ( i + 1 ) & 0xfc00 ) == 0xdc00
32
+ ) {
33
+ // Surrogate Pair
34
+ c = 0x10000 + ( ( c & 0x03ff ) << 10 ) + ( str . charCodeAt ( ++ i ) & 0x03ff ) ;
35
+ out [ p ++ ] = ( c >> 18 ) | 240 ;
36
+ out [ p ++ ] = ( ( c >> 12 ) & 63 ) | 128 ;
37
+ out [ p ++ ] = ( ( c >> 6 ) & 63 ) | 128 ;
38
+ out [ p ++ ] = ( c & 63 ) | 128 ;
39
+ } else {
40
+ out [ p ++ ] = ( c >> 12 ) | 224 ;
41
+ out [ p ++ ] = ( ( c >> 6 ) & 63 ) | 128 ;
42
+ out [ p ++ ] = ( c & 63 ) | 128 ;
25
43
}
26
- output [ p ++ ] = c ;
27
44
}
28
- return output ;
45
+ return out ;
29
46
} ;
30
47
31
48
/**
@@ -35,23 +52,36 @@ const stringToByteArray = function(str) {
35
52
* @return {string } Stringification of the array.
36
53
*/
37
54
const byteArrayToString = function ( bytes ) {
38
- var CHUNK_SIZE = 8192 ;
39
-
40
- // Special-case the simple case for speed's sake.
41
- if ( bytes . length < CHUNK_SIZE ) {
42
- return String . fromCharCode . apply ( null , bytes ) ;
43
- }
44
-
45
- // The remaining logic splits conversion by chunks since
46
- // Function#apply() has a maximum parameter count.
47
- // See discussion: http://goo.gl/LrWmZ9
48
-
49
- var str = '' ;
50
- for ( var i = 0 ; i < bytes . length ; i += CHUNK_SIZE ) {
51
- var chunk = bytes . slice ( i , i + CHUNK_SIZE ) ;
52
- str += String . fromCharCode . apply ( null , chunk ) ;
55
+ // TODO(user): Use native implementations if/when available
56
+ var out = [ ] ,
57
+ pos = 0 ,
58
+ c = 0 ;
59
+ while ( pos < bytes . length ) {
60
+ var c1 = bytes [ pos ++ ] ;
61
+ if ( c1 < 128 ) {
62
+ out [ c ++ ] = String . fromCharCode ( c1 ) ;
63
+ } else if ( c1 > 191 && c1 < 224 ) {
64
+ var c2 = bytes [ pos ++ ] ;
65
+ out [ c ++ ] = String . fromCharCode ( ( ( c1 & 31 ) << 6 ) | ( c2 & 63 ) ) ;
66
+ } else if ( c1 > 239 && c1 < 365 ) {
67
+ // Surrogate Pair
68
+ var c2 = bytes [ pos ++ ] ;
69
+ var c3 = bytes [ pos ++ ] ;
70
+ var c4 = bytes [ pos ++ ] ;
71
+ var u =
72
+ ( ( ( c1 & 7 ) << 18 ) | ( ( c2 & 63 ) << 12 ) | ( ( c3 & 63 ) << 6 ) | ( c4 & 63 ) ) -
73
+ 0x10000 ;
74
+ out [ c ++ ] = String . fromCharCode ( 0xd800 + ( u >> 10 ) ) ;
75
+ out [ c ++ ] = String . fromCharCode ( 0xdc00 + ( u & 1023 ) ) ;
76
+ } else {
77
+ var c2 = bytes [ pos ++ ] ;
78
+ var c3 = bytes [ pos ++ ] ;
79
+ out [ c ++ ] = String . fromCharCode (
80
+ ( ( c1 & 15 ) << 12 ) | ( ( c2 & 63 ) << 6 ) | ( c3 & 63 )
81
+ ) ;
82
+ }
53
83
}
54
- return str ;
84
+ return out . join ( '' ) ;
55
85
} ;
56
86
57
87
// Static lookup maps, lazily populated by init_()
0 commit comments