| Index: src/uri.js
|
| diff --git a/src/uri.js b/src/uri.js
|
| index b195f3da79cc67f2779cb41d3637f32281d768ad..ed7917618e31ba1c4df2edf291aaaea1c48bc06e 100644
|
| --- a/src/uri.js
|
| +++ b/src/uri.js
|
| @@ -165,11 +165,11 @@ function URIDecodeOctets(octets, result, index) {
|
| throw new $URIError("URI malformed");
|
| }
|
| if (value < 0x10000) {
|
| - result[index++] = value;
|
| + %_TwoByteSeqStringSetChar(result, index++, value);
|
| return index;
|
| } else {
|
| - result[index++] = (value >> 10) + 0xd7c0;
|
| - result[index++] = (value & 0x3ff) + 0xdc00;
|
| + %_TwoByteSeqStringSetChar(result, index++, (value >> 10) + 0xd7c0);
|
| + %_TwoByteSeqStringSetChar(result, index++, (value & 0x3ff) + 0xdc00);
|
| return index;
|
| }
|
| }
|
| @@ -178,43 +178,72 @@ function URIDecodeOctets(octets, result, index) {
|
| // ECMA-262, section 15.1.3
|
| function Encode(uri, unescape) {
|
| var uriLength = uri.length;
|
| - // We are going to pass result to %StringFromCharCodeArray
|
| - // which does not expect any getters/setters installed
|
| - // on the incoming array.
|
| - var result = new InternalArray(uriLength);
|
| + var array = new InternalArray(uriLength);
|
| var index = 0;
|
| for (var k = 0; k < uriLength; k++) {
|
| var cc1 = uri.charCodeAt(k);
|
| if (unescape(cc1)) {
|
| - result[index++] = cc1;
|
| + array[index++] = cc1;
|
| } else {
|
| if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw new $URIError("URI malformed");
|
| if (cc1 < 0xD800 || cc1 > 0xDBFF) {
|
| - index = URIEncodeSingle(cc1, result, index);
|
| + index = URIEncodeSingle(cc1, array, index);
|
| } else {
|
| k++;
|
| if (k == uriLength) throw new $URIError("URI malformed");
|
| var cc2 = uri.charCodeAt(k);
|
| if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw new $URIError("URI malformed");
|
| - index = URIEncodePair(cc1, cc2, result, index);
|
| + index = URIEncodePair(cc1, cc2, array, index);
|
| }
|
| }
|
| }
|
| - return %StringFromCharCodeArray(result);
|
| +
|
| + var result = %NewString(array.length, true);
|
| + for (var i = 0; i < array.length; i++) {
|
| + %_OneByteSeqStringSetChar(result, i, array[i]);
|
| + }
|
| + return result;
|
| }
|
|
|
|
|
| // ECMA-262, section 15.1.3
|
| function Decode(uri, reserved) {
|
| var uriLength = uri.length;
|
| - // We are going to pass result to %StringFromCharCodeArray
|
| - // which does not expect any getters/setters installed
|
| - // on the incoming array.
|
| - var result = new InternalArray(uriLength);
|
| + var one_byte = %NewString(uriLength, true);
|
| var index = 0;
|
| - for (var k = 0; k < uriLength; k++) {
|
| - var ch = uri.charAt(k);
|
| - if (ch == '%') {
|
| + var k = 0;
|
| +
|
| + // Optimistically assume ascii string.
|
| + for ( ; k < uriLength; k++) {
|
| + var code = uri.charCodeAt(k);
|
| + if (code == 37) { // '%'
|
| + if (k + 2 >= uriLength) throw new $URIError("URI malformed");
|
| + var cc = URIHexCharsToCharCode(uri.charCodeAt(k+1), uri.charCodeAt(k+2));
|
| + if (cc >> 7) break; // Assumption wrong, two byte string.
|
| + if (reserved(cc)) {
|
| + %_OneByteSeqStringSetChar(one_byte, index++, 37); // '%'.
|
| + %_OneByteSeqStringSetChar(one_byte, index++, uri.charCodeAt(k+1));
|
| + %_OneByteSeqStringSetChar(one_byte, index++, uri.charCodeAt(k+2));
|
| + } else {
|
| + %_OneByteSeqStringSetChar(one_byte, index++, cc);
|
| + }
|
| + k += 2;
|
| + } else {
|
| + if (code > 0x7f) break; // Assumption wrong, two byte string.
|
| + %_OneByteSeqStringSetChar(one_byte, index++, code);
|
| + }
|
| + }
|
| +
|
| + one_byte = TruncateString(one_byte, index);
|
| + if (k == uriLength) return one_byte;
|
| +
|
| + // Write into two byte string.
|
| + var two_byte = %NewString(uriLength - k, false);
|
| + index = 0;
|
| +
|
| + for ( ; k < uriLength; k++) {
|
| + var code = uri.charCodeAt(k);
|
| + if (code == 37) { // '%'
|
| if (k + 2 >= uriLength) throw new $URIError("URI malformed");
|
| var cc = URIHexCharsToCharCode(uri.charCodeAt(++k), uri.charCodeAt(++k));
|
| if (cc >> 7) {
|
| @@ -229,22 +258,21 @@ function Decode(uri, reserved) {
|
| octets[i] = URIHexCharsToCharCode(uri.charCodeAt(++k),
|
| uri.charCodeAt(++k));
|
| }
|
| - index = URIDecodeOctets(octets, result, index);
|
| + index = URIDecodeOctets(octets, two_byte, index);
|
| + } else if (reserved(cc)) {
|
| + %_TwoByteSeqStringSetChar(two_byte, index++, 37); // '%'.
|
| + %_TwoByteSeqStringSetChar(two_byte, index++, uri.charCodeAt(k - 1));
|
| + %_TwoByteSeqStringSetChar(two_byte, index++, uri.charCodeAt(k));
|
| } else {
|
| - if (reserved(cc)) {
|
| - result[index++] = 37; // Char code of '%'.
|
| - result[index++] = uri.charCodeAt(k - 1);
|
| - result[index++] = uri.charCodeAt(k);
|
| - } else {
|
| - result[index++] = cc;
|
| - }
|
| + %_TwoByteSeqStringSetChar(two_byte, index++, cc);
|
| }
|
| } else {
|
| - result[index++] = ch.charCodeAt(0);
|
| + %_TwoByteSeqStringSetChar(two_byte, index++, code);
|
| }
|
| }
|
| - result.length = index;
|
| - return %StringFromCharCodeArray(result);
|
| +
|
| + two_byte = TruncateString(two_byte, index);
|
| + return one_byte + two_byte;
|
| }
|
|
|
|
|
|
|