You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					186 lines
				
				4.9 KiB
			
		
		
			
		
	
	
					186 lines
				
				4.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								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;
							 |