1 | var jsencoding = require('../deps/encoding/encoding');
|
2 |
|
3 | var RE_ENCODED = /%([a-fA-F0-9]{2})/g;
|
4 | function encodedReplacer(match, byte) {
|
5 | return String.fromCharCode(parseInt(byte, 16));
|
6 | }
|
7 | function 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 | };
|
92 | exports.parseParams = parseParams;
|
93 |
|
94 |
|
95 | function 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 | }
|
105 | exports.decodeText = decodeText;
|
106 |
|
107 |
|
108 | var 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;
|
118 | function Decoder() {
|
119 | this.buffer = undefined;
|
120 | }
|
121 | Decoder.prototype.write = function(str) {
|
122 |
|
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;
|
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 | };
|
153 | Decoder.prototype.reset = function() {
|
154 | this.buffer = undefined;
|
155 | };
|
156 | exports.Decoder = Decoder;
|
157 |
|
158 |
|
159 | var 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}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
|
165 | function splitPathPosix(filename) {
|
166 | return RE_SPLIT_POSIX.exec(filename).slice(1);
|
167 | }
|
168 | function splitPathWindows(filename) {
|
169 |
|
170 | var result = RE_SPLIT_DEVICE.exec(filename),
|
171 | device = (result[1] || '') + (result[2] || ''),
|
172 | tail = result[3] || '';
|
173 |
|
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 | }
|
180 | function basename(path) {
|
181 | var f = splitPathPosix(path)[2];
|
182 | if (f === path)
|
183 | f = splitPathWindows(path)[2];
|
184 | return f;
|
185 | }
|
186 | exports.basename = basename; |
\ | No newline at end of file |