123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- var jsencoding = require('../deps/encoding/encoding');
- var RE_ENCODED = /%([a-fA-F0-9]{2})/g;
- function encodedReplacer(match, byte) {
- return String.fromCharCode(parseInt(byte, 16));
- }
- function parseParams(str) {
- var res = [],
- state = 'key',
- charset = '',
- inquote = false,
- escaping = false,
- p = 0,
- tmp = '';
- for (var i = 0, len = str.length; i < len; ++i) {
- if (str[i] === '\\' && inquote) {
- if (escaping)
- escaping = false;
- else {
- escaping = true;
- continue;
- }
- } else if (str[i] === '"') {
- if (!escaping) {
- if (inquote) {
- inquote = false;
- state = 'key';
- } else
- inquote = true;
- continue;
- } else
- escaping = false;
- } else {
- if (escaping && inquote)
- tmp += '\\';
- escaping = false;
- if ((state === 'charset' || state === 'lang') && str[i] === "'") {
- if (state === 'charset') {
- state = 'lang';
- charset = tmp.substring(1);
- } else
- state = 'value';
- tmp = '';
- continue;
- } else if (state === 'key'
- && (str[i] === '*' || str[i] === '=')
- && res.length) {
- if (str[i] === '*')
- state = 'charset';
- else
- state = 'value';
- res[p] = [tmp, undefined];
- tmp = '';
- continue;
- } else if (!inquote && str[i] === ';') {
- state = 'key';
- if (charset) {
- if (tmp.length) {
- tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
- 'binary',
- charset);
- }
- charset = '';
- }
- if (res[p] === undefined)
- res[p] = tmp;
- else
- res[p][1] = tmp;
- tmp = '';
- ++p;
- continue;
- } else if (!inquote && (str[i] === ' ' || str[i] === '\t'))
- continue;
- }
- tmp += str[i];
- }
- if (charset && tmp.length) {
- tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
- 'binary',
- charset);
- }
- if (res[p] === undefined) {
- if (tmp)
- res[p] = tmp;
- } else
- res[p][1] = tmp;
- return res;
- };
- exports.parseParams = parseParams;
- function decodeText(text, textEncoding, destEncoding) {
- var ret;
- if (text && jsencoding.encodingExists(destEncoding)) {
- try {
- ret = jsencoding.TextDecoder(destEncoding)
- .decode(new Buffer(text, textEncoding));
- } catch(e) {}
- }
- return (typeof ret === 'string' ? ret : text);
- }
- exports.decodeText = decodeText;
- var HEX = [
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- ], RE_PLUS = /\+/g;
- function Decoder() {
- this.buffer = undefined;
- }
- Decoder.prototype.write = function(str) {
- // Replace '+' with ' ' before decoding
- str = str.replace(RE_PLUS, ' ');
- var res = '';
- var i = 0, p = 0, len = str.length;
- for (; i < len; ++i) {
- if (this.buffer !== undefined) {
- if (!HEX[str.charCodeAt(i)]) {
- res += '%' + this.buffer;
- this.buffer = undefined;
- --i; // retry character
- } else {
- this.buffer += str[i];
- ++p;
- if (this.buffer.length === 2) {
- res += String.fromCharCode(parseInt(this.buffer, 16));
- this.buffer = undefined;
- }
- }
- } else if (str[i] === '%') {
- if (i > p) {
- res += str.substring(p, i);
- p = i;
- }
- this.buffer = '';
- ++p;
- }
- }
- if (p < len && this.buffer === undefined)
- res += str.substring(p);
- return res;
- };
- Decoder.prototype.reset = function() {
- this.buffer = undefined;
- };
- exports.Decoder = Decoder;
- var RE_SPLIT_POSIX =
- /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,
- RE_SPLIT_DEVICE =
- /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/,
- RE_SPLIT_WINDOWS =
- /^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
- function splitPathPosix(filename) {
- return RE_SPLIT_POSIX.exec(filename).slice(1);
- }
- function splitPathWindows(filename) {
- // Separate device+slash from tail
- var result = RE_SPLIT_DEVICE.exec(filename),
- device = (result[1] || '') + (result[2] || ''),
- tail = result[3] || '';
- // Split the tail into dir, basename and extension
- var result2 = RE_SPLIT_WINDOWS.exec(tail),
- dir = result2[1],
- basename = result2[2],
- ext = result2[3];
- return [device, dir, basename, ext];
- }
- function basename(path) {
- var f = splitPathPosix(path)[2];
- if (f === path)
- f = splitPathWindows(path)[2];
- return f;
- }
- exports.basename = basename;
|