[Zope-CVS] SVN: zope.ucol/trunk/ Initial working version.

Jim Fulton jim at zope.com
Tue Dec 6 15:52:17 EST 2005


Log message for revision 40612:
  Initial working version.
  

Changed:
  A   zope.ucol/trunk/INSTALL.txt
  A   zope.ucol/trunk/README.txt
  A   zope.ucol/trunk/setup.py
  A   zope.ucol/trunk/src/
  A   zope.ucol/trunk/src/zope/
  A   zope.ucol/trunk/src/zope/__init__.py
  A   zope.ucol/trunk/src/zope/ucol/
  A   zope.ucol/trunk/src/zope/ucol/__init__.py
  A   zope.ucol/trunk/src/zope/ucol/_zope_ucol.c
  A   zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx
  A   zope.ucol/trunk/src/zope/ucol/tests.py
  A   zope.ucol/trunk/test.py

-=-
Added: zope.ucol/trunk/INSTALL.txt
===================================================================
--- zope.ucol/trunk/INSTALL.txt	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/INSTALL.txt	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,16 @@
+zope.ucol is install via setup.py in the usual way.
+
+You must have ICU installed.  If ICU isn't installed in the usual
+places for include files and libraries on your system, you can provide
+command-line options to setup.py when building the extensions, as in:
+
+ python2.4 setup.py build_ext \
+   -I/home/jim/p/z4i/jim-icu/var/opt/icu/include \
+   -L/home/jim/p/z4i/jim-icu/var/opt/icu/lib \
+   -R/home/jim/p/z4i/jim-icu/var/opt/icu/lib
+
+ python2.4 setup.py install
+
+Note that if the libraries are in an unusual place, you will want to
+specify their location using the -R option so you don't have to
+specify it at run-time.


Property changes on: zope.ucol/trunk/INSTALL.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zope.ucol/trunk/README.txt
===================================================================
--- zope.ucol/trunk/README.txt	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/README.txt	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,12 @@
+Locale-based text collation using ICU
+
+See the docstring in the zope.ucol package for usage information.
+
+See INSTALL.txt for instalation instructions.
+
+The C extension in this package was created with PyRex.  (Pyrex
+rocks!) PyRex isn't required to use the C Extension, as the pre-built
+C extension is included in this distribution. In addition, the C
+extension was hand edited to remove some excess code included by Pyrex
+that can cause compiler warnings. Hopefully, future versions of Pyrex
+will make this unnecessary.


Property changes on: zope.ucol/trunk/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zope.ucol/trunk/setup.py
===================================================================
--- zope.ucol/trunk/setup.py	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/setup.py	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,14 @@
+from distutils.core import setup, Extension
+
+setup(name='zope.ucol',
+      version='1.0',
+      ext_modules=[
+          Extension('zope.ucol._zope_ucol',
+                    ['src/zope/ucol/_zope_ucol.c'],
+                    libraries=['icui18n'],
+           )
+          ],
+      packages=["zope", "zope.ucol"],
+      package_dir = {'': 'src'},
+      )
+


Property changes on: zope.ucol/trunk/setup.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native


Property changes on: zope.ucol/trunk/src/zope
___________________________________________________________________
Name: svn:externals
   + testing -r40511 svn://svn.zope.org/repos/main/zope.testing/trunk/src/zope/testing


Added: zope.ucol/trunk/src/zope/__init__.py
===================================================================
--- zope.ucol/trunk/src/zope/__init__.py	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/src/zope/__init__.py	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1 @@
+#


