UNPKG

18.9 kBJavaScriptView Raw
1/**
2 * node-singlebyte
3 */
4
5// The MIT License (MIT)
6//
7// Copyright (c) 2013, Sergey Sokoloff (aka Mithgol the Webmaster).
8// https://github.com/Mithgol/node-singlebyte
9//
10// Permission is hereby granted, free of charge, to any person obtaining a copy of
11// this software and associated documentation files (the "Software"), to deal in
12// the Software without restriction, including without limitation the rights to
13// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
14// the Software, and to permit persons to whom the Software is furnished to do so,
15// subject to the following conditions:
16//
17// The above copyright notice and this permission notice shall be included in all
18// copies or substantial portions of the Software.
19//
20// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
22// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
23// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
24// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
27var extend = function(target) {
28 target = target || {};
29 Array.prototype.slice.call(arguments, 1).forEach(function(obj) {
30 Object.keys(obj || {}).forEach(function(key) {
31 target[key] = obj[key];
32 });
33 });
34 return target;
35};
36
37var singlebyte = function(){
38 /* jshint indent: false */
39 if(!( this instanceof singlebyte )){
40 return new singlebyte();
41 }
42
43 this.encodings = [];
44
45 // CP437
46 this.learnEncoding('cp437', this.extendASCII([
47 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7,
48 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5,
49 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9,
50 0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x20A7, 0x192,
51 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA,
52 0xBF, 0x2310, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB,
53 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
54 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
55 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
56 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
57 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
58 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
59 0x3B1, 0x3B2, 0x393, 0x3C0, 0x3A3, 0x3C3, 0x3BC, 0x3C4,
60 0x3A6, 0x398, 0x3A9, 0x3B4, 0x221E, 0x3C6, 0x3B5, 0x2229,
61 0x2261, 0xB1, 0x2265, 0x2264, 0x2320, 0x2321, 0xF7, 0x2248,
62 0xB0, 0x2219, 0xB7, 0x221A, 0x207F, 0xB2, 0x25A0, 0xA0
63 ]));
64
65 // CP850
66 this.learnEncoding('cp850', this.extendASCII([
67 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7,
68 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5,
69 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9,
70 0xFF, 0xD6, 0xDC, 0xF8, 0xA3, 0xD8, 0xD7, 0x192,
71 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA,
72 0xBF, 0xAE, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB,
73 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xC1, 0xC2, 0xC0,
74 0xA9, 0x2563, 0x2551, 0x2557, 0x255D, 0xA2, 0xA5, 0x2510,
75 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0xE3, 0xC3,
76 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0xA4,
77 0xF0, 0xD0, 0xCA, 0xCB, 0xC8, 0x131, 0xCD, 0xCE,
78 0xCF, 0x2518, 0x250C, 0x2588, 0x2584, 0xA6, 0xCC, 0x2580,
79 0xD3, 0xDF, 0xD4, 0xD2, 0xF5, 0xD5, 0xB5, 0xFE,
80 0xDE, 0xDA, 0xDB, 0xD9, 0xFD, 0xDD, 0xAF, 0xB4,
81 0xAD, 0xB1, 0x2017, 0xBE, 0xB6, 0xA7, 0xF7, 0xB8,
82 0xB0, 0xA8, 0xB7, 0xB9, 0xB3, 0xB2, 0x25A0, 0xA0
83 ]));
84
85 // CP858
86 this.learnEncoding('cp858', this.extendASCII([
87 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7,
88 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5,
89 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9,
90 0xFF, 0xD6, 0xDC, 0xF8, 0xA3, 0xD8, 0xD7, 0x192,
91 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA,
92 0xBF, 0xAE, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB,
93 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xC1, 0xC2, 0xC0,
94 0xA9, 0x2563, 0x2551, 0x2557, 0x255D, 0xA2, 0xA5, 0x2510,
95 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0xE3, 0xC3,
96 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0xA4,
97 0xF0, 0xD0, 0xCA, 0xCB, 0xC8, 0x20AC, 0xCD, 0xCE,
98 0xCF, 0x2518, 0x250C, 0x2588, 0x2584, 0xA6, 0xCC, 0x2580,
99 0xD3, 0xDF, 0xD4, 0xD2, 0xF5, 0xD5, 0xB5, 0xFE,
100 0xDE, 0xDA, 0xDB, 0xD9, 0xFD, 0xDD, 0xAF, 0xB4,
101 0xAD, 0xB1, 0x2017, 0xBE, 0xB6, 0xA7, 0xF7, 0xB8,
102 0xB0, 0xA8, 0xB7, 0xB9, 0xB3, 0xB2, 0x25A0, 0xA0
103 ]));
104
105 // CP808
106 this.learnEncoding('cp808', this.extendASCII([
107 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417,
108 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F,
109 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427,
110 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F,
111 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437,
112 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F,
113 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
114 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
115 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
116 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
117 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
118 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
119 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447,
120 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F,
121 0x401, 0x451, 0x404, 0x454, 0x407, 0x457, 0x40E, 0x45E,
122 0xB0, 0x2219, 0xB7, 0x221A, 0x2116, 0x20AC, 0x25A0, 0xA0
123 ]));
124
125 // CP866
126 this.learnEncoding('cp866', this.extendASCII([
127 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417,
128 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F,
129 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427,
130 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F,
131 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437,
132 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F,
133 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
134 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
135 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
136 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
137 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
138 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
139 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447,
140 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F,
141 0x401, 0x451, 0x404, 0x454, 0x407, 0x457, 0x40E, 0x45E,
142 0xB0, 0x2219, 0xB7, 0x221A, 0x2116, 0xA4, 0x25A0, 0xA0
143 ]));
144
145 // CP1125
146 this.learnEncoding('cp1125', this.extendASCII([
147 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417,
148 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E, 0x41F,
149 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427,
150 0x428, 0x429, 0x42A, 0x42B, 0x42C, 0x42D, 0x42E, 0x42F,
151 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437,
152 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43E, 0x43F,
153 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
154 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
155 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
156 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
157 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
158 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
159 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447,
160 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F,
161 0x401, 0x451, 0x490, 0x491, 0x404, 0x454, 0x406, 0x456,
162 0x407, 0x457, 0xB7, 0x221A, 0x2116, 0xA4, 0x25A0, 0xA0
163 ]));
164
165 // KOI8-R
166 this.learnEncoding('koi8-r', this.extendASCII([
167 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
168 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
169 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
170 0x2264, 0x2265, 0xA0, 0x2321, 0xB0, 0xB2, 0xB7, 0xF7,
171 0x2550, 0x2551, 0x2552, 0x451, 0x2553, 0x2554, 0x2555, 0x2556,
172 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
173 0x255F, 0x2560, 0x2561, 0x401, 0x2562, 0x2563, 0x2564, 0x2565,
174 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0xA9,
175 0x44E, 0x430, 0x431, 0x446, 0x434, 0x435, 0x444, 0x433,
176 0x445, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x043E,
177 0x43F, 0x44F, 0x440, 0x441, 0x442, 0x443, 0x436, 0x432,
178 0x44C, 0x44B, 0x437, 0x448, 0x44D, 0x449, 0x447, 0x44A,
179 0x42E, 0x410, 0x411, 0x426, 0x414, 0x415, 0x424, 0x413,
180 0x425, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E,
181 0x41F, 0x42F, 0x420, 0x421, 0x422, 0x423, 0x416, 0x412,
182 0x42C, 0x42B, 0x417, 0x428, 0x42D, 0x429, 0x427, 0x42A
183 ]));
184
185 // KOI8-U
186 this.learnEncoding('koi8-u', this.extendASCII([
187 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
188 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
189 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
190 0x2264, 0x2265, 0xA0, 0x2321, 0xB0, 0xB2, 0xB7, 0xF7,
191 0x2550, 0x2551, 0x2552, 0x451, 0x454, 0x2554, 0x456, 0x457,
192 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x491, 0x255D, 0x255E,
193 0x255F, 0x2560, 0x2561, 0x401, 0x404, 0x2563, 0x406, 0x407,
194 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x490, 0x256C, 0xA9,
195 0x44E, 0x430, 0x431, 0x446, 0x434, 0x435, 0x444, 0x433,
196 0x445, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x043E,
197 0x43F, 0x44F, 0x440, 0x441, 0x442, 0x443, 0x436, 0x432,
198 0x44C, 0x44B, 0x437, 0x448, 0x44D, 0x449, 0x447, 0x44A,
199 0x42E, 0x410, 0x411, 0x426, 0x414, 0x415, 0x424, 0x413,
200 0x425, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E,
201 0x41F, 0x42F, 0x420, 0x421, 0x422, 0x423, 0x416, 0x412,
202 0x42C, 0x42B, 0x417, 0x428, 0x42D, 0x429, 0x427, 0x42A
203 ]));
204
205 // KOI8-RU
206 this.learnEncoding('koi8-ru', this.extendASCII([
207 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
208 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
209 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
210 0x2264, 0x2265, 0xA0, 0x2321, 0xB0, 0xB2, 0xB7, 0xF7,
211 0x2550, 0x2551, 0x2552, 0x451, 0x454, 0x2554, 0x456, 0x457,
212 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x491, 0x45E, 0x255E,
213 0x255F, 0x2560, 0x2561, 0x401, 0x404, 0x2563, 0x406, 0x407,
214 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x490, 0x40E, 0xA9,
215 0x44E, 0x430, 0x431, 0x446, 0x434, 0x435, 0x444, 0x433,
216 0x445, 0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x043E,
217 0x43F, 0x44F, 0x440, 0x441, 0x442, 0x443, 0x436, 0x432,
218 0x44C, 0x44B, 0x437, 0x448, 0x44D, 0x449, 0x447, 0x44A,
219 0x42E, 0x410, 0x411, 0x426, 0x414, 0x415, 0x424, 0x413,
220 0x425, 0x418, 0x419, 0x41A, 0x41B, 0x41C, 0x41D, 0x41E,
221 0x41F, 0x42F, 0x420, 0x421, 0x422, 0x423, 0x416, 0x412,
222 0x42C, 0x42B, 0x417, 0x428, 0x42D, 0x429, 0x427, 0x42A
223 ]));
224
225 // LATIN-1 aka ISO 8859-1 (Western European)
226 this.learnEncoding('latin-1', this.extendASCII([
227 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
228 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
229 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
230 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
231 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
232 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
233 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
234 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
235 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
236 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
237 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
238 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
239 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
240 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
241 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
242 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
243 ]));
244
245 // Windows-1252
246 this.learnEncoding('cp1252', this.extendASCII([
247 0x20AC, 0x81, 0x201A, 0x192, 0x201E, 0x2026, 0x2020, 0x2021,
248 0x2C6, 0x2030, 0x160, 0x2039, 0x152, 0x8D, 0x017D, 0x8F,
249 0x90, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
250 0x02DC, 0x2122, 0x161, 0x203A, 0x0153, 0x9D, 0x17E, 0x178,
251 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
252 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
253 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
254 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
255 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
256 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
257 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
258 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
259 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
260 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
261 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
262 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
263 ]));
264};
265
266singlebyte.prototype.isEncoding = function(encodingName){
267 if( Buffer.isEncoding(encodingName) ) return true;
268 for( var i = 0; i < this.encodings.length; i++ ){
269 if( this.encodings[i].name === encodingName ) return true;
270 }
271 return false;
272};
273
274singlebyte.prototype.learnEncoding = function(encodingName, encodingTable){
275 /*jshint bitwise: false */
276 if( Buffer.isEncoding(encodingName) ){
277 throw new Error(this.errors.BUFFER_ENCODING);
278 }
279
280 if( encodingTable.length !== 256 ){
281 throw new Error(this.errors.INVALID_TABLE_LENGTH);
282 }
283
284 var _this = this;
285 encodingTable = encodingTable.map(function(item){
286 var nextCode = item |0;
287 if( 0 > nextCode || nextCode > 0x10FFFF ){
288 throw new Error(_this.errors.OUT_OF_UNICODE);
289 }
290 return item;
291 });
292
293 if( this.isEncoding(encodingName) ){
294 for( var i = 0; i < this.encodings.length; i++ ){
295 if( this.encodings[i].name === encodingName ){
296 this.encodings[i].table = encodingTable;
297 return;
298 }
299 }
300 } else {
301 this.encodings.push({
302 name: encodingName,
303 table: encodingTable
304 });
305 }
306};
307
308singlebyte.prototype.getEncodingTable = function(encodingName){
309 for( var i = 0; i < this.encodings.length; i++ ){
310 if( this.encodings[i].name === encodingName ){
311 return this.encodings[i].table;
312 }
313 }
314 return null;
315};
316
317singlebyte.prototype.extendASCII = function(extensionTable){
318 if( extensionTable.length !== 128 ){
319 throw new Error(this.errors.INVALID_EXTENSION);
320 }
321
322 var output = [];
323 for( var i = 0; i < 128; i++ ) output.push(i);
324 return output.concat(extensionTable);
325};
326
327singlebyte.prototype.bufToStr = function(buf, encoding, start, end){
328 /* jshint bitwise: false */
329 if(!( Buffer.isBuffer(buf) )){
330 throw new Error(this.errors.NOT_A_BUFFER);
331 }
332 if( Buffer.isEncoding(encoding) ){
333 return buf.toString(encoding, start, end);
334 }
335 var table = this.getEncodingTable(encoding);
336 if( table === null ) throw new Error(this.errors.UNKNOWN_ENCODING);
337
338 if( typeof end === 'undefined' ) end = buf.length;
339 if( typeof start === 'undefined' ) start = 0;
340
341 var output = '';
342 var sourceValue;
343 for( var i = start; i < end; i++ ){
344 sourceValue = table[ buf[i] ];
345 if( sourceValue <= 0xFFFF ){
346 output += String.fromCharCode(sourceValue);
347 } else if( 0x10000 <= sourceValue && sourceValue <= 0x10FFFF ){
348 sourceValue -= 0x10000;
349 output += String.fromCharCode( 0xD800 + (sourceValue >> 10) );
350 output += String.fromCharCode( 0xDC00 + (sourceValue & 0x3FF) );
351 } else throw new Error(this.errors.OUT_OF_UNICODE);
352 }
353 return output;
354};
355
356var strToBufDefaults = {
357 defaultCode: 0x3F // '?'
358};
359
360singlebyte.prototype.strToBuf = function(str, encoding, encodingOptions){
361 if( Buffer.isEncoding(encoding) ){
362 return new Buffer(str, encoding);
363 }
364 str = '' + str;
365 var options = extend({}, strToBufDefaults, encodingOptions);
366 var table = this.getEncodingTable(encoding);
367 if( table === null ) throw new Error(this.errors.UNKNOWN_ENCODING);
368 var output = [];
369 for( var i = 0; i < str.length; i++ ){
370 var charUnicode;
371 var thisCharCode = str.charCodeAt(i);
372 if( 0xD800 <= thisCharCode && thisCharCode <= 0xDBFF &&
373 i+1 < str.length
374 ){
375 var nextCharCode = str.charCodeAt(i+1);
376 if( 0xDC00 <= nextCharCode && nextCharCode <= 0xDFFF ){
377 charUnicode = 0x10000 + (thisCharCode - 0xD800)*0x400 +
378 (nextCharCode - 0xDC00);
379 i++;
380 } else {
381 charUnicode = thisCharCode;
382 }
383 } else {
384 charUnicode = thisCharCode;
385 }
386
387 var codeFoundIndex = table.indexOf(charUnicode);
388 if( codeFoundIndex < 0 ){
389 output.push(options.defaultCode);
390 } else {
391 output.push(codeFoundIndex);
392 }
393 }
394 return new Buffer(output);
395};
396
397singlebyte.prototype.errors = {
398 NOT_A_BUFFER : 'The given source is not a buffer!',
399 UNKNOWN_ENCODING : 'The given encoding is not defined!',
400 INVALID_TABLE_LENGTH : 'The encoding table must have 256 elements!',
401 INVALID_EXTENSION : 'The ASCII extension table must have 128 elements!',
402 BUFFER_ENCODING : "Cannot redefine a Node's encoding!",
403 OUT_OF_UNICODE : "An encoding table's element is greater than 0x10FFFF!"
404};
405
406module.exports = singlebyte();