1'use strict';
2
3var iconvLite = require('iconv-lite');
4
5// Expose to the world
6module.exports.convert = convert;
7
8/**
9 * Convert encoding of an UTF-8 string or a buffer
10 *
11 * @param {String|Buffer} str String to be converted
12 * @param {String} to Encoding to be converted to
13 * @param {String} [from='UTF-8'] Encoding to be converted from
14 * @return {Buffer} Encoded string
15 */
16function convert(str, to, from) {
17    from = checkEncoding(from || 'UTF-8');
18    to = checkEncoding(to || 'UTF-8');
19    str = str || '';
20
21    var result;
22
23    if (from !== 'UTF-8' && typeof str === 'string') {
24        str = Buffer.from(str, 'binary');
25    }
26
27    if (from === to) {
28        if (typeof str === 'string') {
29            result = Buffer.from(str);
30        } else {
31            result = str;
32        }
33    } else {
34        try {
35            result = convertIconvLite(str, to, from);
36        } catch (E) {
37            console.error(E);
38            result = str;
39        }
40    }
41
42    if (typeof result === 'string') {
43        result = Buffer.from(result, 'utf-8');
44    }
45
46    return result;
47}
48
49/**
50 * Convert encoding of astring with iconv-lite
51 *
52 * @param {String|Buffer} str String to be converted
53 * @param {String} to Encoding to be converted to
54 * @param {String} [from='UTF-8'] Encoding to be converted from
55 * @return {Buffer} Encoded string
56 */
57function convertIconvLite(str, to, from) {
58    if (to === 'UTF-8') {
59        return iconvLite.decode(str, from);
60    } else if (from === 'UTF-8') {
61        return iconvLite.encode(str, to);
62    } else {
63        return iconvLite.encode(iconvLite.decode(str, from), to);
64    }
65}
66
67/**
68 * Converts charset name if needed
69 *
70 * @param {String} name Character set
71 * @return {String} Character set name
72 */
73function checkEncoding(name) {
74    return (name || '')
75        .toString()
76        .trim()
77        .replace(/^latin[\-_]?(\d+)$/i, 'ISO-8859-$1')
78        .replace(/^win(?:dows)?[\-_]?(\d+)$/i, 'WINDOWS-$1')
79        .replace(/^utf[\-_]?(\d+)$/i, 'UTF-$1')
80        .replace(/^ks_c_5601\-1987$/i, 'CP949')
81        .replace(/^us[\-_]?ascii$/i, 'ASCII')
82        .toUpperCase();
83}
84