Property changes on: zope.ucol/trunk/src/zope/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.ucol/trunk/src/zope/ucol/__init__.py
===================================================================
--- zope.ucol/trunk/src/zope/ucol/__init__.py	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/src/zope/ucol/__init__.py	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,39 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Locale-based text collation using ICU
+
+The zope.ucol package provides a minimal Pythonic wrapper around the
+u_col C API of the International Components for Unicode (ICU) library.
+It provides locale-based text collation.
+
+To perform collation, you need to create a collator key factory for
+your locale.  We'll use the "root" locale:
+
+    >>> import zope.ucol
+    >>> key = zope.ucol.KeyFactory("root")
+
+The factory is a callable for creating collation keys from unicode
+strings.  The factory can be passed as the key argument to list.sort
+or to the built-in sorted function.
+
+    >>> sorted([u'Sam', u'sally', u'Abe', u'alice', u'Terry', u'tim',
+    ...        u'\U00023119', u'\u62d5'], key=key)
+    [u'Abe', u'alice', u'sally', u'Sam', u'Terry', u'tim', 
+     u'\u62d5', u'\U00023119']
+
+
+$Id$
+"""
+
+from _zope_ucol import KeyFactory


Property changes on: zope.ucol/trunk/src/zope/ucol/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.ucol/trunk/src/zope/ucol/_zope_ucol.c
===================================================================
--- zope.ucol/trunk/src/zope/ucol/_zope_ucol.c	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/src/zope/ucol/_zope_ucol.c	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,984 @@
+/* Generated by Pyrex 0.9.3.1 on Tue Dec  6 15:36:00 2005 */
+
+#include "Python.h"
+#include "structmember.h"
+#ifndef PY_LONG_LONG
+  #define PY_LONG_LONG LONG_LONG
+#endif
+#include "unicode/utypes.h"
+#include "unicode/utf.h"
+#include "unicode/ustring.h"
+#include "unicode/ucol.h"
+
+
+typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
+typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
+static void __Pyx_AddTraceback(char *funcname); /*proto*/
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
+static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+
+static PyObject *__pyx_m;
+static PyObject *__pyx_b;
+static int __pyx_lineno;
+static char *__pyx_filename;
+staticforward char **__pyx_f;
+
+static char __pyx_mdoc[] = "Simple wrapper for ICU ucol API\n\n$Id$\n";
+
+/* Declarations from _zope_ucol */
+
+staticforward PyTypeObject __pyx_type_10_zope_ucol_UCharString;
+
+struct __pyx_obj_10_zope_ucol_UCharString {
+  PyObject_HEAD
+  UChar (*data);
+  int32_t length;
+  PyObject *base;
+  int need_to_free;
+};
+
+staticforward PyTypeObject __pyx_type_10_zope_ucol_KeyFactory;
+
+struct __pyx_obj_10_zope_ucol_KeyFactory {
+  PyObject_HEAD
+  UCollator (*collator);
+};
+
+static PyTypeObject *__pyx_ptype_10_zope_ucol_unicode = 0;
+static PyTypeObject *__pyx_ptype_10_zope_ucol_UCharString = 0;
+static PyTypeObject *__pyx_ptype_10_zope_ucol_KeyFactory = 0;
+
+/* Implementation of _zope_ucol */
+
+
+static PyObject *__pyx_n_sys;
+
+static PyObject *__pyx_n_ValueError;
+
+static PyObject *__pyx_k2p;
+
+static char (__pyx_k2[]) = "Couldn't convert Python unicode data to ICU unicode data.";
+
+static int __pyx_f_10_zope_ucol_11UCharString___new__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_f_10_zope_ucol_11UCharString___new__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyUnicodeObject *__pyx_v_text = 0;
+  int32_t __pyx_v_buffsize;
+  UErrorCode __pyx_v_status;
+  int __pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"text",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_text)) return -1;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_text);
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_text), __pyx_ptype_10_zope_ucol_unicode, 1, "text")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; goto __pyx_L1;}
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":78 */
+  __pyx_1 = ((sizeof(Py_UNICODE )) == 2);
+  if (__pyx_1) {
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":79 */
+    ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->data = __pyx_v_text->str;
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":80 */
+    ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->length = __pyx_v_text->length;
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":81 */
+    Py_INCREF(((PyObject *)__pyx_v_text));
+    Py_DECREF(((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->base);
+    ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->base = ((PyObject *)__pyx_v_text);
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":82 */
+    ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->need_to_free = 0;
+    goto __pyx_L2;
+  }
+  /*else*/ {
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":84 */
+    __pyx_v_buffsize = ((2 * __pyx_v_text->length) + 1);
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":85 */
+    ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->data = ((UChar (*))PyMem_Malloc((__pyx_v_buffsize * (sizeof(UChar )))));
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":86 */
+    __pyx_v_status = 0;
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":87 */
+    u_strFromUTF32(((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->data,__pyx_v_buffsize,(&((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->length),((UChar32 (*))__pyx_v_text->str),__pyx_v_text->length,(&__pyx_v_status));
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":89 */
+    ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->need_to_free = 1;
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":90 */
+    __pyx_1 = U_FAILURE(__pyx_v_status);
+    if (__pyx_1) {
+
+      /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":91 */
+      __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; goto __pyx_L1;}
+      __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; goto __pyx_L1;}
+      Py_INCREF(__pyx_k2p);
+      PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k2p);
+      __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; goto __pyx_L1;}
+      Py_DECREF(__pyx_2); __pyx_2 = 0;
+      Py_DECREF(__pyx_3); __pyx_3 = 0;
+      __Pyx_Raise(__pyx_4, 0, 0);
+      Py_DECREF(__pyx_4); __pyx_4 = 0;
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; goto __pyx_L1;}
+      goto __pyx_L3;
+    }
+    __pyx_L3:;
+  }
+  __pyx_L2:;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_zope_ucol.UCharString.__new__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_text);
+  return __pyx_r;
+}
+
+static void __pyx_f_10_zope_ucol_11UCharString___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_10_zope_ucol_11UCharString___dealloc__(PyObject *__pyx_v_self) {
+  int __pyx_1;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":96 */
+  __pyx_1 = ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->need_to_free;
+  if (__pyx_1) {
+    __pyx_1 = (((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->data != 0);
+  }
+  if (__pyx_1) {
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":97 */
+    PyMem_Free(((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->data);
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":98 */
+    ((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_self)->data = 0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  goto __pyx_L0;
+  __Pyx_AddTraceback("_zope_ucol.UCharString.__dealloc__");
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+}
+
+static PyObject *__pyx_k3p;
+
+static char (__pyx_k3[]) = "Couldn't create a collator";
+
+static int __pyx_f_10_zope_ucol_10KeyFactory___new__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static int __pyx_f_10_zope_ucol_10KeyFactory___new__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  char (*__pyx_v_locale);
+  UCollator (*__pyx_v_collator);
+  UErrorCode __pyx_v_status;
+  int __pyx_r;
+  int __pyx_1;
+  PyObject *__pyx_2 = 0;
+  PyObject *__pyx_3 = 0;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"locale",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "s", __pyx_argnames, &__pyx_v_locale)) return -1;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":110 */
+  __pyx_v_status = U_ZERO_ERROR;
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":111 */
+  __pyx_v_collator = ucol_open(__pyx_v_locale,(&__pyx_v_status));
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":112 */
+  __pyx_1 = U_FAILURE(__pyx_v_status);
+  if (__pyx_1) {
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":113 */
+    __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_ValueError); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
+    __pyx_3 = PyTuple_New(1); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
+    Py_INCREF(__pyx_k3p);
+    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_k3p);
+    __pyx_4 = PyObject_CallObject(__pyx_2, __pyx_3); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
+    Py_DECREF(__pyx_2); __pyx_2 = 0;
+    Py_DECREF(__pyx_3); __pyx_3 = 0;
+    __Pyx_Raise(__pyx_4, 0, 0);
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 113; goto __pyx_L1;}
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":114 */
+  ((struct __pyx_obj_10_zope_ucol_KeyFactory *)__pyx_v_self)->collator = __pyx_v_collator;
+
+  __pyx_r = 0;
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_3);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_zope_ucol.KeyFactory.__new__");
+  __pyx_r = -1;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+  return __pyx_r;
+}
+
+static void __pyx_f_10_zope_ucol_10KeyFactory___dealloc__(PyObject *__pyx_v_self); /*proto*/
+static void __pyx_f_10_zope_ucol_10KeyFactory___dealloc__(PyObject *__pyx_v_self) {
+  int __pyx_1;
+  Py_INCREF(__pyx_v_self);
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":117 */
+  __pyx_1 = (((struct __pyx_obj_10_zope_ucol_KeyFactory *)__pyx_v_self)->collator != 0);
+  if (__pyx_1) {
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":118 */
+    ucol_close(((struct __pyx_obj_10_zope_ucol_KeyFactory *)__pyx_v_self)->collator);
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  goto __pyx_L0;
+  __Pyx_AddTraceback("_zope_ucol.KeyFactory.__dealloc__");
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_self);
+}
+
+static PyObject *__pyx_k4p;
+
+static char (__pyx_k4[]) = "size from ucol_getSortKey changed %d %d";
+
+static PyObject *__pyx_f_10_zope_ucol_10KeyFactory___call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
+static PyObject *__pyx_f_10_zope_ucol_10KeyFactory___call__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
+  PyUnicodeObject *__pyx_v_text = 0;
+  char (*__pyx_v_buffer);
+  int32_t __pyx_v_bufsize;
+  int32_t __pyx_v_size;
+  PyObject *__pyx_v_icutext;
+  PyObject *__pyx_v_result;
+  PyObject *__pyx_r;
+  PyObject *__pyx_1 = 0;
+  PyObject *__pyx_2 = 0;
+  int __pyx_3;
+  PyObject *__pyx_4 = 0;
+  static char *__pyx_argnames[] = {"text",0};
+  if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O", __pyx_argnames, &__pyx_v_text)) return 0;
+  Py_INCREF(__pyx_v_self);
+  Py_INCREF(__pyx_v_text);
+  __pyx_v_icutext = Py_None; Py_INCREF(__pyx_v_icutext);
+  __pyx_v_result = Py_None; Py_INCREF(__pyx_v_result);
+  if (!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_text), __pyx_ptype_10_zope_ucol_unicode, 1, "text")) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 120; goto __pyx_L1;}
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":129 */
+  __pyx_1 = PyTuple_New(1); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
+  Py_INCREF(((PyObject *)__pyx_v_text));
+  PyTuple_SET_ITEM(__pyx_1, 0, ((PyObject *)__pyx_v_text));
+  __pyx_2 = PyObject_CallObject(((PyObject*)__pyx_ptype_10_zope_ucol_UCharString), __pyx_1); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 129; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+  Py_DECREF(__pyx_v_icutext);
+  __pyx_v_icutext = __pyx_2;
+  __pyx_2 = 0;
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":130 */
+  __pyx_v_bufsize = (((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_icutext)->length * 2);
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":131 */
+  __pyx_v_buffer = ((char (*))PyMem_Malloc(__pyx_v_bufsize));
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":132 */
+  __pyx_v_size = ucol_getSortKey(((struct __pyx_obj_10_zope_ucol_KeyFactory *)__pyx_v_self)->collator,((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_icutext)->data,((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_icutext)->length,__pyx_v_buffer,__pyx_v_bufsize);
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":136 */
+  __pyx_3 = (__pyx_v_size > __pyx_v_bufsize);
+  if (__pyx_3) {
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":137 */
+    __pyx_v_bufsize = __pyx_v_size;
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":138 */
+    PyMem_Free(__pyx_v_buffer);
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":139 */
+    __pyx_v_buffer = ((char (*))PyMem_Malloc(__pyx_v_bufsize));
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":140 */
+    __pyx_v_size = ucol_getSortKey(((struct __pyx_obj_10_zope_ucol_KeyFactory *)__pyx_v_self)->collator,((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_icutext)->data,((struct __pyx_obj_10_zope_ucol_UCharString *)__pyx_v_icutext)->length,__pyx_v_buffer,__pyx_v_bufsize);
+
+    /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":144 */
+    __pyx_1 = PyInt_FromLong(__pyx_v_size); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
+    __pyx_2 = PyInt_FromLong(__pyx_v_bufsize); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
+    __pyx_4 = PyTuple_New(2); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
+    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
+    PyTuple_SET_ITEM(__pyx_4, 1, __pyx_2);
+    __pyx_1 = 0;
+    __pyx_2 = 0;
+    __pyx_1 = PyNumber_Remainder(__pyx_k4p, __pyx_4); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; goto __pyx_L1;}
+    Py_DECREF(__pyx_4); __pyx_4 = 0;
+    if (!(__pyx_v_size == __pyx_v_bufsize)) {
+      PyErr_SetObject(PyExc_AssertionError, __pyx_1);
+      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; goto __pyx_L1;}
+    }
+    Py_DECREF(__pyx_1); __pyx_1 = 0;
+    goto __pyx_L2;
+  }
+  __pyx_L2:;
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":147 */
+  __pyx_2 = PyString_FromStringAndSize(__pyx_v_buffer,__pyx_v_size); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; goto __pyx_L1;}
+  Py_DECREF(__pyx_v_result);
+  __pyx_v_result = __pyx_2;
+  __pyx_2 = 0;
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":148 */
+  PyMem_Free(__pyx_v_buffer);
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":149 */
+  Py_INCREF(__pyx_v_result);
+  __pyx_r = __pyx_v_result;
+  goto __pyx_L0;
+
+  __pyx_r = Py_None; Py_INCREF(__pyx_r);
+  goto __pyx_L0;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  Py_XDECREF(__pyx_2);
+  Py_XDECREF(__pyx_4);
+  __Pyx_AddTraceback("_zope_ucol.KeyFactory.__call__");
+  __pyx_r = 0;
+  __pyx_L0:;
+  Py_DECREF(__pyx_v_icutext);
+  Py_DECREF(__pyx_v_result);
+  Py_DECREF(__pyx_v_self);
+  Py_DECREF(__pyx_v_text);
+  return __pyx_r;
+}
+
+static __Pyx_InternTabEntry __pyx_intern_tab[] = {
+  {&__pyx_n_ValueError, "ValueError"},
+  {&__pyx_n_sys, "sys"},
+  {0, 0}
+};
+
+static __Pyx_StringTabEntry __pyx_string_tab[] = {
+  {&__pyx_k2p, __pyx_k2, sizeof(__pyx_k2)},
+  {&__pyx_k3p, __pyx_k3, sizeof(__pyx_k3)},
+  {&__pyx_k4p, __pyx_k4, sizeof(__pyx_k4)},
+  {0, 0, 0}
+};
+
+static PyObject *__pyx_tp_new_10_zope_ucol_UCharString(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  struct __pyx_obj_10_zope_ucol_UCharString *p = (struct __pyx_obj_10_zope_ucol_UCharString *)o;
+  p->base = Py_None; Py_INCREF(p->base);
+  if (__pyx_f_10_zope_ucol_11UCharString___new__(o, a, k) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_10_zope_ucol_UCharString(PyObject *o) {
+  struct __pyx_obj_10_zope_ucol_UCharString *p = (struct __pyx_obj_10_zope_ucol_UCharString *)o;
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++o->ob_refcnt;
+    __pyx_f_10_zope_ucol_11UCharString___dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --o->ob_refcnt;
+    PyErr_Restore(etype, eval, etb);
+  }
+  Py_XDECREF(p->base);
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_10_zope_ucol_UCharString(PyObject *o, visitproc v, void *a) {
+  int e;
+  struct __pyx_obj_10_zope_ucol_UCharString *p = (struct __pyx_obj_10_zope_ucol_UCharString *)o;
+  if (p->base) {
+    e = (*v)(p->base, a); if (e) return e;
+  }
+  return 0;
+}
+
+static int __pyx_tp_clear_10_zope_ucol_UCharString(PyObject *o) {
+  struct __pyx_obj_10_zope_ucol_UCharString *p = (struct __pyx_obj_10_zope_ucol_UCharString *)o;
+  Py_XDECREF(p->base);
+  p->base = Py_None; Py_INCREF(p->base);
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_10_zope_ucol_UCharString[] = {
+  {0, 0, 0, 0}
+};
+
+static struct PyMemberDef __pyx_members_10_zope_ucol_UCharString[] = {
+  {"length", T_INT, offsetof(struct __pyx_obj_10_zope_ucol_UCharString, length), READONLY, 0},
+  {"base", T_OBJECT, offsetof(struct __pyx_obj_10_zope_ucol_UCharString, base), READONLY, 0},
+  {"need_to_free", T_INT, offsetof(struct __pyx_obj_10_zope_ucol_UCharString, need_to_free), READONLY, 0},
+  {0, 0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_UCharString = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_UCharString = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_UCharString = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_UCharString = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+statichere PyTypeObject __pyx_type_10_zope_ucol_UCharString = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_zope_ucol.UCharString", /*tp_name*/
+  sizeof(struct __pyx_obj_10_zope_ucol_UCharString), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_10_zope_ucol_UCharString, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_UCharString, /*tp_as_number*/
+  &__pyx_tp_as_sequence_UCharString, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_UCharString, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  0, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_UCharString, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+  "Wrapper for ICU UChar arrays\n    ", /*tp_doc*/
+  __pyx_tp_traverse_10_zope_ucol_UCharString, /*tp_traverse*/
+  __pyx_tp_clear_10_zope_ucol_UCharString, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_10_zope_ucol_UCharString, /*tp_methods*/
+  __pyx_members_10_zope_ucol_UCharString, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_10_zope_ucol_UCharString, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static PyObject *__pyx_tp_new_10_zope_ucol_KeyFactory(PyTypeObject *t, PyObject *a, PyObject *k) {
+  PyObject *o = (*t->tp_alloc)(t, 0);
+  if (__pyx_f_10_zope_ucol_10KeyFactory___new__(o, a, k) < 0) {
+    Py_DECREF(o); o = 0;
+  }
+  return o;
+}
+
+static void __pyx_tp_dealloc_10_zope_ucol_KeyFactory(PyObject *o) {
+  {
+    PyObject *etype, *eval, *etb;
+    PyErr_Fetch(&etype, &eval, &etb);
+    ++o->ob_refcnt;
+    __pyx_f_10_zope_ucol_10KeyFactory___dealloc__(o);
+    if (PyErr_Occurred()) PyErr_WriteUnraisable(o);
+    --o->ob_refcnt;
+    PyErr_Restore(etype, eval, etb);
+  }
+  (*o->ob_type->tp_free)(o);
+}
+
+static int __pyx_tp_traverse_10_zope_ucol_KeyFactory(PyObject *o, visitproc v, void *a) {
+  return 0;
+}
+
+static int __pyx_tp_clear_10_zope_ucol_KeyFactory(PyObject *o) {
+  return 0;
+}
+
+static struct PyMethodDef __pyx_methods_10_zope_ucol_KeyFactory[] = {
+  {0, 0, 0, 0}
+};
+
+static PyNumberMethods __pyx_tp_as_number_KeyFactory = {
+  0, /*nb_add*/
+  0, /*nb_subtract*/
+  0, /*nb_multiply*/
+  0, /*nb_divide*/
+  0, /*nb_remainder*/
+  0, /*nb_divmod*/
+  0, /*nb_power*/
+  0, /*nb_negative*/
+  0, /*nb_positive*/
+  0, /*nb_absolute*/
+  0, /*nb_nonzero*/
+  0, /*nb_invert*/
+  0, /*nb_lshift*/
+  0, /*nb_rshift*/
+  0, /*nb_and*/
+  0, /*nb_xor*/
+  0, /*nb_or*/
+  0, /*nb_coerce*/
+  0, /*nb_int*/
+  0, /*nb_long*/
+  0, /*nb_float*/
+  0, /*nb_oct*/
+  0, /*nb_hex*/
+  0, /*nb_inplace_add*/
+  0, /*nb_inplace_subtract*/
+  0, /*nb_inplace_multiply*/
+  0, /*nb_inplace_divide*/
+  0, /*nb_inplace_remainder*/
+  0, /*nb_inplace_power*/
+  0, /*nb_inplace_lshift*/
+  0, /*nb_inplace_rshift*/
+  0, /*nb_inplace_and*/
+  0, /*nb_inplace_xor*/
+  0, /*nb_inplace_or*/
+  0, /*nb_floor_divide*/
+  0, /*nb_true_divide*/
+  0, /*nb_inplace_floor_divide*/
+  0, /*nb_inplace_true_divide*/
+};
+
+static PySequenceMethods __pyx_tp_as_sequence_KeyFactory = {
+  0, /*sq_length*/
+  0, /*sq_concat*/
+  0, /*sq_repeat*/
+  0, /*sq_item*/
+  0, /*sq_slice*/
+  0, /*sq_ass_item*/
+  0, /*sq_ass_slice*/
+  0, /*sq_contains*/
+  0, /*sq_inplace_concat*/
+  0, /*sq_inplace_repeat*/
+};
+
+static PyMappingMethods __pyx_tp_as_mapping_KeyFactory = {
+  0, /*mp_length*/
+  0, /*mp_subscript*/
+  0, /*mp_ass_subscript*/
+};
+
+static PyBufferProcs __pyx_tp_as_buffer_KeyFactory = {
+  0, /*bf_getreadbuffer*/
+  0, /*bf_getwritebuffer*/
+  0, /*bf_getsegcount*/
+  0, /*bf_getcharbuffer*/
+};
+
+statichere PyTypeObject __pyx_type_10_zope_ucol_KeyFactory = {
+  PyObject_HEAD_INIT(0)
+  0, /*ob_size*/
+  "_zope_ucol.KeyFactory", /*tp_name*/
+  sizeof(struct __pyx_obj_10_zope_ucol_KeyFactory), /*tp_basicsize*/
+  0, /*tp_itemsize*/
+  __pyx_tp_dealloc_10_zope_ucol_KeyFactory, /*tp_dealloc*/
+  0, /*tp_print*/
+  0, /*tp_getattr*/
+  0, /*tp_setattr*/
+  0, /*tp_compare*/
+  0, /*tp_repr*/
+  &__pyx_tp_as_number_KeyFactory, /*tp_as_number*/
+  &__pyx_tp_as_sequence_KeyFactory, /*tp_as_sequence*/
+  &__pyx_tp_as_mapping_KeyFactory, /*tp_as_mapping*/
+  0, /*tp_hash*/
+  __pyx_f_10_zope_ucol_10KeyFactory___call__, /*tp_call*/
+  0, /*tp_str*/
+  0, /*tp_getattro*/
+  0, /*tp_setattro*/
+  &__pyx_tp_as_buffer_KeyFactory, /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE, /*tp_flags*/
+  "Compute a collation key for a unicode string.\n    ", /*tp_doc*/
+  __pyx_tp_traverse_10_zope_ucol_KeyFactory, /*tp_traverse*/
+  __pyx_tp_clear_10_zope_ucol_KeyFactory, /*tp_clear*/
+  0, /*tp_richcompare*/
+  0, /*tp_weaklistoffset*/
+  0, /*tp_iter*/
+  0, /*tp_iternext*/
+  __pyx_methods_10_zope_ucol_KeyFactory, /*tp_methods*/
+  0, /*tp_members*/
+  0, /*tp_getset*/
+  0, /*tp_base*/
+  0, /*tp_dict*/
+  0, /*tp_descr_get*/
+  0, /*tp_descr_set*/
+  0, /*tp_dictoffset*/
+  0, /*tp_init*/
+  0, /*tp_alloc*/
+  __pyx_tp_new_10_zope_ucol_KeyFactory, /*tp_new*/
+  0, /*tp_free*/
+  0, /*tp_is_gc*/
+  0, /*tp_bases*/
+  0, /*tp_mro*/
+  0, /*tp_cache*/
+  0, /*tp_subclasses*/
+  0, /*tp_weaklist*/
+};
+
+static struct PyMethodDef __pyx_methods[] = {
+  {0, 0, 0, 0}
+};
+
+DL_EXPORT(void) init_zope_ucol(void); /*proto*/
+DL_EXPORT(void) init_zope_ucol(void) {
+  PyObject *__pyx_1 = 0;
+  __pyx_m = Py_InitModule4("_zope_ucol", __pyx_methods, __pyx_mdoc, 0, PYTHON_API_VERSION);
+  if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; goto __pyx_L1;};
+  __pyx_b = PyImport_AddModule("__builtin__");
+  if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; goto __pyx_L1;};
+  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; goto __pyx_L1;};
+  if (__Pyx_InternStrings(__pyx_intern_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; goto __pyx_L1;};
+  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 14; goto __pyx_L1;};
+  __pyx_ptype_10_zope_ucol_unicode = __Pyx_ImportType("__builtin__", "unicode", sizeof(PyUnicodeObject)); if (!__pyx_ptype_10_zope_ucol_unicode) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; goto __pyx_L1;}
+  __pyx_type_10_zope_ucol_UCharString.tp_free = _PyObject_GC_Del;
+  if (PyType_Ready(&__pyx_type_10_zope_ucol_UCharString) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "UCharString", (PyObject *)&__pyx_type_10_zope_ucol_UCharString) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 65; goto __pyx_L1;}
+  __pyx_ptype_10_zope_ucol_UCharString = &__pyx_type_10_zope_ucol_UCharString;
+  if (PyType_Ready(&__pyx_type_10_zope_ucol_KeyFactory) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; goto __pyx_L1;}
+  if (PyObject_SetAttrString(__pyx_m, "KeyFactory", (PyObject *)&__pyx_type_10_zope_ucol_KeyFactory) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 101; goto __pyx_L1;}
+  __pyx_ptype_10_zope_ucol_KeyFactory = &__pyx_type_10_zope_ucol_KeyFactory;
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":18 */
+  __pyx_1 = __Pyx_Import(__pyx_n_sys, 0); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;}
+  if (PyObject_SetAttr(__pyx_m, __pyx_n_sys, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 18; goto __pyx_L1;}
+  Py_DECREF(__pyx_1); __pyx_1 = 0;
+
+  /* "/home/jim/p/zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx":120 */
+  return;
+  __pyx_L1:;
+  Py_XDECREF(__pyx_1);
+  __Pyx_AddTraceback("_zope_ucol");
+}
+
+static char *__pyx_filenames[] = {
+  "_zope_ucol.pyx",
+};
+statichere char **__pyx_f = __pyx_filenames;
+
+/* Runtime support code */
+
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
+    if (!type) {
+        PyErr_Format(PyExc_SystemError, "Missing type object");
+        return 0;
+    }
+    if ((none_allowed && obj == Py_None) || PyObject_TypeCheck(obj, type))
+        return 1;
+    PyErr_Format(PyExc_TypeError,
+        "Argument '%s' has incorrect type (expected %s, got %s)",
+        name, type->tp_name, obj->ob_type->tp_name);
+    return 0;
+}
+
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
+    PyObject *__import__ = 0;
+    PyObject *empty_list = 0;
+    PyObject *module = 0;
+    PyObject *global_dict = 0;
+    PyObject *empty_dict = 0;
+    PyObject *list;
+    __import__ = PyObject_GetAttrString(__pyx_b, "__import__");
+    if (!__import__)
+        goto bad;
+    if (from_list)
+        list = from_list;
+    else {
+        empty_list = PyList_New(0);
+        if (!empty_list)
+            goto bad;
+        list = empty_list;
+    }
+    global_dict = PyModule_GetDict(__pyx_m);
+    if (!global_dict)
+        goto bad;
+    empty_dict = PyDict_New();
+    if (!empty_dict)
+        goto bad;
+    module = PyObject_CallFunction(__import__, "OOOO",
+        name, global_dict, empty_dict, list);
+bad:
+    Py_XDECREF(empty_list);
+    Py_XDECREF(__import__);
+    Py_XDECREF(empty_dict);
+    return module;
+}
+
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
+    PyObject *result;
+    result = PyObject_GetAttr(dict, name);
+    if (!result)
+        PyErr_SetObject(PyExc_NameError, name);
+    return result;
+}
+
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
+    Py_XINCREF(type);
+    Py_XINCREF(value);
+    Py_XINCREF(tb);
+    /* First, check the traceback argument, replacing None with NULL. */
+    if (tb == Py_None) {
+        Py_DECREF(tb);
+        tb = 0;
+    }
+    else if (tb != NULL && !PyTraceBack_Check(tb)) {
+        PyErr_SetString(PyExc_TypeError,
+            "raise: arg 3 must be a traceback or None");
+        goto raise_error;
+    }
+    /* Next, replace a missing value with None */
+    if (value == NULL) {
+        value = Py_None;
+        Py_INCREF(value);
+    }
+    /* Next, repeatedly, replace a tuple exception with its first item */
+    while (PyTuple_Check(type) && PyTuple_Size(type) > 0) {
+        PyObject *tmp = type;
+        type = PyTuple_GET_ITEM(type, 0);
+        Py_INCREF(type);
+        Py_DECREF(tmp);
+    }
+    if (PyString_Check(type))
+        ;
+    else if (PyClass_Check(type))
+        ; /*PyErr_NormalizeException(&type, &value, &tb);*/
+    else if (PyInstance_Check(type)) {
+        /* Raising an instance.  The value should be a dummy. */
+        if (value != Py_None) {
+            PyErr_SetString(PyExc_TypeError,
+              "instance exception may not have a separate value");
+            goto raise_error;
+        }
+        else {
+            /* Normalize to raise <class>, <instance> */
+            Py_DECREF(value);
+            value = type;
+            type = (PyObject*) ((PyInstanceObject*)type)->in_class;
+            Py_INCREF(type);
+        }
+    }
+    else {
+        /* Not something you can raise.  You get an exception
+           anyway, just not what you specified :-) */
+        PyErr_Format(PyExc_TypeError,
+                 "exceptions must be strings, classes, or "
+                 "instances, not %s", type->ob_type->tp_name);
+        goto raise_error;
+    }
+    PyErr_Restore(type, value, tb);
+    return;
+raise_error:
+    Py_XDECREF(value);
+    Py_XDECREF(type);
+    Py_XDECREF(tb);
+    return;
+}
+
+static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
+    while (t->p) {
+        *t->p = PyString_InternFromString(t->s);
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
+    while (t->p) {
+        *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
+        if (!*t->p)
+            return -1;
+        ++t;
+    }
+    return 0;
+}
+
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, 
+    long size) 
+{
+    PyObject *py_module_name = 0;
+    PyObject *py_class_name = 0;
+    PyObject *py_name_list = 0;
+    PyObject *py_module = 0;
+    PyObject *result = 0;
+    
+    py_module_name = PyString_FromString(module_name);
+    if (!py_module_name)
+        goto bad;
+    py_class_name = PyString_FromString(class_name);
+    if (!py_class_name)
+        goto bad;
+    py_name_list = PyList_New(1);
+    if (!py_name_list)
+        goto bad;
+    Py_INCREF(py_class_name);
+    if (PyList_SetItem(py_name_list, 0, py_class_name) < 0)
+        goto bad;
+    py_module = __Pyx_Import(py_module_name, py_name_list);
+    if (!py_module)
+        goto bad;
+    result = PyObject_GetAttr(py_module, py_class_name);
+    if (!result)
+        goto bad;
+    if (!PyType_Check(result)) {
+        PyErr_Format(PyExc_TypeError, 
+            "%s.%s is not a type object",
+            module_name, class_name);
+        goto bad;
+    }
+    if (((PyTypeObject *)result)->tp_basicsize != size) {
+        PyErr_Format(PyExc_ValueError, 
+            "%s.%s does not appear to be the correct type object",
+            module_name, class_name);
+        goto bad;
+    }
+    goto done;
+bad:
+    Py_XDECREF(result);
+    result = 0;
+done:
+    Py_XDECREF(py_module_name);
+    Py_XDECREF(py_class_name);
+    Py_XDECREF(py_name_list);
+    return (PyTypeObject *)result;
+}
+
+#include "compile.h"
+#include "frameobject.h"
+#include "traceback.h"
+
+static void __Pyx_AddTraceback(char *funcname) {
+    PyObject *py_srcfile = 0;
+    PyObject *py_funcname = 0;
+    PyObject *py_globals = 0;
+    PyObject *empty_tuple = 0;
+    PyObject *empty_string = 0;
+    PyCodeObject *py_code = 0;
+    PyFrameObject *py_frame = 0;
+    
+    py_srcfile = PyString_FromString(__pyx_filename);
+    if (!py_srcfile) goto bad;
+    py_funcname = PyString_FromString(funcname);
+    if (!py_funcname) goto bad;
+    py_globals = PyModule_GetDict(__pyx_m);
+    if (!py_globals) goto bad;
+    empty_tuple = PyTuple_New(0);
+    if (!empty_tuple) goto bad;
+    empty_string = PyString_FromString("");
+    if (!empty_string) goto bad;
+    py_code = PyCode_New(
+        0,            /*int argcount,*/
+        0,            /*int nlocals,*/
+        0,            /*int stacksize,*/
+        0,            /*int flags,*/
+        empty_string, /*PyObject *code,*/
+        empty_tuple,  /*PyObject *consts,*/
+        empty_tuple,  /*PyObject *names,*/
+        empty_tuple,  /*PyObject *varnames,*/
+        empty_tuple,  /*PyObject *freevars,*/
+        empty_tuple,  /*PyObject *cellvars,*/
+        py_srcfile,   /*PyObject *filename,*/
+        py_funcname,  /*PyObject *name,*/
+        __pyx_lineno,   /*int firstlineno,*/
+        empty_string  /*PyObject *lnotab*/
+    );
+    if (!py_code) goto bad;
+    py_frame = PyFrame_New(
+        PyThreadState_Get(), /*PyThreadState *tstate,*/
+        py_code,             /*PyCodeObject *code,*/
+        py_globals,          /*PyObject *globals,*/
+        0                    /*PyObject *locals*/
+    );
+    if (!py_frame) goto bad;
+    py_frame->f_lineno = __pyx_lineno;
+    PyTraceBack_Here(py_frame);
+bad:
+    Py_XDECREF(py_srcfile);
+    Py_XDECREF(py_funcname);
+    Py_XDECREF(empty_tuple);
+    Py_XDECREF(empty_string);
+    Py_XDECREF(py_code);
+    Py_XDECREF(py_frame);
+}


Property changes on: zope.ucol/trunk/src/zope/ucol/_zope_ucol.c
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx
===================================================================
--- zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,149 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Simple wrapper for ICU ucol API
+
+$Id$
+"""
+import sys
+
+cdef extern from  "unicode/utypes.h":
+
+    ctypedef int UErrorCode
+    ctypedef int int32_t
+    ctypedef char uint8_t
+    int U_FAILURE(UErrorCode status)
+    UErrorCode U_ZERO_ERROR
+
+cdef extern from  "unicode/utf.h":
+    ctypedef int UChar
+    ctypedef int UChar32
+
+cdef extern from  "unicode/ustring.h":
+    UChar *u_strFromUTF32(UChar *dest, int32_t destCapacity,
+                          int32_t *pDestLength,
+                          UChar32 *src, int32_t srcLength,
+                          UErrorCode *status)
+
+cdef extern from  "unicode/ucol.h":
+
+    ctypedef struct UCollator:
+        pass
+    UCollator *ucol_open(char *locale, UErrorCode *status)
+    void ucol_close(UCollator *collator)
+    int32_t ucol_getSortKey(UCollator *coll,
+                            UChar *source, int32_t sourceLength,
+                            uint8_t *result,
+                            int32_t resultLength
+                            )
+
+cdef extern from  "Python.h":
+
+    cdef int PyUnicode_Check(ob)
+    cdef int PyString_Check(ob)
+
+    ctypedef int Py_UNICODE
+
+    ctypedef class __builtin__.unicode [object PyUnicodeObject]:
+        cdef int length
+        cdef Py_UNICODE *str
+
+    void *PyMem_Malloc(int)
+    void PyMem_Free(void *p)
+    object PyString_FromStringAndSize(char *v, int l)
+    
+cdef class UCharString:
+    """Wrapper for ICU UChar arrays
+    """
+
+    cdef UChar *data
+    cdef readonly int32_t length
+    cdef readonly object base
+    cdef readonly int need_to_free
+
+    def __new__(self, unicode text):
+        cdef int32_t buffsize
+        cdef UErrorCode status
+
+        if sizeof(Py_UNICODE) == 2:
+            self.data = text.str
+            self.length = text.length
+            self.base = text
+            self.need_to_free = 0
+        else:
+            buffsize = 2*text.length + 1
+            self.data = <UChar*>PyMem_Malloc(buffsize*sizeof(UChar))
+            status = 0
+            u_strFromUTF32(self.data, buffsize, &(self.length),
+                           <UChar32*>text.str, text.length, &status)
+            self.need_to_free = 1
+            if U_FAILURE(status):
+                raise ValueError(
+                    "Couldn't convert Python unicode data to ICU unicode data."
+                    )
+
+    def __dealloc__(self):
+        if self.need_to_free and self.data != NULL:
+            PyMem_Free(self.data)
+            self.data = NULL
+
+
+cdef class KeyFactory:
+    """Compute a collation key for a unicode string.
+    """
+
+    cdef UCollator *collator
+
+    def __new__(self, char *locale):
+        cdef UCollator *collator
+        cdef UErrorCode status
+        status = U_ZERO_ERROR
+        collator = ucol_open(locale, &status)
+        if U_FAILURE(status):
+            raise ValueError("Couldn't create a collator")
+        self.collator = collator
+
+    def __dealloc__(self):
+        if self.collator != NULL:
+            ucol_close(self.collator)
+
+    def __call__(self, unicode text):
+        """Compute a collation key for the given unicode text.
+
+        Of course, the key is only valid for the given locale.
+        """
+        cdef char *buffer
+        cdef int32_t bufsize
+        cdef int32_t size
+
+        icutext = UCharString(text)
+        bufsize = (<UCharString>icutext).length*2
+        buffer = <char*>PyMem_Malloc(bufsize)
+        size = ucol_getSortKey(self.collator,
+                               (<UCharString>icutext).data,
+                               (<UCharString>icutext).length,
+                               buffer, bufsize)
+        if size > bufsize:
+            bufsize = size
+            PyMem_Free(buffer)
+            buffer = <char*>PyMem_Malloc(bufsize)
+            size = ucol_getSortKey(self.collator,
+                                   (<UCharString>icutext).data,
+                                   (<UCharString>icutext).length,
+                                   buffer, bufsize)
+            assert size == bufsize, ("size from ucol_getSortKey changed %d %d"
+                                     % (size, bufsize))
+
+        result = PyString_FromStringAndSize(buffer, size)
+        PyMem_Free(buffer)
+        return result


