/usr/lib/python2.7/dist-packages/zope/ucol/_zope_ucol.pyx is in python-zope.ucol 1.0.2-2ubuntu8.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | ##############################################################################
#
# 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":
cdef enum UErrorCode:
U_USING_DEFAULT_WARNING = -127
U_USING_FALLBACK_WARNING = -128
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
)
int ucol_strcoll(UCollator *coll,
UChar *source, int32_t sourceLength,
UChar *target, int32_t targetLength)
cdef extern from "Python.h":
int PyUnicode_Check(ob)
int PyString_Check(ob)
ctypedef int Py_UNICODE
Py_UNICODE *PyUnicode_AS_UNICODE(ob)
int PyUnicode_GET_SIZE(ob)
char *PyString_AS_STRING(ob)
void *PyMem_Malloc(int size)
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, text):
cdef int32_t buffsize
cdef UErrorCode status
cdef Py_UNICODE *str
cdef int length
if not PyUnicode_Check(text):
if PyString_Check(text):
text = unicode(text)
assert PyUnicode_Check(text)
else:
raise TypeError("Expected unicode string")
length = PyUnicode_GET_SIZE(text)
str = PyUnicode_AS_UNICODE(text)
if sizeof(Py_UNICODE) == 2:
self.data = str
self.length = length
self.base = text
self.need_to_free = 0
else:
buffsize = 2*length + 1
self.data = <UChar*>PyMem_Malloc(buffsize*sizeof(UChar))
if self.data == NULL:
raise MemoryError
status = 0
u_strFromUTF32(self.data, buffsize, &(self.length),
<UChar32*>str, length, &status)
assert self.length <= buffsize
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 Collator:
"""Compute a collation key for a unicode string.
"""
cdef UCollator *collator
cdef readonly object locale
cdef readonly int used_default_information
def __new__(self, locale):
cdef UCollator *collator
cdef UErrorCode status
if not PyString_Check(locale):
raise TypeError("String locale expected")
status = U_ZERO_ERROR
collator = ucol_open(PyString_AS_STRING(locale), &status)
if U_FAILURE(status):
raise ValueError("Couldn't create a collator")
self.collator = collator
self.locale = locale
if (status == U_USING_DEFAULT_WARNING
or
status == U_USING_FALLBACK_WARNING):
status = 1
self.used_default_information = status
def __dealloc__(self):
if self.collator != NULL:
ucol_close(self.collator)
def key(self, 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+10
# the +1 below is needed to avoid an apprent buffer overflow bug in ICU
buffer = <char*>PyMem_Malloc(bufsize +1)
if buffer == NULL:
raise MemoryError
size = ucol_getSortKey(self.collator,
(<UCharString>icutext).data,
(<UCharString>icutext).length,
<uint8_t*>buffer, bufsize)
while size > bufsize:
bufsize = size
PyMem_Free(buffer)
buffer = <char*>PyMem_Malloc(bufsize +1) # See above +1
if buffer == NULL:
raise MemoryError
size = ucol_getSortKey(self.collator,
(<UCharString>icutext).data,
(<UCharString>icutext).length,
<uint8_t*>buffer, bufsize)
result = PyString_FromStringAndSize(buffer, size)
PyMem_Free(buffer)
return result
def cmp(self, o1, o2):
u1 = UCharString(o1)
u2 = UCharString(o2)
return ucol_strcoll(
self.collator,
(<UCharString>u1).data,
(<UCharString>u1).length,
(<UCharString>u2).data,
(<UCharString>u2).length,
)
|