[pygobject] Support gunichar



commit f129b3db2c78d3cce3614993fdd1619fb9eb9c79
Author: Paolo Borelli <pborelli gnome org>
Date:   Sun Nov 21 12:16:53 2010 +0100

    Support gunichar
    
    https://bugzilla.gnome.org/show_bug.cgi?id=623615

 gi/pygi-argument.c       |   60 ++++++++++++++++++++++++++++++++++++++++++++++
 gi/pygi-info.c           |    5 ++++
 tests/test_everything.py |    5 ++++
 3 files changed, 70 insertions(+), 0 deletions(-)
---
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 8eaf8ba..7128a28 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -378,6 +378,8 @@ check_number_release:
             }
             break;
         }
+        case GI_TYPE_TAG_UNICHAR:
+            /* TODO: check if it is a single valid utf8 character? */
         case GI_TYPE_TAG_UTF8:
         case GI_TYPE_TAG_FILENAME:
             if (!PYGLIB_PyBaseString_Check (object) ) {
@@ -761,6 +763,42 @@ _pygi_argument_from_object (PyObject   *object,
 
             break;
         }
+        case GI_TYPE_TAG_UNICHAR:
+        {
+            gchar *string;
+
+            if (object == Py_None) {
+                arg.v_uint32 = 0;
+                break;
+            }
+
+#if PY_VERSION_HEX < 0x03000000
+            if (PyUnicode_Check(object)) {
+                 PyObject *pystr_obj = PyUnicode_AsUTF8String (object);
+
+                 if (!pystr_obj)
+                     break;
+
+                 string = g_strdup(PyString_AsString (pystr_obj));
+                 Py_DECREF(pystr_obj);
+            } else {
+                 string = g_strdup(PyString_AsString (object));
+            }
+#else
+            {
+                PyObject *pybytes_obj = PyUnicode_AsUTF8String (object);
+                if (!pybytes_obj)
+                    break;
+
+                string = g_strdup(PyBytes_AsString (pybytes_obj));
+                Py_DECREF (pybytes_obj);
+            }
+#endif
+
+            arg.v_uint32 = g_utf8_get_char (string);
+
+            break;
+        }
         case GI_TYPE_TAG_UTF8:
         {
             gchar *string;
@@ -1279,6 +1317,27 @@ _pygi_argument_to_object (GIArgument  *arg,
             object = pyg_type_wrapper_new ( (GType) arg->v_long);
             break;
         }
+        case GI_TYPE_TAG_UNICHAR:
+        {
+            /* Preserve the bidirectional mapping between 0 and "" */
+            if (arg->v_uint32 == 0) {
+                object = PYGLIB_PyUnicode_FromString ("");
+            } else if (g_unichar_validate (arg->v_uint32)) {
+                gchar utf8[7];
+                gint bytes;
+
+                bytes = g_unichar_to_utf8 (arg->v_uint32, &utf8);
+                object = PYGLIB_PyUnicode_FromStringAndSize ((char*)utf8, bytes);
+            } else {
+                /* TODO: Convert the error to an exception. */
+                PyErr_Format (PyExc_TypeError,
+                              "Invalid unicode codepoint %" G_GUINT32_FORMAT,
+                              arg->v_uint32);
+                object = Py_None;
+                Py_INCREF (object);
+            }
+            break;
+        }
         case GI_TYPE_TAG_UTF8:
             if (arg->v_string == NULL) {
                 object = Py_None;
@@ -1662,6 +1721,7 @@ _pygi_argument_release (GIArgument   *arg,
         case GI_TYPE_TAG_FLOAT:
         case GI_TYPE_TAG_DOUBLE:
         case GI_TYPE_TAG_GTYPE:
+        case GI_TYPE_TAG_UNICHAR:
             break;
         case GI_TYPE_TAG_FILENAME:
         case GI_TYPE_TAG_UTF8:
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 33f71c1..9d15e5e 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -349,6 +349,9 @@ _pygi_g_type_tag_size (GITypeTag type_tag)
         case GI_TYPE_TAG_GTYPE:
             size = sizeof (GType);
             break;
+        case GI_TYPE_TAG_UNICHAR:
+            size = sizeof (gunichar);
+            break;
         case GI_TYPE_TAG_VOID:
         case GI_TYPE_TAG_UTF8:
         case GI_TYPE_TAG_FILENAME:
@@ -388,6 +391,7 @@ _pygi_g_type_info_size (GITypeInfo *type_info)
         case GI_TYPE_TAG_FLOAT:
         case GI_TYPE_TAG_DOUBLE:
         case GI_TYPE_TAG_GTYPE:
+        case GI_TYPE_TAG_UNICHAR:
             if (g_type_info_is_pointer (type_info)) {
                 size = sizeof (gpointer);
             } else {
@@ -767,6 +771,7 @@ pygi_g_struct_info_is_simple (GIStructInfo *struct_info)
             case GI_TYPE_TAG_UINT64:
             case GI_TYPE_TAG_FLOAT:
             case GI_TYPE_TAG_DOUBLE:
+            case GI_TYPE_TAG_UNICHAR:
                 if (g_type_info_is_pointer (field_type_info)) {
                     is_simple = FALSE;
                 }
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 6e77a3d..ee19e6b 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -48,6 +48,11 @@ class TestEverything(unittest.TestCase):
         self.assertEquals(surface.get_width(), 10)
         self.assertEquals(surface.get_height(), 10)
 
+    def test_unichar(self):
+        self.assertEquals("c", Everything.test_unichar("c"))
+        self.assertEquals("", Everything.test_unichar(""))
+        self.assertEquals("\xe2\x99\xa5", Everything.test_unichar("\xe2\x99\xa5"))
+
     def test_floating(self):
         Everything.TestFloating()
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]