diff options
Diffstat (limited to 'js/src/Ice/StringUtil.js')
-rw-r--r-- | js/src/Ice/StringUtil.js | 546 |
1 files changed, 266 insertions, 280 deletions
diff --git a/js/src/Ice/StringUtil.js b/js/src/Ice/StringUtil.js index f7866d3d92a..76e3a41a5fa 100644 --- a/js/src/Ice/StringUtil.js +++ b/js/src/Ice/StringUtil.js @@ -7,21 +7,17 @@ // // ********************************************************************** -(function(global){ - require("Ice/Debug"); - - var Ice = global.Ice || {}; - - var Debug = Ice.Debug; - - var StringUtil = {}; +var Ice = require("../Ice/Debug").Ice; +var Debug = Ice.Debug; +Ice.StringUtil = +{ // // Return the index of the first character in str to // appear in match, starting from start. Returns -1 if none is // found. // - StringUtil.findFirstOf = function(str, match, start) + findFirstOf: function(str, match, start) { start = start === undefined ? 0 : start; @@ -36,14 +32,13 @@ } return -1; - }; - + }, // // Return the index of the first character in str which does // not appear in match, starting from start. Returns -1 if none is // found. // - StringUtil.findFirstNotOf = function(str, match, start) + findFirstNotOf: function(str, match, start) { start = start === undefined ? 0 : start; @@ -58,101 +53,13 @@ } return -1; - }; - - // - // Write the byte b as an escape sequence if it isn't a printable ASCII - // character and append the escape sequence to sb. Additional characters - // that should be escaped can be passed in special. If b is any of these - // characters, b is preceded by a backslash in sb. - // - function encodeChar(b, sb, special) - { - switch(b) - { - case 92: // '\\' - { - sb.push("\\\\"); - break; - } - case 39: // '\'' - { - sb.push("\\'"); - break; - } - case 34: // '"' - { - sb.push("\\\""); - break; - } - case 8: // '\b' - { - sb.push("\\b"); - break; - } - case 12: // '\f' - { - sb.push("\\f"); - break; - } - case 10: // '\n' - { - sb.push("\\n"); - break; - } - case 13: // '\r' - { - sb.push("\\r"); - break; - } - case 9: // '\t' - { - sb.push("\\t"); - break; - } - default: - { - if(!(b >= 32 && b <= 126)) - { - sb.push('\\'); - var octal = b.toString(8); - // - // Add leading zeroes so that we avoid problems during - // decoding. For example, consider the encoded string - // \0013 (i.e., a character with value 1 followed by - // the character '3'). If the leading zeroes were omitted, - // the result would be incorrectly interpreted by the - // decoder as a single character with value 11. - // - for(var j = octal.length; j < 3; j++) - { - sb.push('0'); - } - sb.push(octal); - } - else - { - var c = String.fromCharCode(b); - if(special !== null && special.indexOf(c) !== -1) - { - sb.push('\\'); - sb.push(c); - } - else - { - sb.push(c); - } - } - } - } - } - + }, // // Add escape sequences (such as "\n", or "\007") to make a string // readable in ASCII. Any characters that appear in special are // prefixed with a backlash in the returned string. // - StringUtil.escapeString = function(s, special) + escapeString: function(s, special) { special = special === undefined ? null : special; @@ -190,172 +97,12 @@ } return result.join(""); - }; - - function checkChar(s, pos) - { - var n = s.charCodeAt(pos); - if(!(n >= 32 && n <= 126)) - { - var msg; - if(pos > 0) - { - msg = "character after `" + s.substring(0, pos) + "'"; - } - else - { - msg = "first character"; - } - msg += " is not a printable ASCII character (ordinal " + n + ")"; - throw new Error(msg); - } - return n; - } - - // - // Decode the character or escape sequence starting at start and return it. - // nextStart is set to the index of the first character following the decoded - // character or escape sequence. - // - function decodeChar(s, start, end, nextStart) - { - Debug.assert(start >= 0); - Debug.assert(end <= s.length); - - if(start >= end) - { - throw new Error("EOF while decoding string"); - } - - var c; - - if(s.charAt(start) != '\\') - { - c = checkChar(s, start++); - } - else - { - if(start + 1 == end) - { - throw new Error("trailing backslash"); - } - switch(s.charAt(++start)) - { - case '\\': - case '\'': - case '"': - { - c = s.charCodeAt(start++); - break; - } - case 'b': - { - ++start; - c = "\b".charCodeAt(0); - break; - } - case 'f': - { - ++start; - c = "\f".charCodeAt(0); - break; - } - case 'n': - { - ++start; - c = "\n".charCodeAt(0); - break; - } - case 'r': - { - ++start; - c = "\r".charCodeAt(0); - break; - } - case 't': - { - ++start; - c = "\t".charCodeAt(0); - break; - } - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - var octalChars = "01234567"; - var val = 0; - for(var j = 0; j < 3 && start < end; ++j) - { - var ch = s.charAt(start++); - if(octalChars.indexOf(ch) == -1) - { - --start; - break; - } - val = val * 8 + parseInt(ch); - } - if(val > 255) - { - var msg = "octal value \\" + val.toString(8) + " (" + val + ") is out of range"; - throw new Error(msg); - } - c = val; - break; - } - default: - { - c = checkChar(s, start++); - break; - } - } - } - nextStart.value = start; - return c; - } - - // - // Remove escape sequences from s and append the result to sb. - // Return true if successful, false otherwise. - // - function decodeString(s, start, end, arr) - { - var nextStart = { 'value': 0 }, c, c2, c3; - while(start < end) - { - c = decodeChar(s, start, end, nextStart); - start = nextStart.value; - - if(c < 128) - { - arr.push(String.fromCharCode(c)); - } - else if(c > 191 && c < 224) - { - c2 = decodeChar(s, start, end, nextStart); - start = nextStart.value; - arr.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); - } - else - { - c2 = decodeChar(s, start, end, nextStart); - start = nextStart.value; - c3 = decodeChar(s, start, end, nextStart); - start = nextStart.value; - arr.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); - } - } - } - + }, // // Remove escape sequences added by escapeString. Throws Error // for an invalid input string. // - StringUtil.unescapeString = function(s, start, end) + unescapeString: function(s, start, end) { start = start === undefined ? 0 : start; end = end === undefined ? s.length : end; @@ -366,12 +113,11 @@ decodeString(s, start, end, arr); return arr.join(""); - }; - + }, // // Split string helper; returns null for unmatched quotes // - StringUtil.splitString = function(str, delim) + splitString: function(str, delim) { var v = []; var s = ""; @@ -431,15 +177,14 @@ } return v; - }; - + }, // // If a single or double quotation mark is found at the start position, // then the position of the matching closing quote is returned. If no // quotation mark is found at the start position, then 0 is returned. // If no matching closing quote is found, then -1 is returned. // - StringUtil.checkQuote = function(s, start) + checkQuote: function(s, start) { start = start === undefined ? 0 : start; @@ -460,9 +205,8 @@ return -1; // Unmatched quote } return 0; // Not quoted - }; - - StringUtil.hashCode = function(s) + }, + hashCode: function(s) { var hash = 0; var n = s.length; @@ -473,9 +217,8 @@ } return hash; - }; - - StringUtil.toInt = function(s) + }, + toInt: function(s) { var n = parseInt(s, 10); if(isNaN(n)) @@ -483,8 +226,251 @@ throw new Error("conversion of `" + s + "' to int failed"); } return n; - }; + } +}; +module.exports.Ice = Ice; + +// +// Write the byte b as an escape sequence if it isn't a printable ASCII +// character and append the escape sequence to sb. Additional characters +// that should be escaped can be passed in special. If b is any of these +// characters, b is preceded by a backslash in sb. +// +function encodeChar(b, sb, special) +{ + switch(b) + { + case 92: // '\\' + { + sb.push("\\\\"); + break; + } + case 39: // '\'' + { + sb.push("\\'"); + break; + } + case 34: // '"' + { + sb.push("\\\""); + break; + } + case 8: // '\b' + { + sb.push("\\b"); + break; + } + case 12: // '\f' + { + sb.push("\\f"); + break; + } + case 10: // '\n' + { + sb.push("\\n"); + break; + } + case 13: // '\r' + { + sb.push("\\r"); + break; + } + case 9: // '\t' + { + sb.push("\\t"); + break; + } + default: + { + if(!(b >= 32 && b <= 126)) + { + sb.push('\\'); + var octal = b.toString(8); + // + // Add leading zeroes so that we avoid problems during + // decoding. For example, consider the encoded string + // \0013 (i.e., a character with value 1 followed by + // the character '3'). If the leading zeroes were omitted, + // the result would be incorrectly interpreted by the + // decoder as a single character with value 11. + // + for(var j = octal.length; j < 3; j++) + { + sb.push('0'); + } + sb.push(octal); + } + else + { + var c = String.fromCharCode(b); + if(special !== null && special.indexOf(c) !== -1) + { + sb.push('\\'); + sb.push(c); + } + else + { + sb.push(c); + } + } + } + } +} +function checkChar(s, pos) +{ + var n = s.charCodeAt(pos); + if(!(n >= 32 && n <= 126)) + { + var msg; + if(pos > 0) + { + msg = "character after `" + s.substring(0, pos) + "'"; + } + else + { + msg = "first character"; + } + msg += " is not a printable ASCII character (ordinal " + n + ")"; + throw new Error(msg); + } + return n; +} + +// +// Decode the character or escape sequence starting at start and return it. +// nextStart is set to the index of the first character following the decoded +// character or escape sequence. +// +function decodeChar(s, start, end, nextStart) +{ + Debug.assert(start >= 0); + Debug.assert(end <= s.length); + + if(start >= end) + { + throw new Error("EOF while decoding string"); + } - Ice.StringUtil = StringUtil; - global.Ice = Ice; -}(typeof (global) === "undefined" ? window : global)); + var c; + + if(s.charAt(start) != '\\') + { + c = checkChar(s, start++); + } + else + { + if(start + 1 == end) + { + throw new Error("trailing backslash"); + } + switch(s.charAt(++start)) + { + case '\\': + case '\'': + case '"': + { + c = s.charCodeAt(start++); + break; + } + case 'b': + { + ++start; + c = "\b".charCodeAt(0); + break; + } + case 'f': + { + ++start; + c = "\f".charCodeAt(0); + break; + } + case 'n': + { + ++start; + c = "\n".charCodeAt(0); + break; + } + case 'r': + { + ++start; + c = "\r".charCodeAt(0); + break; + } + case 't': + { + ++start; + c = "\t".charCodeAt(0); + break; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + var octalChars = "01234567"; + var val = 0; + for(var j = 0; j < 3 && start < end; ++j) + { + var ch = s.charAt(start++); + if(octalChars.indexOf(ch) == -1) + { + --start; + break; + } + val = val * 8 + parseInt(ch); + } + if(val > 255) + { + var msg = "octal value \\" + val.toString(8) + " (" + val + ") is out of range"; + throw new Error(msg); + } + c = val; + break; + } + default: + { + c = checkChar(s, start++); + break; + } + } + } + nextStart.value = start; + return c; +} + +// +// Remove escape sequences from s and append the result to sb. +// Return true if successful, false otherwise. +// +function decodeString(s, start, end, arr) +{ + var nextStart = { 'value': 0 }, c, c2, c3; + while(start < end) + { + c = decodeChar(s, start, end, nextStart); + start = nextStart.value; + + if(c < 128) + { + arr.push(String.fromCharCode(c)); + } + else if(c > 191 && c < 224) + { + c2 = decodeChar(s, start, end, nextStart); + start = nextStart.value; + arr.push(String.fromCharCode(((c & 31) << 6) | (c2 & 63))); + } + else + { + c2 = decodeChar(s, start, end, nextStart); + start = nextStart.value; + c3 = decodeChar(s, start, end, nextStart); + start = nextStart.value; + arr.push(String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63))); + } + } +} |