[mw-devel] MARVIN r82 - branches/smonkey

welshbyte at sucs.org welshbyte at sucs.org
Wed Jul 26 03:22:48 BST 2006


Author: welshbyte
Date: 2006-07-26 03:22:45 +0100 (Wed, 26 Jul 2006)
New Revision: 82

Modified:
   branches/smonkey/client.js
   branches/smonkey/js.c
   branches/smonkey/server.c
   branches/smonkey/server.js
Log:
Started doing the JSString creation needed by js_exec() but having trouble
with character sets and iconv etc. Copied and modified some of pwb's iconv
code from mw to write local2jschars() but it's not working at all at the
moment.


Modified: branches/smonkey/client.js
===================================================================
--- branches/smonkey/client.js	2006-07-21 13:38:31 UTC (rev 81)
+++ branches/smonkey/client.js	2006-07-26 02:22:45 UTC (rev 82)
@@ -0,0 +1,4 @@
+// Called when the server breaks the connection
+function shutdown() {
+	print("Javascript says: So long, and thanks for all the fish...\n");
+}

Modified: branches/smonkey/js.c
===================================================================
--- branches/smonkey/js.c	2006-07-21 13:38:31 UTC (rev 81)
+++ branches/smonkey/js.c	2006-07-26 02:22:45 UTC (rev 82)
@@ -1,5 +1,7 @@
 #include <stdarg.h>
 #include <string.h>
+#include <errno.h>
+#include <wchar.h>
 
 #include "xml.h"
 #include "js.h"
@@ -8,10 +10,10 @@
 JSContext *jscx;
 JSObject *jsglob;
 JSClass globclass = {
-		"global",0,
-		JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
-        JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
-	};
+	"milliways",0,
+	JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
+	JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
+};
 
 /* Function for printing to standard out from javascript (helpful for
  * debugging and demonstrates how to call C from js)
@@ -28,20 +30,82 @@
 		if (JSVAL_IS_STRING(argv[i])) {
 			jsmsg = JS_ValueToString(cx,argv[i]);
 			ucmsg = JS_GetStringBytes(jsmsg);
+			/* TODO: Might need to convert ucmsg to the local charset here */
 			printf("%s", ucmsg);
 		}
+		/* TODO: Cases where argv[i] is of a different type */
 	}
 	return JS_TRUE;
 }
 
+/* Convert a string from local charset to a string of jschar which
+   JS_NewUCString() needs to create a new JSString with unicode 
+   characters in. An appropriate jschar* is created by casting 
+   UTF-16 data to jschar*, which is why we encode to UTF-16 here. */
+jschar *
+local2jschars(wchar_t * local) {
+	jschar * utf16;
+	char * charset;
+	iconv_t conv;
+	int nconv;
+	size_t localbytesleft;
+	size_t utf16bytesleft;
+	char * localcpy;
+	char * utf16cpy;
+
+	charset = "WCHAR_T";
+	conv = iconv_open("UTF-16", charset);
+	if (conv == (iconv_t)-1) {
+		fprintf(stderr, "local2utf16 bombed.\n");
+		return NULL;
+	}
+	
+	localbytesleft = (wcslen(local)) * sizeof(wchar_t);
+	utf16 = malloc(wcslen(local) * sizeof(jschar));
+	if (utf16 == NULL) {
+		fprintf(stderr, "Could not allocate memory for iconv\n");
+		return NULL;
+	}
+	
+	localcpy = (char *)local;
+	utf16cpy = (char *)utf16;
+	
+	while (localbytesleft > 0) {
+		nconv = iconv(conv, 
+			&localcpy, &localbytesleft, 
+			&utf16cpy, &utf16bytesleft);
+		if (nconv == (size_t)-1) {
+			fprintf(stderr, "local2jschars barfed (%d)\n", errno);
+			/* iconv barfed, but why? */
+			if (errno == EILSEQ || errno == EINVAL) {
+				/* invalid input sequence, skip it */
+				fprintf(stderr, "Invalid input sequence\n");
+				local++;
+				localbytesleft--;
+				errno = 0;
+				continue;
+			} else {
+				/* some other error, recover what we can */
+				fprintf(stderr, "Some other error\n");
+				*(char *)utf16 = '\0';
+				perror("iconv");
+				errno = 0;
+				break;
+			}
+		}
+	}
+	iconv_close(conv);
+	return utf16;
+}
+
 /* Execute some javascript commands */
 int
 js_exec(char * name, char * fmt, ...) {
 	va_list ap;
 	double a_double;
 	int an_int;
-	char * a_string;
-	char * strbytes;
+	wchar_t * a_string;
+	jschar * js_string;
 	xmlDocPtr a_xml;
 	int argc;
 	jsval argv[10]; /* Static for now, 10 should suffice */
@@ -71,15 +135,19 @@
 			}
 			break;
 		case 's':
-			a_string = va_arg(ap, char *);
+			a_string = va_arg(ap, wchar_t *);
 			/* js will handle this chunk of memory, do not free() strbytes */
-			strbytes = (char *)JS_malloc(jscx, sizeof(a_string));
-			if (strbytes == NULL) {
+			js_string = (jschar *)JS_malloc(jscx, sizeof(jschar) * wcslen(a_string));
+			if (!js_string || js_string == NULL) {
 				fprintf(stderr, "Could not allocate memory for string. Aborting slang_exec(%s)\n", name);
 				return -1;
 			}
-			strcpy(strbytes, a_string);
-			argv[argc] = STRING_TO_JSVAL(JS_NewString(jscx, strbytes, strlen(strbytes)));
+			js_string = local2jschars(a_string);
+			if (js_string != NULL) {
+				argv[argc] = STRING_TO_JSVAL(JS_NewUCString(jscx, js_string, wcslen(a_string)));
+			} else {
+				argv[argc] = STRING_TO_JSVAL(JS_NewString(jscx, "(Garbled string)", 16));
+			}
 			break;
 		case 'x':
 			a_xml = va_arg(ap, xmlDocPtr);

Modified: branches/smonkey/server.c
===================================================================
--- branches/smonkey/server.c	2006-07-21 13:38:31 UTC (rev 81)
+++ branches/smonkey/server.c	2006-07-26 02:22:45 UTC (rev 82)
@@ -164,7 +164,7 @@
 		return -1;
 	}
 	load_js("server.js");
-	js_exec("test","dis",(double)42, (int)69, "PootPoot!");
+	js_exec("test","dis",(double)42.3, (int)69, L"PootPoot!ツ\n");
 
 	getsockname(main_socket, (struct sockaddr *)&addr, &size);
 	printf("Server started on %s port %d\n", inet_ntop(addr.sin6_family,&(addr.sin6_addr),addr_buff,128), ntohs(addr.sin6_port) );

Modified: branches/smonkey/server.js
===================================================================
--- branches/smonkey/server.js	2006-07-21 13:38:31 UTC (rev 81)
+++ branches/smonkey/server.js	2006-07-26 02:22:45 UTC (rev 82)
@@ -1,6 +1,15 @@
-print("♫ Does marvin like UTF8? ♫\n");
+print("♫ Does marvin like UTF8? ♫ ... ツ\n");
 
 function test (foo, bar, baz) {
 	quux = "double: " + foo + " int: " + bar + " string: " + baz + "\n";
-	print(quux)
+	print(quux);
 }
+
+function msg_recv(foo, bar, baz, quux) {
+	quuux = "msg_recv(" + foo + "," + bar + "," + baz + "," + quux + ")\n";
+	print(quux);
+}
+
+function session_gone(sess) {
+	message = "session_gone: " + sess + "\n";
+}




More information about the mw-devel mailing list