@tjieco/library
Version:
TypeScript port of ZXing multi-format 1D/2D barcode image processing library, with Code128 and ITF support.
93 lines (85 loc) • 4.19 kB
text/typescript
// declare require to support dynamic text-encoding module loading in node
declare function require(moduleName: string): any;
// declare window to use in browser
declare var window: any;
import { TextDecoder as TextDecoderFromTE, TextEncoder as TextEncoderFromTE } from 'text-encoding';
import CharacterSetECI from './../common/CharacterSetECI';
import Exception from './../Exception';
export default class StringEncoding {
public static decode(bytes: Uint8Array, encoding: string | CharacterSetECI): string {
let encodingString: string;
if (typeof encoding === 'string') {
encodingString = encoding;
} else {
encodingString = encoding.getName();
}
if (StringEncoding.isBrowser()) {
// tslint:disable-next-line:no-string-literal
const TextDecoderBrowser = window['TextDecoder'];
// use TextEncoder if is available (should be in newer browsers)
if (undefined !== TextDecoderBrowser) {
// console.log(TextDecoderBrowser)
return new TextDecoderBrowser(encoding).decode(bytes);
} else {
// fall back to minimal decoding
return StringEncoding.decodeFallBack(bytes, encodingString);
}
} else {
const TextDecoderFromTEClass: typeof TextDecoderFromTE = require('text-encoding').TextDecoder;
return new TextDecoderFromTEClass(encodingString).decode(bytes);
}
}
public static encode(s: string, encoding: string | CharacterSetECI): Uint8Array {
let encodingString: string;
if (typeof encoding === 'string') {
encodingString = encoding;
} else {
encodingString = encoding.getName();
}
if (StringEncoding.isBrowser()) {
// tslint:disable-next-line:no-string-literal
const TextEncoderBrowser = window['TextEncoder'];
// use TextEncoder if is available (should be in newer browsers)
const ec = CharacterSetECI.getCharacterSetECIByName(encodingString);
if (undefined !== TextEncoderBrowser) {
// TODO: TextEncoder only supports utf-8 encoding as per specs
return new TextEncoderBrowser(encoding).encode(s);
} else {
// fall back to minimal decoding
return StringEncoding.encodeFallBack(s, encodingString);
}
} else {
// Note: NONSTANDARD_allowLegacyEncoding is required for other encodings than UTF8
// TextEncoder only encodes to UTF8 by default as specified by encoding.spec.whatwg.org
const TextEncoderFromTEClass: typeof TextEncoderFromTE = require('text-encoding').TextEncoder;
return new TextEncoderFromTEClass(encodingString, { NONSTANDARD_allowLegacyEncoding: true }).encode(s);
}
}
private static isBrowser(): boolean {
return typeof window !== 'undefined' && ({}).toString.call(window) === '[object Window]';
}
private static decodeFallBack(bytes: Uint8Array, encoding: string): string {
const ec = CharacterSetECI.getCharacterSetECIByName(encoding);
if (ec.equals(CharacterSetECI.UTF8) ||
ec.equals(CharacterSetECI.ISO8859_1) ||
ec.equals(CharacterSetECI.ASCII)) {
let s = '';
for (let i = 0, length = bytes.length; i < length; i++) {
let h = bytes[i].toString(16);
if (h.length < 2) {
h = '0' + h;
}
s += '%' + h;
}
return decodeURIComponent(s);
} else if (ec.equals(CharacterSetECI.UnicodeBigUnmarked)) {
return String.fromCharCode.apply(null, new Uint16Array(bytes.buffer));
} else {
throw new Exception(Exception.UnsupportedOperationException, `encoding ${encoding} not supported`);
}
}
private static encodeFallBack(s: string, encoding: string): Uint8Array {
// TODO: encode
return null;
}
}