7 changed files with 173 additions and 15 deletions
@ -0,0 +1,138 @@ |
|||||
|
/* |
||||
|
* Copyright © 2016-2017 The Thingsboard Authors |
||||
|
* |
||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
|
* you may not use this file except in compliance with the License. |
||||
|
* You may obtain a copy of the License at |
||||
|
* |
||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
* |
||||
|
* Unless required by applicable law or agreed to in writing, software |
||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
|
* See the License for the specific language governing permissions and |
||||
|
* limitations under the License. |
||||
|
*/ |
||||
|
|
||||
|
export function utf8Encode(str) { |
||||
|
var result; |
||||
|
|
||||
|
if (angular.isUndefined(Uint8Array)) { // eslint-disable-line no-undef
|
||||
|
result = utf8ToBytes(str); |
||||
|
} else { |
||||
|
result = new Uint8Array(utf8ToBytes(str)); // eslint-disable-line no-undef
|
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
export function utf8Decode(bytes) { |
||||
|
return utf8Slice(bytes, 0, bytes.length); |
||||
|
} |
||||
|
|
||||
|
function utf8Slice (buf, start, end) { |
||||
|
var res = '' |
||||
|
var tmp = '' |
||||
|
end = Math.min(buf.length, end || Infinity) |
||||
|
start = start || 0; |
||||
|
|
||||
|
for (var i = start; i < end; i++) { |
||||
|
if (buf[i] <= 0x7F) { |
||||
|
res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) |
||||
|
tmp = '' |
||||
|
} else { |
||||
|
tmp += '%' + buf[i].toString(16) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return res + decodeUtf8Char(tmp) |
||||
|
} |
||||
|
|
||||
|
function decodeUtf8Char (str) { |
||||
|
try { |
||||
|
return decodeURIComponent(str) |
||||
|
} catch (err) { |
||||
|
return String.fromCharCode(0xFFFD) // UTF 8 invalid char
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function utf8ToBytes (string, units) { |
||||
|
units = units || Infinity |
||||
|
var codePoint |
||||
|
var length = string.length |
||||
|
var leadSurrogate = null |
||||
|
var bytes = [] |
||||
|
var i = 0 |
||||
|
|
||||
|
for (; i < length; i++) { |
||||
|
codePoint = string.charCodeAt(i) |
||||
|
|
||||
|
// is surrogate component
|
||||
|
if (codePoint > 0xD7FF && codePoint < 0xE000) { |
||||
|
// last char was a lead
|
||||
|
if (leadSurrogate) { |
||||
|
// 2 leads in a row
|
||||
|
if (codePoint < 0xDC00) { |
||||
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
||||
|
leadSurrogate = codePoint |
||||
|
continue |
||||
|
} else { |
||||
|
// valid surrogate pair
|
||||
|
codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 |
||||
|
leadSurrogate = null |
||||
|
} |
||||
|
} else { |
||||
|
// no lead yet
|
||||
|
|
||||
|
if (codePoint > 0xDBFF) { |
||||
|
// unexpected trail
|
||||
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
||||
|
continue |
||||
|
} else if (i + 1 === length) { |
||||
|
// unpaired lead
|
||||
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
||||
|
continue |
||||
|
} else { |
||||
|
// valid lead
|
||||
|
leadSurrogate = codePoint |
||||
|
continue |
||||
|
} |
||||
|
} |
||||
|
} else if (leadSurrogate) { |
||||
|
// valid bmp char, but last char was a lead
|
||||
|
if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) |
||||
|
leadSurrogate = null |
||||
|
} |
||||
|
|
||||
|
// encode utf8
|
||||
|
if (codePoint < 0x80) { |
||||
|
if ((units -= 1) < 0) break |
||||
|
bytes.push(codePoint) |
||||
|
} else if (codePoint < 0x800) { |
||||
|
if ((units -= 2) < 0) break |
||||
|
bytes.push( |
||||
|
codePoint >> 0x6 | 0xC0, |
||||
|
codePoint & 0x3F | 0x80 |
||||
|
) |
||||
|
} else if (codePoint < 0x10000) { |
||||
|
if ((units -= 3) < 0) break |
||||
|
bytes.push( |
||||
|
codePoint >> 0xC | 0xE0, |
||||
|
codePoint >> 0x6 & 0x3F | 0x80, |
||||
|
codePoint & 0x3F | 0x80 |
||||
|
) |
||||
|
} else if (codePoint < 0x200000) { |
||||
|
if ((units -= 4) < 0) break |
||||
|
bytes.push( |
||||
|
codePoint >> 0x12 | 0xF0, |
||||
|
codePoint >> 0xC & 0x3F | 0x80, |
||||
|
codePoint >> 0x6 & 0x3F | 0x80, |
||||
|
codePoint & 0x3F | 0x80 |
||||
|
) |
||||
|
} else { |
||||
|
throw new Error('Invalid code point') |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return bytes |
||||
|
} |
||||
Loading…
Reference in new issue