Skip to content

Commit

Permalink
Use TextDecoder/TextEncoder where available
Browse files Browse the repository at this point in the history
  • Loading branch information
RealDolos committed May 12, 2018
1 parent ed9cb3b commit 9362e00
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 91 deletions.
45 changes: 3 additions & 42 deletions browser/decode.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

var utf8 = require('./utf8');

function Decoder(buffer) {
this.offset = 0;
if (buffer instanceof ArrayBuffer) {
Expand All @@ -13,47 +15,6 @@ function Decoder(buffer) {
}
}

function utf8Read(view, offset, length) {
var string = '', chr = 0;
for (var i = offset, end = offset + length; i < end; i++) {
var byte = view.getUint8(i);
if ((byte & 0x80) === 0x00) {
string += String.fromCharCode(byte);
continue;
}
if ((byte & 0xe0) === 0xc0) {
string += String.fromCharCode(
((byte & 0x1f) << 6) |
(view.getUint8(++i) & 0x3f)
);
continue;
}
if ((byte & 0xf0) === 0xe0) {
string += String.fromCharCode(
((byte & 0x0f) << 12) |
((view.getUint8(++i) & 0x3f) << 6) |
((view.getUint8(++i) & 0x3f) << 0)
);
continue;
}
if ((byte & 0xf8) === 0xf0) {
chr = ((byte & 0x07) << 18) |
((view.getUint8(++i) & 0x3f) << 12) |
((view.getUint8(++i) & 0x3f) << 6) |
((view.getUint8(++i) & 0x3f) << 0);
if (chr >= 0x010000) { // surrogate pair
chr -= 0x010000;
string += String.fromCharCode((chr >>> 10) + 0xD800, (chr & 0x3FF) + 0xDC00);
} else {
string += String.fromCharCode(chr);
}
continue;
}
throw new Error('Invalid byte ' + byte.toString(16));
}
return string;
}

Decoder.prototype.array = function (length) {
var value = new Array(length);
for (var i = 0; i < length; i++) {
Expand All @@ -72,7 +33,7 @@ Decoder.prototype.map = function (length) {
};

Decoder.prototype.str = function (length) {
var value = utf8Read(this.view, this.offset, length);
var value = utf8.read(this.view, this.offset, length);
this.offset += length;
return value;
};
Expand Down
52 changes: 3 additions & 49 deletions browser/encode.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,12 @@
'use strict';

function utf8Write(view, offset, str) {
var c = 0;
for (var i = 0, l = str.length; i < l; i++) {
c = str.charCodeAt(i);
if (c < 0x80) {
view.setUint8(offset++, c);
}
else if (c < 0x800) {
view.setUint8(offset++, 0xc0 | (c >> 6));
view.setUint8(offset++, 0x80 | (c & 0x3f));
}
else if (c < 0xd800 || c >= 0xe000) {
view.setUint8(offset++, 0xe0 | (c >> 12));
view.setUint8(offset++, 0x80 | (c >> 6) & 0x3f);
view.setUint8(offset++, 0x80 | (c & 0x3f));
}
else {
i++;
c = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
view.setUint8(offset++, 0xf0 | (c >> 18));
view.setUint8(offset++, 0x80 | (c >> 12) & 0x3f);
view.setUint8(offset++, 0x80 | (c >> 6) & 0x3f);
view.setUint8(offset++, 0x80 | (c & 0x3f));
}
}
}

function utf8Length(str) {
var c = 0, length = 0;
for (var i = 0, l = str.length; i < l; i++) {
c = str.charCodeAt(i);
if (c < 0x80) {
length += 1;
}
else if (c < 0x800) {
length += 2;
}
else if (c < 0xd800 || c >= 0xe000) {
length += 3;
}
else {
i++;
length += 4;
}
}
return length;
}
var utf8 = require('./utf8');

function _encode(bytes, defers, value) {
var type = typeof value, i = 0, l = 0, hi = 0, lo = 0, length = 0, size = 0;

if (type === 'string') {
length = utf8Length(value);
length = utf8.length(value);

// fixstr
if (length < 0x20) {
Expand Down Expand Up @@ -289,7 +243,7 @@ function encode(value) {
view.setUint8(offset + j, bin[j]);
}
} else if (defer.str) {
utf8Write(view, offset, defer.str);
utf8.write(view, offset, defer.str);
} else if (defer.float !== undefined) {
view.setFloat64(offset, defer.float);
}
Expand Down
114 changes: 114 additions & 0 deletions browser/utf8.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
'use strict';
/* globals TextDecoder, TextEncoder */

var read = function read(view, offset, length) {
var string = '', chr = 0;
for (var i = offset, end = offset + length; i < end; i++) {
var byte = view.getUint8(i);
if ((byte & 0x80) === 0x00) {
string += String.fromCharCode(byte);
continue;
}
if ((byte & 0xe0) === 0xc0) {
string += String.fromCharCode(
((byte & 0x1f) << 6) |
(view.getUint8(++i) & 0x3f)
);
continue;
}
if ((byte & 0xf0) === 0xe0) {
string += String.fromCharCode(
((byte & 0x0f) << 12) |
((view.getUint8(++i) & 0x3f) << 6) |
((view.getUint8(++i) & 0x3f) << 0)
);
continue;
}
if ((byte & 0xf8) === 0xf0) {
chr = ((byte & 0x07) << 18) |
((view.getUint8(++i) & 0x3f) << 12) |
((view.getUint8(++i) & 0x3f) << 6) |
((view.getUint8(++i) & 0x3f) << 0);
if (chr >= 0x010000) { // surrogate pair
chr -= 0x010000;
string += String.fromCharCode((chr >>> 10) + 0xD800, (chr & 0x3FF) + 0xDC00);
} else {
string += String.fromCharCode(chr);
}
continue;
}
throw new Error('Invalid byte ' + byte.toString(16));
}
return string;
};

if (typeof TextDecoder !== 'undefined') {
var decoder = new TextDecoder();
read = function read(view, offset, length) {
var arr = new Uint8Array(view.buffer || view, offset, length);
return decoder.decode(arr);
};
}

var write = function write(view, offset, str) {
var c = 0;
for (var i = 0, l = str.length; i < l; i++) {
c = str.charCodeAt(i);
if (c < 0x80) {
view.setUint8(offset++, c);
}
else if (c < 0x800) {
view.setUint8(offset++, 0xc0 | (c >> 6));
view.setUint8(offset++, 0x80 | (c & 0x3f));
}
else if (c < 0xd800 || c >= 0xe000) {
view.setUint8(offset++, 0xe0 | (c >> 12));
view.setUint8(offset++, 0x80 | (c >> 6) & 0x3f);
view.setUint8(offset++, 0x80 | (c & 0x3f));
}
else {
i++;
c = 0x10000 + (((c & 0x3ff) << 10) | (str.charCodeAt(i) & 0x3ff));
view.setUint8(offset++, 0xf0 | (c >> 18));
view.setUint8(offset++, 0x80 | (c >> 12) & 0x3f);
view.setUint8(offset++, 0x80 | (c >> 6) & 0x3f);
view.setUint8(offset++, 0x80 | (c & 0x3f));
}
}
};

if (typeof TextEncoder !== 'undefined') {
var encoder = new TextEncoder();
write = function write(view, offset, str) {
var arr = new Uint8Array(view.buffer || view, offset);
var encoded = encoder.encode(str);
arr.set(encoded);
};
}

function length(str) {
var c = 0, length = 0;
for (var i = 0, l = str.length; i < l; i++) {
c = str.charCodeAt(i);
if (c < 0x80) {
length += 1;
}
else if (c < 0x800) {
length += 2;
}
else if (c < 0xd800 || c >= 0xe000) {
length += 3;
}
else {
i++;
length += 4;
}
}
return length;
}

module.exports = {
read: read,
write: write,
length: length
};

0 comments on commit 9362e00

Please sign in to comment.