123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- var REVERSE_SOLIDUS = 0x5c;
- var QUOTATION_MARK = 0x22;
- var APOSTROPHE = 0x27;
- var TAB = 0x09;
- var WHITESPACE = 0x20;
- var AMPERSAND = 0x26;
- var LESSTHANSIGN = 0x3C;
- var GREATERTHANSIGN = 0x3E;
- function isHex(code) {
- return (code >= 48 && code <= 57) ||
- (code >= 65 && code <= 70) ||
- (code >= 97 && code <= 102);
- }
- function decodeString(str) {
- var decoded = '';
- var len = str.length;
- var firstChar = str.charCodeAt(0);
- var start = firstChar === QUOTATION_MARK || firstChar === APOSTROPHE ? 1 : 0;
- var end = start === 1 && len > 1 && str.charCodeAt(len - 1) === firstChar ? len - 2 : len - 1;
- for (var i = start; i <= end; i++) {
- var code = str.charCodeAt(i);
- if (code === REVERSE_SOLIDUS) {
-
- if (i === end) {
-
-
- if (i !== len - 1) {
- decoded = str.substr(i + 1);
- }
- break;
- }
- code = str.charCodeAt(++i);
-
- if (code !== 0x0A && code !== 0x0C && code !== 0x0D) {
-
- for (var j = 0; j < 6 && i + j <= end;) {
- code = str.charCodeAt(i + j);
- if (isHex(code)) {
- j++;
- } else {
- break;
- }
- }
- if (j > 0) {
- code = str.charCodeAt(i + j);
-
-
- if (code === WHITESPACE || code === TAB) {
- j++;
- }
- code = parseInt(str.substr(i, j), 16);
- if (
- (code === 0) ||
- (code >= 0xD800 && code <= 0xDFFF) ||
- (code > 0x10FFFF)
- ) {
-
- code = 0xFFFD;
- }
-
-
- decoded += String.fromCharCode(code);
- i += j - 1;
- } else {
- decoded += str.charAt(i);
- }
- }
- } else {
- decoded += str.charAt(i);
- }
- }
- return decoded;
- }
- function encodeString(str, apostrophe) {
- var quote = apostrophe ? '\'' : '"';
- var quoteCode = apostrophe ? APOSTROPHE : QUOTATION_MARK;
- var encoded = quote;
- var wsBeforeHexIsNeeded = false;
- for (var i = 0; i < str.length; i++) {
- var code = str.charCodeAt(i);
- if (code <= 0x1F || code === AMPERSAND || code === LESSTHANSIGN || code === GREATERTHANSIGN) {
- encoded += '\\' + code.toString(16);
- wsBeforeHexIsNeeded = true;
- } else if (code === REVERSE_SOLIDUS || code === quoteCode) {
- encoded += '\\' + str.charAt(i);
- wsBeforeHexIsNeeded = false;
- } else {
- if (wsBeforeHexIsNeeded && isHex(code)) {
- encoded += ' ';
- }
- encoded += str.charAt(i);
- wsBeforeHexIsNeeded = false;
- }
- }
- encoded += quote;
- return encoded;
- }
- module.exports = {
- decode: decodeString,
- encode: encodeString
- };
|