1
2//////////////////// IncludeStringH.proto ////////////////////
3
4#include <string.h>
5
6//////////////////// IncludeCppStringH.proto ////////////////////
7
8#include <string>
9
10//////////////////// InitStrings.proto ////////////////////
11
12static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
13
14//////////////////// InitStrings ////////////////////
15
16static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
17    while (t->p) {
18        #if PY_MAJOR_VERSION < 3
19        if (t->is_unicode) {
20            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
21        } else if (t->intern) {
22            *t->p = PyString_InternFromString(t->s);
23        } else {
24            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
25        }
26        #else  /* Python 3+ has unicode identifiers */
27        if (t->is_unicode | t->is_str) {
28            if (t->intern) {
29                *t->p = PyUnicode_InternFromString(t->s);
30            } else if (t->encoding) {
31                *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
32            } else {
33                *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
34            }
35        } else {
36            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
37        }
38        #endif
39        if (!*t->p)
40            return -1;
41        ++t;
42    }
43    return 0;
44}
45
46//////////////////// BytesContains.proto ////////////////////
47
48static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
49
50//////////////////// BytesContains ////////////////////
51
52static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
53    const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
54    char* char_start = PyBytes_AS_STRING(bytes);
55    char* pos;
56    for (pos=char_start; pos < char_start+length; pos++) {
57        if (character == pos[0]) return 1;
58    }
59    return 0;
60}
61
62
63//////////////////// PyUCS4InUnicode.proto ////////////////////
64
65static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/
66static CYTHON_INLINE int __Pyx_PyUnicodeBufferContainsUCS4(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character); /*proto*/
67
68//////////////////// PyUCS4InUnicode ////////////////////
69
70static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
71#if CYTHON_PEP393_ENABLED
72    const int kind = PyUnicode_KIND(unicode);
73    if (likely(kind != PyUnicode_WCHAR_KIND)) {
74        Py_ssize_t i;
75        const void* udata = PyUnicode_DATA(unicode);
76        const Py_ssize_t length = PyUnicode_GET_LENGTH(unicode);
77        for (i=0; i < length; i++) {
78            if (unlikely(character == PyUnicode_READ(kind, udata, i))) return 1;
79        }
80        return 0;
81    }
82#endif
83    return __Pyx_PyUnicodeBufferContainsUCS4(
84        PyUnicode_AS_UNICODE(unicode),
85        PyUnicode_GET_SIZE(unicode),
86        character);
87}
88
89static CYTHON_INLINE int __Pyx_PyUnicodeBufferContainsUCS4(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character) {
90    Py_UNICODE uchar;
91    Py_UNICODE* pos;
92    #if Py_UNICODE_SIZE == 2
93    if (character > 65535) {
94        /* handle surrogate pairs for Py_UNICODE buffers in 16bit Unicode builds */
95        Py_UNICODE high_val, low_val;
96        high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1)));
97        low_val  = (Py_UNICODE) (0xDC00 | ( (character - 0x10000)        & ((1<<10)-1)));
98        for (pos=buffer; pos < buffer+length-1; pos++) {
99            if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1;
100        }
101        return 0;
102    }
103    #endif
104    uchar = (Py_UNICODE) character;
105    for (pos=buffer; pos < buffer+length; pos++) {
106        if (unlikely(uchar == pos[0])) return 1;
107    }
108    return 0;
109}
110
111
112//////////////////// PyUnicodeContains.proto ////////////////////
113
114static CYTHON_INLINE int __Pyx_PyUnicode_Contains(PyObject* substring, PyObject* text, int eq) {
115    int result = PyUnicode_Contains(text, substring);
116    return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
117}
118
119
120//////////////////// StrEquals.proto ////////////////////
121//@requires: BytesEquals
122//@requires: UnicodeEquals
123
124#if PY_MAJOR_VERSION >= 3
125#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
126#else
127#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
128#endif
129
130
131//////////////////// UnicodeEquals.proto ////////////////////
132
133static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
134
135//////////////////// UnicodeEquals ////////////////////
136//@requires: BytesEquals
137
138static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
139#if CYTHON_COMPILING_IN_PYPY
140    return PyObject_RichCompareBool(s1, s2, equals);
141#else
142#if PY_MAJOR_VERSION < 3
143    PyObject* owned_ref = NULL;
144#endif
145    int s1_is_unicode, s2_is_unicode;
146    if (s1 == s2) {
147        /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
148        goto return_eq;
149    }
150    s1_is_unicode = PyUnicode_CheckExact(s1);
151    s2_is_unicode = PyUnicode_CheckExact(s2);
152#if PY_MAJOR_VERSION < 3
153    if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
154        owned_ref = PyUnicode_FromObject(s2);
155        if (unlikely(!owned_ref))
156            return -1;
157        s2 = owned_ref;
158        s2_is_unicode = 1;
159    } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
160        owned_ref = PyUnicode_FromObject(s1);
161        if (unlikely(!owned_ref))
162            return -1;
163        s1 = owned_ref;
164        s1_is_unicode = 1;
165    } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
166        return __Pyx_PyBytes_Equals(s1, s2, equals);
167    }
168#endif
169    if (s1_is_unicode & s2_is_unicode) {
170        Py_ssize_t length;
171        int kind;
172        void *data1, *data2;
173        #if CYTHON_PEP393_ENABLED
174        if (unlikely(PyUnicode_READY(s1) < 0) || unlikely(PyUnicode_READY(s2) < 0))
175            return -1;
176        #endif
177        length = __Pyx_PyUnicode_GET_LENGTH(s1);
178        if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
179            goto return_ne;
180        }
181        // len(s1) == len(s2) >= 1  (empty string is interned, and "s1 is not s2")
182        kind = __Pyx_PyUnicode_KIND(s1);
183        if (kind != __Pyx_PyUnicode_KIND(s2)) {
184            goto return_ne;
185        }
186        data1 = __Pyx_PyUnicode_DATA(s1);
187        data2 = __Pyx_PyUnicode_DATA(s2);
188        if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
189            goto return_ne;
190        } else if (length == 1) {
191            goto return_eq;
192        } else {
193            int result = memcmp(data1, data2, (size_t)(length * kind));
194            #if PY_MAJOR_VERSION < 3
195            Py_XDECREF(owned_ref);
196            #endif
197            return (equals == Py_EQ) ? (result == 0) : (result != 0);
198        }
199    } else if ((s1 == Py_None) & s2_is_unicode) {
200        goto return_ne;
201    } else if ((s2 == Py_None) & s1_is_unicode) {
202        goto return_ne;
203    } else {
204        int result;
205        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
206        if (!py_result)
207            return -1;
208        result = __Pyx_PyObject_IsTrue(py_result);
209        Py_DECREF(py_result);
210        return result;
211    }
212return_eq:
213    #if PY_MAJOR_VERSION < 3
214    Py_XDECREF(owned_ref);
215    #endif
216    return (equals == Py_EQ);
217return_ne:
218    #if PY_MAJOR_VERSION < 3
219    Py_XDECREF(owned_ref);
220    #endif
221    return (equals == Py_NE);
222#endif
223}
224
225
226//////////////////// BytesEquals.proto ////////////////////
227
228static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
229
230//////////////////// BytesEquals ////////////////////
231//@requires: IncludeStringH
232
233static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
234#if CYTHON_COMPILING_IN_PYPY
235    return PyObject_RichCompareBool(s1, s2, equals);
236#else
237    if (s1 == s2) {
238        /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
239        return (equals == Py_EQ);
240    } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
241        const char *ps1, *ps2;
242        Py_ssize_t length = PyBytes_GET_SIZE(s1);
243        if (length != PyBytes_GET_SIZE(s2))
244            return (equals == Py_NE);
245        // len(s1) == len(s2) >= 1  (empty string is interned, and "s1 is not s2")
246        ps1 = PyBytes_AS_STRING(s1);
247        ps2 = PyBytes_AS_STRING(s2);
248        if (ps1[0] != ps2[0]) {
249            return (equals == Py_NE);
250        } else if (length == 1) {
251            return (equals == Py_EQ);
252        } else {
253            int result = memcmp(ps1, ps2, (size_t)length);
254            return (equals == Py_EQ) ? (result == 0) : (result != 0);
255        }
256    } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
257        return (equals == Py_NE);
258    } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
259        return (equals == Py_NE);
260    } else {
261        int result;
262        PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
263        if (!py_result)
264            return -1;
265        result = __Pyx_PyObject_IsTrue(py_result);
266        Py_DECREF(py_result);
267        return result;
268    }
269#endif
270}
271
272//////////////////// GetItemIntByteArray.proto ////////////////////
273
274#define __Pyx_GetItemInt_ByteArray(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
275    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
276    __Pyx_GetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
277    (PyErr_SetString(PyExc_IndexError, "bytearray index out of range"), -1))
278
279static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i,
280                                                         int wraparound, int boundscheck);
281
282//////////////////// GetItemIntByteArray ////////////////////
283
284static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i,
285                                                         int wraparound, int boundscheck) {
286    Py_ssize_t length;
287    if (wraparound | boundscheck) {
288        length = PyByteArray_GET_SIZE(string);
289        if (wraparound & unlikely(i < 0)) i += length;
290        if ((!boundscheck) || likely((0 <= i) & (i < length))) {
291            return (unsigned char) (PyByteArray_AS_STRING(string)[i]);
292        } else {
293            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
294            return -1;
295        }
296    } else {
297        return (unsigned char) (PyByteArray_AS_STRING(string)[i]);
298    }
299}
300
301
302//////////////////// SetItemIntByteArray.proto ////////////////////
303
304#define __Pyx_SetItemInt_ByteArray(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
305    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
306    __Pyx_SetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, v, wraparound, boundscheck) : \
307    (PyErr_SetString(PyExc_IndexError, "bytearray index out of range"), -1))
308
309static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, unsigned char v,
310                                                         int wraparound, int boundscheck);
311
312//////////////////// SetItemIntByteArray ////////////////////
313
314static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, unsigned char v,
315                                                         int wraparound, int boundscheck) {
316    Py_ssize_t length;
317    if (wraparound | boundscheck) {
318        length = PyByteArray_GET_SIZE(string);
319        if (wraparound & unlikely(i < 0)) i += length;
320        if ((!boundscheck) || likely((0 <= i) & (i < length))) {
321            PyByteArray_AS_STRING(string)[i] = (char) v;
322            return 0;
323        } else {
324            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
325            return -1;
326        }
327    } else {
328        PyByteArray_AS_STRING(string)[i] = (char) v;
329        return 0;
330    }
331}
332
333
334//////////////////// GetItemIntUnicode.proto ////////////////////
335
336#define __Pyx_GetItemInt_Unicode(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
337    (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
338    __Pyx_GetItemInt_Unicode_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
339    (PyErr_SetString(PyExc_IndexError, "string index out of range"), (Py_UCS4)-1))
340
341static CYTHON_INLINE Py_UCS4 __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i,
342                                                           int wraparound, int boundscheck);
343
344//////////////////// GetItemIntUnicode ////////////////////
345
346static CYTHON_INLINE Py_UCS4 __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i,
347                                                           int wraparound, int boundscheck) {
348    Py_ssize_t length;
349#if CYTHON_PEP393_ENABLED
350    if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return (Py_UCS4)-1;
351#endif
352    if (wraparound | boundscheck) {
353        length = __Pyx_PyUnicode_GET_LENGTH(ustring);
354        if (wraparound & unlikely(i < 0)) i += length;
355        if ((!boundscheck) || likely((0 <= i) & (i < length))) {
356            return __Pyx_PyUnicode_READ_CHAR(ustring, i);
357        } else {
358            PyErr_SetString(PyExc_IndexError, "string index out of range");
359            return (Py_UCS4)-1;
360        }
361    } else {
362        return __Pyx_PyUnicode_READ_CHAR(ustring, i);
363    }
364}
365
366
367/////////////// decode_cpp_string.proto ///////////////
368//@requires: IncludeCppStringH
369//@requires: decode_c_bytes
370
371static CYTHON_INLINE PyObject* __Pyx_decode_cpp_string(
372         std::string cppstring, Py_ssize_t start, Py_ssize_t stop,
373         const char* encoding, const char* errors,
374         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
375    return __Pyx_decode_c_bytes(
376        cppstring.data(), cppstring.size(), start, stop, encoding, errors, decode_func);
377}
378
379/////////////// decode_c_string.proto ///////////////
380
381static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
382         const char* cstring, Py_ssize_t start, Py_ssize_t stop,
383         const char* encoding, const char* errors,
384         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
385
386/////////////// decode_c_string ///////////////
387//@requires: IncludeStringH
388
389/* duplicate code to avoid calling strlen() if start >= 0 and stop >= 0 */
390
391static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
392         const char* cstring, Py_ssize_t start, Py_ssize_t stop,
393         const char* encoding, const char* errors,
394         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
395    Py_ssize_t length;
396    if (unlikely((start < 0) | (stop < 0))) {
397        length = strlen(cstring);
398        if (start < 0) {
399            start += length;
400            if (start < 0)
401                start = 0;
402        }
403        if (stop < 0)
404            stop += length;
405    }
406    length = stop - start;
407    if (unlikely(length <= 0))
408        return PyUnicode_FromUnicode(NULL, 0);
409    cstring += start;
410    if (decode_func) {
411        return decode_func(cstring, length, errors);
412    } else {
413        return PyUnicode_Decode(cstring, length, encoding, errors);
414    }
415}
416
417/////////////// decode_c_bytes.proto ///////////////
418
419static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
420         const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
421         const char* encoding, const char* errors,
422         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
423
424/////////////// decode_c_bytes ///////////////
425
426static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
427         const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
428         const char* encoding, const char* errors,
429         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
430    if (unlikely((start < 0) | (stop < 0))) {
431        if (start < 0) {
432            start += length;
433            if (start < 0)
434                start = 0;
435        }
436        if (stop < 0)
437            stop += length;
438    }
439    if (stop > length)
440        stop = length;
441    length = stop - start;
442    if (unlikely(length <= 0))
443        return PyUnicode_FromUnicode(NULL, 0);
444    cstring += start;
445    if (decode_func) {
446        return decode_func(cstring, length, errors);
447    } else {
448        return PyUnicode_Decode(cstring, length, encoding, errors);
449    }
450}
451
452/////////////// decode_bytes.proto ///////////////
453//@requires: decode_c_bytes
454
455static CYTHON_INLINE PyObject* __Pyx_decode_bytes(
456         PyObject* string, Py_ssize_t start, Py_ssize_t stop,
457         const char* encoding, const char* errors,
458         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
459    return __Pyx_decode_c_bytes(
460        PyBytes_AS_STRING(string), PyBytes_GET_SIZE(string),
461        start, stop, encoding, errors, decode_func);
462}
463
464/////////////// decode_bytearray.proto ///////////////
465//@requires: decode_c_bytes
466
467static CYTHON_INLINE PyObject* __Pyx_decode_bytearray(
468         PyObject* string, Py_ssize_t start, Py_ssize_t stop,
469         const char* encoding, const char* errors,
470         PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
471    return __Pyx_decode_c_bytes(
472        PyByteArray_AS_STRING(string), PyByteArray_GET_SIZE(string),
473        start, stop, encoding, errors, decode_func);
474}
475
476/////////////// PyUnicode_Substring.proto ///////////////
477
478static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
479            PyObject* text, Py_ssize_t start, Py_ssize_t stop);
480
481/////////////// PyUnicode_Substring ///////////////
482
483static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
484            PyObject* text, Py_ssize_t start, Py_ssize_t stop) {
485    Py_ssize_t length;
486#if CYTHON_PEP393_ENABLED
487    if (unlikely(PyUnicode_READY(text) == -1)) return NULL;
488    length = PyUnicode_GET_LENGTH(text);
489#else
490    length = PyUnicode_GET_SIZE(text);
491#endif
492    if (start < 0) {
493        start += length;
494        if (start < 0)
495            start = 0;
496    }
497    if (stop < 0)
498        stop += length;
499    else if (stop > length)
500        stop = length;
501    length = stop - start;
502    if (length <= 0)
503        return PyUnicode_FromUnicode(NULL, 0);
504#if CYTHON_PEP393_ENABLED
505    return PyUnicode_FromKindAndData(PyUnicode_KIND(text),
506        PyUnicode_1BYTE_DATA(text) + start*PyUnicode_KIND(text), stop-start);
507#else
508    return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(text)+start, stop-start);
509#endif
510}
511
512
513/////////////// py_unicode_istitle.proto ///////////////
514
515// Py_UNICODE_ISTITLE() doesn't match unicode.istitle() as the latter
516// additionally allows character that comply with Py_UNICODE_ISUPPER()
517
518#if PY_VERSION_HEX < 0x030200A2
519static CYTHON_INLINE int __Pyx_Py_UNICODE_ISTITLE(Py_UNICODE uchar)
520#else
521static CYTHON_INLINE int __Pyx_Py_UNICODE_ISTITLE(Py_UCS4 uchar)
522#endif
523{
524    return Py_UNICODE_ISTITLE(uchar) || Py_UNICODE_ISUPPER(uchar);
525}
526
527
528/////////////// unicode_tailmatch.proto ///////////////
529
530// Python's unicode.startswith() and unicode.endswith() support a
531// tuple of prefixes/suffixes, whereas it's much more common to
532// test for a single unicode string.
533
534static int __Pyx_PyUnicode_Tailmatch(PyObject* s, PyObject* substr,
535                                     Py_ssize_t start, Py_ssize_t end, int direction) {
536    if (unlikely(PyTuple_Check(substr))) {
537        Py_ssize_t i, count = PyTuple_GET_SIZE(substr);
538        for (i = 0; i < count; i++) {
539            int result;
540#if CYTHON_COMPILING_IN_CPYTHON
541            result = PyUnicode_Tailmatch(s, PyTuple_GET_ITEM(substr, i),
542                                         start, end, direction);
543#else
544            PyObject* sub = PySequence_GetItem(substr, i);
545            if (unlikely(!sub)) return -1;
546            result = PyUnicode_Tailmatch(s, sub, start, end, direction);
547            Py_DECREF(sub);
548#endif
549            if (result) {
550                return result;
551            }
552        }
553        return 0;
554    }
555    return PyUnicode_Tailmatch(s, substr, start, end, direction);
556}
557
558
559/////////////// bytes_tailmatch.proto ///////////////
560
561static int __Pyx_PyBytes_SingleTailmatch(PyObject* self, PyObject* arg, Py_ssize_t start,
562                                         Py_ssize_t end, int direction)
563{
564    const char* self_ptr = PyBytes_AS_STRING(self);
565    Py_ssize_t self_len = PyBytes_GET_SIZE(self);
566    const char* sub_ptr;
567    Py_ssize_t sub_len;
568    int retval;
569
570#if PY_VERSION_HEX >= 0x02060000
571    Py_buffer view;
572    view.obj = NULL;
573#endif
574
575    if ( PyBytes_Check(arg) ) {
576        sub_ptr = PyBytes_AS_STRING(arg);
577        sub_len = PyBytes_GET_SIZE(arg);
578    }
579#if PY_MAJOR_VERSION < 3
580    // Python 2.x allows mixing unicode and str
581    else if ( PyUnicode_Check(arg) ) {
582        return PyUnicode_Tailmatch(self, arg, start, end, direction);
583    }
584#endif
585    else {
586#if PY_VERSION_HEX < 0x02060000
587        if (unlikely(PyObject_AsCharBuffer(arg, &sub_ptr, &sub_len)))
588            return -1;
589#else
590        if (unlikely(PyObject_GetBuffer(self, &view, PyBUF_SIMPLE) == -1))
591            return -1;
592        sub_ptr = (const char*) view.buf;
593        sub_len = view.len;
594#endif
595    }
596
597    if (end > self_len)
598        end = self_len;
599    else if (end < 0)
600        end += self_len;
601    if (end < 0)
602        end = 0;
603    if (start < 0)
604        start += self_len;
605    if (start < 0)
606        start = 0;
607
608    if (direction > 0) {
609        /* endswith */
610        if (end-sub_len > start)
611            start = end - sub_len;
612    }
613
614    if (start + sub_len <= end)
615        retval = !memcmp(self_ptr+start, sub_ptr, (size_t)sub_len);
616    else
617        retval = 0;
618
619#if PY_VERSION_HEX >= 0x02060000
620    if (view.obj)
621        PyBuffer_Release(&view);
622#endif
623
624    return retval;
625}
626
627static int __Pyx_PyBytes_Tailmatch(PyObject* self, PyObject* substr, Py_ssize_t start,
628                                   Py_ssize_t end, int direction)
629{
630    if (unlikely(PyTuple_Check(substr))) {
631        Py_ssize_t i, count = PyTuple_GET_SIZE(substr);
632        for (i = 0; i < count; i++) {
633            int result;
634#if CYTHON_COMPILING_IN_CPYTHON
635            result = __Pyx_PyBytes_SingleTailmatch(self, PyTuple_GET_ITEM(substr, i),
636                                                   start, end, direction);
637#else
638            PyObject* sub = PySequence_GetItem(substr, i);
639            if (unlikely(!sub)) return -1;
640            result = __Pyx_PyBytes_SingleTailmatch(self, sub, start, end, direction);
641            Py_DECREF(sub);
642#endif
643            if (result) {
644                return result;
645            }
646        }
647        return 0;
648    }
649
650    return __Pyx_PyBytes_SingleTailmatch(self, substr, start, end, direction);
651}
652
653
654/////////////// str_tailmatch.proto ///////////////
655
656static CYTHON_INLINE int __Pyx_PyStr_Tailmatch(PyObject* self, PyObject* arg, Py_ssize_t start,
657                                               Py_ssize_t end, int direction);
658
659/////////////// str_tailmatch ///////////////
660//@requires: bytes_tailmatch
661//@requires: unicode_tailmatch
662
663static CYTHON_INLINE int __Pyx_PyStr_Tailmatch(PyObject* self, PyObject* arg, Py_ssize_t start,
664                                               Py_ssize_t end, int direction)
665{
666    // We do not use a C compiler macro here to avoid "unused function"
667    // warnings for the *_Tailmatch() function that is not being used in
668    // the specific CPython version.  The C compiler will generate the same
669    // code anyway, and will usually just remove the unused function.
670    if (PY_MAJOR_VERSION < 3)
671        return __Pyx_PyBytes_Tailmatch(self, arg, start, end, direction);
672    else
673        return __Pyx_PyUnicode_Tailmatch(self, arg, start, end, direction);
674}
675
676
677/////////////// bytes_index.proto ///////////////
678
679static CYTHON_INLINE char __Pyx_PyBytes_GetItemInt(PyObject* bytes, Py_ssize_t index, int check_bounds) {
680    if (check_bounds) {
681        Py_ssize_t size = PyBytes_GET_SIZE(bytes);
682        if (unlikely(index >= size) | ((index < 0) & unlikely(index < -size))) {
683            PyErr_SetString(PyExc_IndexError, "string index out of range");
684            return -1;
685        }
686    }
687    if (index < 0)
688        index += PyBytes_GET_SIZE(bytes);
689    return PyBytes_AS_STRING(bytes)[index];
690}
691
692
693//////////////////// StringJoin.proto ////////////////////
694
695#if PY_MAJOR_VERSION < 3
696#define __Pyx_PyString_Join __Pyx_PyBytes_Join
697#define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v))
698#else
699#define __Pyx_PyString_Join PyUnicode_Join
700#define __Pyx_PyBaseString_Join PyUnicode_Join
701#endif
702
703#if CYTHON_COMPILING_IN_CPYTHON
704    #if PY_MAJOR_VERSION < 3
705    #define __Pyx_PyBytes_Join _PyString_Join
706    #else
707    #define __Pyx_PyBytes_Join _PyBytes_Join
708    #endif
709#else
710static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values); /*proto*/
711#endif
712
713
714//////////////////// StringJoin ////////////////////
715
716#if !CYTHON_COMPILING_IN_CPYTHON
717static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) {
718    return PyObject_CallMethodObjArgs(sep, PYIDENT("join"), values, NULL);
719}
720#endif
721
722
723//////////////////// ByteArrayAppendObject.proto ////////////////////
724
725static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value);
726
727//////////////////// ByteArrayAppendObject ////////////////////
728//@requires: ByteArrayAppend
729
730static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value) {
731    Py_ssize_t ival;
732#if PY_MAJOR_VERSION < 3
733    if (unlikely(PyString_Check(value))) {
734        if (unlikely(PyString_GET_SIZE(value) != 1)) {
735            PyErr_SetString(PyExc_ValueError, "string must be of size 1");
736            return -1;
737        }
738        ival = (unsigned char) (PyString_AS_STRING(value)[0]);
739    } else
740#endif
741    {
742        // CPython calls PyNumber_Index() internally
743        ival = __Pyx_PyIndex_AsSsize_t(value);
744        if (unlikely((ival < 0) | (ival > 255))) {
745            if (ival == -1 && PyErr_Occurred())
746                return -1;
747            PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
748            return -1;
749        }
750    }
751    return __Pyx_PyByteArray_Append(bytearray, ival);
752}
753
754//////////////////// ByteArrayAppend.proto ////////////////////
755
756static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value);
757
758//////////////////// ByteArrayAppend ////////////////////
759//@requires: ObjectHandling.c::PyObjectCallMethod
760
761static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value) {
762    PyObject *pyval, *retval;
763#if CYTHON_COMPILING_IN_CPYTHON
764    if (likely((value >= 0) & (value <= 255))) {
765        Py_ssize_t n = Py_SIZE(bytearray);
766        if (likely(n != PY_SSIZE_T_MAX)) {
767            if (unlikely(PyByteArray_Resize(bytearray, n + 1) < 0))
768                return -1;
769            PyByteArray_AS_STRING(bytearray)[n] = value;
770            return 0;
771        }
772    } else {
773        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
774        return -1;
775    }
776#endif
777    pyval = PyInt_FromLong(value);
778    if (unlikely(!pyval))
779        return -1;
780    retval = __Pyx_PyObject_CallMethod1(bytearray, PYIDENT("append"), pyval);
781    Py_DECREF(pyval);
782    if (unlikely(!retval))
783        return -1;
784    Py_DECREF(retval);
785    return 0;
786}
787