1 /*
  2  * UTF16LE.js - Implement Unicode Transformation Format 16 bit,
  3  * Little Endian mappings
  4  *
  5  * Copyright © 2014-2015, 2018, JEDLSoft
  6  *
  7  * Licensed under the Apache License, Version 2.0 (the "License");
  8  * you may not use this file except in compliance with the License.
  9  * You may obtain a copy of the License at
 10  *
 11  *     http://www.apache.org/licenses/LICENSE-2.0
 12  *
 13  * Unless required by applicable law or agreed to in writing, software
 14  * distributed under the License is distributed on an "AS IS" BASIS,
 15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 16  *
 17  * See the License for the specific language governing permissions and
 18  * limitations under the License.
 19  */
 20 
 21 // !data charset/UTF-16 charset/UTF-16LE
 22 
 23 var Charset = require("./Charset.js");
 24 var Charmap = require("./Charmap.js");
 25 
 26 /**
 27  * @class
 28  * Create a new UTF-16LE mapping instance
 29  * @constructor
 30  * @extends Charmap
 31  */
 32 var UTF16LE = function (options) {
 33     options = options || {sync: true};
 34     if (typeof(options.charset) === "object" && options.charset instanceof Charset) {
 35         this.charset = options.charset;
 36         this._init(options);
 37     } else {
 38         new Charset({
 39             name: "UTF-16LE",
 40             sync: options.sync,
 41             loadParams: options.loadParams,
 42             onLoad: ilib.bind(this, function(cs) {
 43                 this.charset = cs;
 44                 this._init(options);
 45             })
 46         });
 47     }
 48 };
 49 
 50 UTF16LE.prototype = new Charmap({noinstance: true});
 51 UTF16LE.prototype.parent = Charmap;
 52 UTF16LE.prototype.constructor = UTF16LE;
 53 
 54 /**
 55  * @private
 56  * Initialize the charmap instance
 57  */
 58 UTF16LE.prototype._init = function(options) {
 59     this._calcExpansionFactor();
 60 
 61     if (typeof(options.onLoad) === "function") {
 62         options.onLoad(this);
 63     }
 64 };
 65 
 66 UTF16LE.prototype.mapToUnicode = function (bytes) {
 67     if (typeof(Buffer) !== "undefined") {
 68         // nodejs can convert it quickly in native code
 69         var b = Buffer.from(bytes);
 70         return b.toString("utf16le");
 71     }
 72     // otherwise we have to implement it in pure JS
 73     var ret = "";
 74     for (var i = 0; i < bytes.length; i += 2) {
 75         ret += String.fromCharCode(bytes[i+1] << 8 | bytes[i]);
 76     }
 77 
 78     return ret;
 79 };
 80 
 81 UTF16LE.prototype.mapToNative =  function(str) {
 82     if (typeof(Buffer) !== "undefined") {
 83         // nodejs can convert it quickly in native code
 84         var b = Buffer.from(str, "utf16le");
 85         return new Uint8Array(b);
 86     }
 87     // otherwise we have to implement it in pure JS
 88     var ret = new Uint8Array(str.length * 2 + 2);
 89     var c;
 90     for (var i = 0; i < str.length; i++) {
 91         c = str.charCodeAt(i);
 92         ret[i*2] = c & 0xFF;
 93         ret[i*2+1] = (c >> 8) & 0xFF;
 94     }
 95     // double null terminate it, just in case
 96     ret[i*2+1] = 0;
 97     ret[i*2+2] = 0;
 98 
 99     return ret;
100 };
101 
102 Charmap._algorithms["UTF-16"] = UTF16LE;
103 Charmap._algorithms["UTF-16LE"] = UTF16LE;
104 
105 module.exports = UTF16LE;