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; |