Property changes on: zope.ucol/trunk/src/zope/ucol/_zope_ucol.pyx
___________________________________________________________________
Name: svn:eol-style
   + native

Added: zope.ucol/trunk/src/zope/ucol/tests.py
===================================================================
--- zope.ucol/trunk/src/zope/ucol/tests.py	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/src/zope/ucol/tests.py	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,29 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""XXX short summary goes here.
+
+$Id$
+"""
+import unittest
+from zope.testing import doctest
+
+def test_suite():
+    return unittest.TestSuite((
+        doctest.DocTestSuite('zope.ucol',
+                             optionflags=doctest.NORMALIZE_WHITESPACE),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
+


Property changes on: zope.ucol/trunk/src/zope/ucol/tests.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Added: zope.ucol/trunk/test.py
===================================================================
--- zope.ucol/trunk/test.py	2005-12-06 19:56:39 UTC (rev 40611)
+++ zope.ucol/trunk/test.py	2005-12-06 20:52:16 UTC (rev 40612)
@@ -0,0 +1,27 @@
+#!/home/jim/p/z4i/jim-icu/var/opt/python/bin/python -u
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Run tests in a Zope instance home.
+
+$Id$
+"""
+import sys
+sys.path.insert(0, 'src')
+from zope.testing import testrunner
+
+defaults = '--test-path src -szope.ucol'.split()
+
+status = testrunner.run(defaults)
+
+sys.exit(status)


Property changes on: zope.ucol/trunk/test.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the Zope-CVS mailing list