THRIFT-885: fix string encoding

git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@998371 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/js/thrift.js b/lib/js/thrift.js
index f048dbf..9b92658 100644
--- a/lib/js/thrift.js
+++ b/lib/js/thrift.js
@@ -169,13 +169,13 @@
 
     //Gets the browser specific XmlHttpRequest Object
     getXmlHttpRequestObject : function() {
-	
+    
         try { return new XMLHttpRequest() } catch(e) {}
         try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
         try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}
 
         throw "Your browser doesn't support the XmlHttpRequest object.  Try upgrading to Firefox."
-	
+    
     },
 
     flush : function(){
@@ -185,7 +185,7 @@
             return this.send_buf;
 
         var xreq = this.getXmlHttpRequestObject()
-        		
+                
         if (xreq.overrideMimeType)
             xreq.overrideMimeType("application/json")
         
@@ -451,7 +451,42 @@
     },
 
     writeString : function(str){
-        this.tstack.push('"'+encodeURIComponent(str)+'"');
+        // We do not encode uri components for wire transfer: 
+        if(str === null) {
+            this.tstack.push(null);
+        } else {
+            // concat may be slower than building a byte buffer
+            var escapedString = "";
+            for(var i = 0; i < str.length; i++) {
+                var ch = str.charAt(i);          // a single double quote: "
+                if(ch === '\"') {
+                    escapedString += '\\\"';     // write out as: \"
+                } else if(ch === '\\') {         // a single backslash: \
+                    escapedString += '\\\\';     // write out as: \\
+                /* Currently escaped forward slashes break TJSONProtocol.
+                 * As it stands, we can simply pass forward slashes into our strings
+                 * across the wire without being escaped.
+                 * I think this is the protocol's bug, not thrift.js
+                 * } else if(ch === '/') {       // a single forward slash: /
+                 *  escapedString += '\\/';      // write out as \/
+                 * } 
+                 */
+                } else if(ch === '\b') {        // a single backspace: invisible
+                    escapedString += '\\b';     // write out as: \b"
+                } else if(ch === '\f') {        // a single formfeed: invisible
+                    escapedString += '\\f';     // write out as: \f"
+                } else if(ch === '\n') {        // a single newline: invisible
+                    escapedString += '\\n';     // write out as: \n"
+                } else if(ch === '\r') {        // a single return: invisible
+                    escapedString += '\\r';     // write out as: \r"
+                } else if(ch === '\t') {        // a single tab: invisible
+                    escapedString += '\\t';     // write out as: \t"
+                } else {
+                    escapedString += ch;        // Else it need not be escaped
+                }
+            }
+            this.tstack.push('"' + escapedString + '"');
+        }
     },
 
     writeBinary : function(str){
@@ -663,8 +698,6 @@
 
     readString : function(){
         var r = this.readI32()
-        r["value"] = decodeURIComponent(r["value"])
-        
         return r
     },