Remove internal `utf8` utility
Summary: As requested by davidaurelio in https://github.com/mathiasbynens/utf8.js/issues/17#issuecomment-312500535, this makes it possible for developers to use the `utf8` package from npm in combination with React Native. Ref. https://github.com/mathiasbynens/utf8.js/issues/17 Closes https://github.com/facebook/react-native/pull/17146 Differential Revision: D6765030 Pulled By: hramos fbshipit-source-id: dda9b3255618470aea2e32c5ba3cf1325e2ec997
This commit is contained in:
parent
3c2bb3e90a
commit
431670f908
|
@ -1,63 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2016-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {encode} = require('../utf8');
|
||||
|
||||
describe('UTF-8 encoding:', () => {
|
||||
it('can encode code points < U+80', () => {
|
||||
const arrayBuffer = encode('\u0000abcDEF\u007f');
|
||||
expect(new Uint8Array(arrayBuffer)).toEqual(
|
||||
new Uint8Array([0x00, 0x61, 0x62, 0x63, 0x44, 0x45, 0x46, 0x7f]));
|
||||
});
|
||||
|
||||
it('can encode code points < U+800', () => {
|
||||
const arrayBuffer = encode('\u0080\u0548\u07ff');
|
||||
expect(new Uint8Array(arrayBuffer)).toEqual(
|
||||
new Uint8Array([0xc2, 0x80, 0xd5, 0x88, 0xdf, 0xbf]));
|
||||
});
|
||||
|
||||
it('can encode code points < U+10000', () => {
|
||||
const arrayBuffer = encode('\u0800\uac48\uffff');
|
||||
expect(new Uint8Array(arrayBuffer)).toEqual(
|
||||
new Uint8Array([0xe0, 0xa0, 0x80, 0xea, 0xb1, 0x88, 0xef, 0xbf, 0xbf]));
|
||||
});
|
||||
|
||||
it('can encode code points in the Supplementary Planes (surrogate pairs)', () => {
|
||||
const arrayBuffer = encode([
|
||||
'\ud800\udc00',
|
||||
'\ud800\ude89',
|
||||
'\ud83d\ude3b',
|
||||
'\udbff\udfff'
|
||||
].join(''));
|
||||
expect(new Uint8Array(arrayBuffer)).toEqual(
|
||||
new Uint8Array([
|
||||
0xf0, 0x90, 0x80, 0x80,
|
||||
0xf0, 0x90, 0x8a, 0x89,
|
||||
0xf0, 0x9f, 0x98, 0xbb,
|
||||
0xf4, 0x8f, 0xbf, 0xbf,
|
||||
])
|
||||
);
|
||||
});
|
||||
|
||||
it('allows for stray high surrogates', () => {
|
||||
const arrayBuffer = encode(String.fromCharCode(0x61, 0xd8c6, 0x62));
|
||||
expect(new Uint8Array(arrayBuffer)).toEqual(
|
||||
new Uint8Array([0x61, 0xed, 0xa3, 0x86, 0x62]));
|
||||
});
|
||||
|
||||
it('allows for stray low surrogates', () => {
|
||||
const arrayBuffer = encode(String.fromCharCode(0x61, 0xde19, 0x62));
|
||||
expect(new Uint8Array(arrayBuffer)).toEqual(
|
||||
new Uint8Array([0x61, 0xed, 0xb8, 0x99, 0x62]));
|
||||
});
|
||||
});
|
|
@ -1,91 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2016-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule utf8
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
class ByteVector {
|
||||
_storage: Uint8Array;
|
||||
_sizeWritten: number;
|
||||
|
||||
constructor(size) {
|
||||
this._storage = new Uint8Array(size);
|
||||
this._sizeWritten = 0;
|
||||
}
|
||||
|
||||
push(value: number): ByteVector {
|
||||
const i = this._sizeWritten;
|
||||
if (i === this._storage.length) {
|
||||
this._realloc();
|
||||
}
|
||||
this._storage[i] = value;
|
||||
this._sizeWritten = i + 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
getBuffer(): ArrayBuffer {
|
||||
return this._storage.buffer.slice(0, this._sizeWritten);
|
||||
}
|
||||
|
||||
_realloc() {
|
||||
const storage = this._storage;
|
||||
this._storage = new Uint8Array(align(storage.length * 1.5));
|
||||
this._storage.set(storage);
|
||||
}
|
||||
}
|
||||
|
||||
/*eslint-disable no-bitwise */
|
||||
exports.encode = (string: string): ArrayBuffer => {
|
||||
const {length} = string;
|
||||
const bytes = new ByteVector(length);
|
||||
|
||||
// each character / char code is assumed to represent an UTF-16 wchar.
|
||||
// With the notable exception of surrogate pairs, each wchar represents the
|
||||
// corresponding unicode code point.
|
||||
// For an explanation of UTF-8 encoding, read [1]
|
||||
// For an explanation of UTF-16 surrogate pairs, read [2]
|
||||
//
|
||||
// [1] https://en.wikipedia.org/wiki/UTF-8#Description
|
||||
// [2] https://en.wikipedia.org/wiki/UTF-16#U.2B10000_to_U.2B10FFFF
|
||||
let nextCodePoint = string.charCodeAt(0);
|
||||
for (let i = 0; i < length; i++) {
|
||||
let codePoint = nextCodePoint;
|
||||
nextCodePoint = string.charCodeAt(i + 1);
|
||||
|
||||
if (codePoint < 0x80) {
|
||||
bytes.push(codePoint);
|
||||
} else if (codePoint < 0x800) {
|
||||
bytes
|
||||
.push(0xc0 | codePoint >>> 6)
|
||||
.push(0x80 | codePoint & 0x3f);
|
||||
} else if (codePoint >>> 10 === 0x36 && nextCodePoint >>> 10 === 0x37) { // high surrogate & low surrogate
|
||||
codePoint = 0x10000 + (((codePoint & 0x3ff) << 10) | (nextCodePoint & 0x3ff));
|
||||
bytes
|
||||
.push(0xf0 | codePoint >>> 18 & 0x7)
|
||||
.push(0x80 | codePoint >>> 12 & 0x3f)
|
||||
.push(0x80 | codePoint >>> 6 & 0x3f)
|
||||
.push(0x80 | codePoint & 0x3f);
|
||||
|
||||
i += 1;
|
||||
nextCodePoint = string.charCodeAt(i + 1);
|
||||
} else {
|
||||
bytes
|
||||
.push(0xe0 | codePoint >>> 12)
|
||||
.push(0x80 | codePoint >>> 6 & 0x3f)
|
||||
.push(0x80 | codePoint & 0x3f);
|
||||
}
|
||||
}
|
||||
return bytes.getBuffer();
|
||||
};
|
||||
|
||||
// align to multiples of 8 bytes
|
||||
function align(size: number): number {
|
||||
return size % 8 ? (Math.floor(size / 8) + 1) << 3 : size;
|
||||
}
|
Loading…
Reference in New Issue