From e2d9fe135481bdc0e91983662ef8ceaea09dd685 Mon Sep 17 00:00:00 2001
From: user <user@user-ThinkPad-X60.(none)>
Date: Sun, 3 May 2015 16:39:00 -0400
Subject: [PATCH] use string-decoder lib to handle utf8 correctly over the tcp
 socket

---
 pd/nw/pdgui.js | 116 +++++++++++++++++++++++--------------------------
 1 file changed, 55 insertions(+), 61 deletions(-)

diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 9b1b36811..57ff069fc 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -1715,70 +1715,64 @@ exports.connect = connect;
 // characters from pd->gui messages.  Because of this a newline is added in
 // gui_post.  Once all the old tcl messages are removed we can parse solely
 // on ";", and the side effect can be removed.
-
 // can be removed.
 
-var plums = require('string_decoder').StringDecoder;
-var rufus = new plums('utf8');
-
-var nextCmd = ""; // Build up a command across lines (or buffers)
-var cmdHeader = 0;
+// StringDecoder is used to make sure UTF8 characters which happen to
+// straddle buffers get handled correctly.  If this proves too slow, there's
+// a Buffer Tools lib in Node.js that's more powerful.  But for now this seems
+// fine...
+var StringDecoder = require('string_decoder').StringDecoder;
 
 function init_socket_events () {
-	client.on('data', function(data) {
-	//    console.log('DATA: ' + data);
-	      var dataStr = data.toString('utf-8');
-
-              var mumps = rufus.write(data);
-              if (rufus.end() !== "") {
-                  console.log("fuckkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, we got hitchikers... " + rufus.end());
-              }
-
-
-//	      console.log("The whole buffer is " + dataStr);
-//              if (nextCmd !== "") {
-//                  console.log("fuckkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk nextCmd is " + nextCmd);
-//              }
-	      var arr = dataStr.split("\n");
-	      var arrLen = arr.length;
-	      for (var i = 0; i < arrLen; i++) {
-		  var prefix = arr[i].substring(0, 2);
-		  if (prefix == 'nw' || prefix == 'nn') {
-		      nextCmd = arr[i].substring(3);
-//	              console.log("nextCmd is " + nextCmd);
-		      cmdHeader = 1;
-		  } else if (cmdHeader) {
-		      nextCmd += arr[i];
-	//              console.log("2nd part of cmd is " + arr[i]);
-		  } else {
-//		      gui_post(arr[i], "blue");
-		  }
-		  // check if we end with a semicolon followed by a newline
-		  if (nextCmd.slice(-1) === ";" && nextCmd.slice(-2) !== '\\') {
-//console.log("raw cmd is: " + nextCmd);
-//		      nextCmd = nextCmd.replace(/\n/g, "\\n");
-//		      nextCmd = nextCmd.replace(/'/g, "\\\'");
-		      var selector = nextCmd.slice(0, nextCmd.indexOf(" "));
-		      var args = nextCmd.slice(selector.length + 1, -1);
-//                      console.log("About to eval: " + selector + '(' + args + ');');
-                      eval(selector + '(' + args + ');');
-		      nextCmd = "";
-		      cmdHeader = 0;
-		  }
-
-	      }
-	    // Close the client socket completely
-	//    client.destroy();
-	//    console.log('Connection closed');
-
-	 });
-
-	// Add a 'close' event handler for the client socket
-	 client.on('close', function() {
-	     //console.log('Connection closed');
-             //client.destroy();
-             nw_app_quit(); // set a timeout here if you need to debug
-	 });
+    var decoder = new StringDecoder('utf8');
+    var nextCmd = ""; // Build up a command across lines (or buffers)
+    var cmdHeader = 0;
+
+    client.on('data', function(data) {
+        var dataStr = decoder.write(data);
+        // For debugging the buffer...
+        //if (decoder.end() !== "") {
+        //    console.log("utf8 multi-byte character split across buffer");
+        //    console.log("end bytes are " + decoder.end());
+        //}
+        var arr = dataStr.split("\n");
+        var arrLen = arr.length;
+        for (var i = 0; i < arrLen; i++) {
+            var prefix = arr[i].substring(0, 2);
+            if (prefix == 'nw' || prefix == 'nn') {
+                nextCmd = arr[i].substring(3);
+                //console.log("nextCmd is " + nextCmd);
+                cmdHeader = 1;
+            } else if (cmdHeader) {
+	        nextCmd += arr[i];
+                //console.log("2nd part of cmd is " + arr[i]);
+            } else {
+                // Show the remaining old tcl/tk messages in blue
+                //gui_post(arr[i], "blue");
+            }
+            // check if we end with a semicolon followed by a newline
+            if (nextCmd.slice(-1) === ";" && nextCmd.slice(-2) !== '\\') {
+                //nextCmd = nextCmd.replace(/\n/g, "\\n");
+                //nextCmd = nextCmd.replace(/'/g, "\\\'");
+                var selector = nextCmd.slice(0, nextCmd.indexOf(" "));
+                var args = nextCmd.slice(selector.length + 1, -1);
+                //console.log("About to eval: " + selector + '(' + args + ');');
+                 eval(selector + '(' + args + ');');
+                 nextCmd = "";
+                 cmdHeader = 0;
+            }
+	}
+	// client.destroy();
+	// console.log('Connection closed');
+
+    });
+
+    // Add a 'close' event handler for the client socket
+    client.on('close', function() {
+        //console.log('Connection closed');
+        //client.destroy();
+        nw_app_quit(); // set a timeout here if you need to debug
+    });
 }
 
 exports.init_socket_events = init_socket_events;
@@ -1787,7 +1781,7 @@ exports.init_socket_events = init_socket_events;
 function pdsend(string) {
     client.write(string + ';');
     // for now, let's reprint the outgoing string to the pdwindow
-//    gui_post(string + ';', "red");
+    // gui_post(string + ';', "red");
 }
 
 exports.pdsend = pdsend;
-- 
GitLab