changeset 132:537cf7deadc9

Added a new PYM_UTF16String C++ class to make calling UC JSAPI functions a little easier and less error-prone.
author Atul Varma <varmaa@toolness.com>
date Sun, 23 Aug 2009 18:43:46 -0700
parents f956a6dea16c
children a9c0db56e06b
files src/context.cpp src/utils.h
diffstat 2 files changed, 38 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/src/context.cpp	Sun Aug 23 18:04:21 2009 -0700
+++ b/src/context.cpp	Sun Aug 23 18:43:46 2009 -0700
@@ -233,22 +233,17 @@
                         "utf-16", &buffer, &size))
     return NULL;
 
-  if (self->runtime != object->runtime) {
-    PyMem_Free(buffer);
-    PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime);
-  }
+  PYM_UTF16String str(buffer, size);
+
+  PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime);
 
   jsval val;
   JSBool result;
   Py_BEGIN_ALLOW_THREADS;
-  // Note that we're manipulating buffer and size here to get rid of
-  // the BOM.
-  result = JS_GetUCProperty(self->cx, object->obj, (jschar *) (buffer + 2),
-                            (size / 2) - 1, &val);
+  result = JS_GetUCProperty(self->cx, object->obj, str.jsbuffer,
+                            str.jslen, &val);
   Py_END_ALLOW_THREADS;
 
-  PyMem_Free(buffer);
-
   if (!result) {
     PYM_jsExceptionToPython(self);
     return NULL;
@@ -298,22 +293,17 @@
                         "utf-16", &source, &sourceLen, &filename, &lineNo))
     return NULL;
 
-  if (self->runtime != object->runtime) {
-    PyMem_Free(source);
-    PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime);
-  }
+  PYM_UTF16String str(source, sourceLen);
+
+  PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime);
 
   jsval rval;
   JSBool result;
   Py_BEGIN_ALLOW_THREADS;
-  // Note that we're manipulating buffer and size here to get rid of
-  // the BOM.
-  result = JS_EvaluateUCScript(self->cx, object->obj, (jschar *) (source + 2),
-                               (sourceLen / 2) - 1, filename, lineNo, &rval);
+  result = JS_EvaluateUCScript(self->cx, object->obj, str.jsbuffer,
+                               str.jslen, filename, lineNo, &rval);
   Py_END_ALLOW_THREADS;
 
-  PyMem_Free(source);
-
   if (!result) {
     PYM_jsExceptionToPython(self);
     return NULL;
@@ -336,31 +326,23 @@
                         "utf-16", &name, &namelen, &value))
     return NULL;
 
-  if (self->runtime != object->runtime) {
-    PyMem_Free(name);
-    PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime);
-  }
-
+  PYM_UTF16String str(name, namelen);
   jsval jsValue;
 
-  if (PYM_pyObjectToJsval(self, value, &jsValue) == -1) {
-    PyMem_Free(name);
-    return NULL;
-  }
+  PYM_ENSURE_RUNTIME_MATCH(self->runtime, object->runtime);
 
-  // Note that we're manipulating buffer and size here to get rid of
-  // the BOM.
-  if (!JS_DefineUCProperty(self->cx, object->obj, (jschar *) (name + 2),
-                           (namelen / 2) - 1, jsValue, NULL, NULL,
+  if (PYM_pyObjectToJsval(self, value, &jsValue) == -1)
+    return NULL;
+
+  if (!JS_DefineUCProperty(self->cx, object->obj, str.jsbuffer,
+                           str.jslen, jsValue, NULL, NULL,
                            JSPROP_ENUMERATE)) {
     // TODO: There's probably an exception pending on self->cx,
     // what should we do about it?
-    PyMem_Free(name);
     PyErr_SetString(PYM_error, "JS_DefineProperty() failed");
     return NULL;
   }
 
-  PyMem_Free(name);
   Py_RETURN_NONE;
 }
 
--- a/src/utils.h	Sun Aug 23 18:04:21 2009 -0700
+++ b/src/utils.h	Sun Aug 23 18:43:46 2009 -0700
@@ -43,6 +43,27 @@
 #include <jsdhash.h>
 #include <Python.h>
 
+// Simple class that holds on to a UTF-16 string created by
+// PyArg_ParseTuple() for as long as it's in scope.  It also
+// provides easy BOM-stripping accessors for JS-land.
+class PYM_UTF16String {
+public:
+  PYM_UTF16String(char *buffer, int size) : jsbuffer((jschar *) (buffer + 2)),
+    jslen(size / 2 - 1), pybuffer(buffer), pysize(size) {
+  }
+
+  ~PYM_UTF16String() {
+    PyMem_Free(pybuffer);
+  }
+
+  jschar *jsbuffer;
+  size_t jslen;
+
+protected:
+  char *pybuffer;
+  int pysize;
+};
+
 // Simple class that holds the Python global interpreter lock (GIL)
 // for as long as it's in scope.
 class PYM_PyAutoEnsureGIL {