UNPKG

5.01 kBJavaScriptView Raw
1var jsencoding = require('../deps/encoding/encoding');
2
3var RE_ENCODED = /%([a-fA-F0-9]{2})/g;
4function encodedReplacer(match, byte) {
5 return String.fromCharCode(parseInt(byte, 16));
6}
7function parseParams(str) {
8 var res = [],
9 state = 'key',
10 charset = '',
11 inquote = false,
12 escaping = false,
13 p = 0,
14 tmp = '';
15
16 for (var i = 0, len = str.length; i < len; ++i) {
17 if (str[i] === '\\' && inquote) {
18 if (escaping)
19 escaping = false;
20 else {
21 escaping = true;
22 continue;
23 }
24 } else if (str[i] === '"') {
25 if (!escaping) {
26 if (inquote) {
27 inquote = false;
28 state = 'key';
29 } else
30 inquote = true;
31 continue;
32 } else
33 escaping = false;
34 } else {
35 if (escaping && inquote)
36 tmp += '\\';
37 escaping = false;
38 if ((state === 'charset' || state === 'lang') && str[i] === "'") {
39 if (state === 'charset') {
40 state = 'lang';
41 charset = tmp.substring(1);
42 } else
43 state = 'value';
44 tmp = '';
45 continue;
46 } else if (state === 'key'
47 && (str[i] === '*' || str[i] === '=')
48 && res.length) {
49 if (str[i] === '*')
50 state = 'charset';
51 else
52 state = 'value';
53 res[p] = [tmp, undefined];
54 tmp = '';
55 continue;
56 } else if (!inquote && str[i] === ';') {
57 state = 'key';
58 if (charset) {
59 if (tmp.length) {
60 tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
61 'binary',
62 charset);
63 }
64 charset = '';
65 }
66 if (res[p] === undefined)
67 res[p] = tmp;
68 else
69 res[p][1] = tmp;
70 tmp = '';
71 ++p;
72 continue;
73 } else if (!inquote && (str[i] === ' ' || str[i] === '\t'))
74 continue;
75 }
76 tmp += str[i];
77 }
78 if (charset && tmp.length) {
79 tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
80 'binary',
81 charset);
82 }
83
84 if (res[p] === undefined) {
85 if (tmp)
86 res[p] = tmp;
87 } else
88 res[p][1] = tmp;
89
90 return res;
91};
92exports.parseParams = parseParams;
93
94
95function decodeText(text, textEncoding, destEncoding) {
96 var ret;
97 if (text && jsencoding.encodingExists(destEncoding)) {
98 try {
99 ret = jsencoding.TextDecoder(destEncoding)
100 .decode(new Buffer(text, textEncoding));
101 } catch(e) {}
102 }
103 return (typeof ret === 'string' ? ret : text);
104}
105exports.decodeText = decodeText;
106
107
108var HEX = [
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
113 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
115 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
117], RE_PLUS = /\+/g;
118function Decoder() {
119 this.buffer = undefined;
120}
121Decoder.prototype.write = function(str) {
122 // Replace '+' with ' ' before decoding
123 str = str.replace(RE_PLUS, ' ');
124 var res = '';
125 var i = 0, p = 0, len = str.length;
126 for (; i < len; ++i) {
127 if (this.buffer !== undefined) {
128 if (!HEX[str.charCodeAt(i)]) {
129 res += '%' + this.buffer;
130 this.buffer = undefined;
131 --i; // retry character
132 } else {
133 this.buffer += str[i];
134 ++p;
135 if (this.buffer.length === 2) {
136 res += String.fromCharCode(parseInt(this.buffer, 16));
137 this.buffer = undefined;
138 }
139 }
140 } else if (str[i] === '%') {
141 if (i > p) {
142 res += str.substring(p, i);
143 p = i;
144 }
145 this.buffer = '';
146 ++p;
147 }
148 }
149 if (p < len && this.buffer === undefined)
150 res += str.substring(p);
151 return res;
152};
153Decoder.prototype.reset = function() {
154 this.buffer = undefined;
155};
156exports.Decoder = Decoder;
157
158
159var RE_SPLIT_POSIX =
160 /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,
161 RE_SPLIT_DEVICE =
162 /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/,
163 RE_SPLIT_WINDOWS =
164 /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
165function splitPathPosix(filename) {
166 return RE_SPLIT_POSIX.exec(filename).slice(1);
167}
168function splitPathWindows(filename) {
169 // Separate device+slash from tail
170 var result = RE_SPLIT_DEVICE.exec(filename),
171 device = (result[1] || '') + (result[2] || ''),
172 tail = result[3] || '';
173 // Split the tail into dir, basename and extension
174 var result2 = RE_SPLIT_WINDOWS.exec(tail),
175 dir = result2[1],
176 basename = result2[2],
177 ext = result2[3];
178 return [device, dir, basename, ext];
179}
180function basename(path) {
181 var f = splitPathPosix(path)[2];
182 if (f === path)
183 f = splitPathWindows(path)[2];
184 return f;
185}
186exports.basename = basename;
\No newline at end of file