/* String object implementation */

/* XXX This is now called 'bytes' as far as the user is concerned.
   Many docstrings and error messages need to be cleaned up. */

#define PY_SSIZE_T_CLEAN

#include "Python.h"

#include "bytes_methods.h"

static Py_ssize_t
_getbuffer(PyObject *obj, Py_buffer *view)
{
    PyBufferProcs *buffer = Py_Type(obj)->tp_as_buffer;

    if (buffer == NULL || buffer->bf_getbuffer == NULL)
    {
        PyErr_Format(PyExc_TypeError,
                     "Type %.100s doesn't support the buffer API",
                     Py_Type(obj)->tp_name);
        return -1;
    }

    if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
            return -1;
    return view->len;
}

#ifdef COUNT_ALLOCS
int null_strings, one_strings;
#endif

static PyStringObject *characters[UCHAR_MAX + 1];
static PyStringObject *nullstring;

/*
   For both PyString_FromString() and PyString_FromStringAndSize(), the
   parameter `size' denotes number of characters to allocate, not counting any
   null terminating character.

   For PyString_FromString(), the parameter `str' points to a null-terminated
   string containing exactly `size' bytes.

   For PyString_FromStringAndSize(), the parameter the parameter `str' is
   either NULL or else points to a string containing at least `size' bytes.
   For PyString_FromStringAndSize(), the string in the `str' parameter does
   not have to be null-terminated.  (Therefore it is safe to construct a
   substring by calling `PyString_FromStringAndSize(origstring, substrlen)'.)
   If `str' is NULL then PyString_FromStringAndSize() will allocate `size+1'
   bytes (setting the last byte to the null terminating character) and you can
   fill in the data yourself.  If `str' is non-NULL then the resulting
   PyString object must be treated as immutable and you must not fill in nor
   alter the data yourself, since the strings may be shared.

   The PyObject member `op->ob_size', which denotes the number of "extra
   items" in a variable-size object, will contain the number of bytes
   allocated for string data, not counting the null terminating character.  It
   is therefore equal to the equal to the `size' parameter (for
   PyString_FromStringAndSize()) or the length of the string in the `str'
   parameter (for PyString_FromString()).
*/
PyObject *
PyString_FromStringAndSize(const char *str, Py_ssize_t size)
{
	register PyStringObject *op;
	assert(size >= 0);
	if (size == 0 && (op = nullstring) != NULL) {
#ifdef COUNT_ALLOCS
		null_strings++;
#endif
		Py_INCREF(op);
		return (PyObject *)op;
	}
	if (size == 1 && str != NULL &&
	    (op = characters[*str & UCHAR_MAX]) != NULL)
	{
#ifdef COUNT_ALLOCS
		one_strings++;
#endif
		Py_INCREF(op);
		return (PyObject *)op;
	}

	/* Inline PyObject_NewVar */
	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
	if (op == NULL)
		return PyErr_NoMemory();
	PyObject_INIT_VAR(op, &PyString_Type, size);
	op->ob_shash = -1;
	if (str != NULL)
		Py_MEMCPY(op->ob_sval, str, size);
	op->ob_sval[size] = '\0';
	/* share short strings */
	if (size == 0) {
		nullstring = op;
		Py_INCREF(op);
	} else if (size == 1 && str != NULL) {
		characters[*str & UCHAR_MAX] = op;
		Py_INCREF(op);
	}
	return (PyObject *) op;
}

PyObject *
PyString_FromString(const char *str)
{
	register size_t size;
	register PyStringObject *op;

	assert(str != NULL);
	size = strlen(str);
	if (size > PY_SSIZE_T_MAX) {
		PyErr_SetString(PyExc_OverflowError,
			"string is too long for a Python string");
		return NULL;
	}
	if (size == 0 && (op = nullstring) != NULL) {
#ifdef COUNT_ALLOCS
		null_strings++;
#endif
		Py_INCREF(op);
		return (PyObject *)op;
	}
	if (size == 1 && (op = characters[*str & UCHAR_MAX]) != NULL) {
#ifdef COUNT_ALLOCS
		one_strings++;
#endif
		Py_INCREF(op);
		return (PyObject *)op;
	}

	/* Inline PyObject_NewVar */
	op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size);
	if (op == NULL)
		return PyErr_NoMemory();
	PyObject_INIT_VAR(op, &PyString_Type, size);
	op->ob_shash = -1;
	Py_MEMCPY(op->ob_sval, str, size+1);
	/* share short strings */
	if (size == 0) {
		nullstring = op;
		Py_INCREF(op);
	} else if (size == 1) {
		characters[*str & UCHAR_MAX] = op;
		Py_INCREF(op);
	}
	return (PyObject *) op;
}

PyObject *
PyString_FromFormatV(const char *format, va_list vargs)
{
	va_list count;
	Py_ssize_t n = 0;
	const char* f;
	char *s;
	PyObject* string;

#ifdef VA_LIST_IS_ARRAY
	Py_MEMCPY(count, vargs, sizeof(va_list));
#else
#ifdef  __va_copy
	__va_copy(count, vargs);
#else
	count = vargs;
#endif
#endif
	/* step 1: figure out how large a buffer we need */
	for (f = format; *f; f++) {
		if (*f == '%') {
			const char* p = f;
			while (*++f && *f != '%' && !ISALPHA(*f))
				;

			/* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
			 * they don't affect the amount of space we reserve.
			 */
			if ((*f == 'l' || *f == 'z') &&
					(f[1] == 'd' || f[1] == 'u'))
				++f;

			switch (*f) {
			case 'c':
				(void)va_arg(count, int);
				/* fall through... */
			case '%':
				n++;
				break;
			case 'd': case 'u': case 'i': case 'x':
				(void) va_arg(count, int);
				/* 20 bytes is enough to hold a 64-bit
				   integer.  Decimal takes the most space.
				   This isn't enough for octal. */
				n += 20;
				break;
			case 's':
				s = va_arg(count, char*);
				n += strlen(s);
				break;
			case 'p':
				(void) va_arg(count, int);
				/* maximum 64-bit pointer representation:
				 * 0xffffffffffffffff
				 * so 19 characters is enough.
				 * XXX I count 18 -- what's the extra for?
				 */
				n += 19;
				break;
			default:
				/* if we stumble upon an unknown
				   formatting code, copy the rest of
				   the format string to the output
				   string. (we cannot just skip the
				   code, since there's no way to know
				   what's in the argument list) */
				n += strlen(p);
				goto expand;
			}
		} else
			n++;
	}
 expand:
	/* step 2: fill the buffer */
	/* Since we've analyzed how much space we need for the worst case,
	   use sprintf directly instead of the slower PyOS_snprintf. */
	string = PyString_FromStringAndSize(NULL, n);
	if (!string)
		return NULL;

	s = PyString_AsString(string);

	for (f = format; *f; f++) {
		if (*f == '%') {
			const char* p = f++;
			Py_ssize_t i;
			int longflag = 0;
			int size_tflag = 0;
			/* parse the width.precision part (we're only
			   interested in the precision value, if any) */
			n = 0;
			while (ISDIGIT(*f))
				n = (n*10) + *f++ - '0';
			if (*f == '.') {
				f++;
				n = 0;
				while (ISDIGIT(*f))
					n = (n*10) + *f++ - '0';
			}
			while (*f && *f != '%' && !ISALPHA(*f))
				f++;
			/* handle the long flag, but only for %ld and %lu.
			   others can be added when necessary. */
			if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) {
				longflag = 1;
				++f;
			}
			/* handle the size_t flag. */
			if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
				size_tflag = 1;
				++f;
			}

			switch (*f) {
			case 'c':
				*s++ = va_arg(vargs, int);
				break;
			case 'd':
				if (longflag)
					sprintf(s, "%ld", va_arg(vargs, long));
				else if (size_tflag)
					sprintf(s, "%" PY_FORMAT_SIZE_T "d",
					        va_arg(vargs, Py_ssize_t));
				else
					sprintf(s, "%d", va_arg(vargs, int));
				s += strlen(s);
				break;
			case 'u':
				if (longflag)
					sprintf(s, "%lu",
						va_arg(vargs, unsigned long));
				else if (size_tflag)
					sprintf(s, "%" PY_FORMAT_SIZE_T "u",
					        va_arg(vargs, size_t));
				else
					sprintf(s, "%u",
						va_arg(vargs, unsigned int));
				s += strlen(s);
				break;
			case 'i':
				sprintf(s, "%i", va_arg(vargs, int));
				s += strlen(s);
				break;
			case 'x':
				sprintf(s, "%x", va_arg(vargs, int));
				s += strlen(s);
				break;
			case 's':
				p = va_arg(vargs, char*);
				i = strlen(p);
				if (n > 0 && i > n)
					i = n;
				Py_MEMCPY(s, p, i);
				s += i;
				break;
			case 'p':
				sprintf(s, "%p", va_arg(vargs, void*));
				/* %p is ill-defined:  ensure leading 0x. */
				if (s[1] == 'X')
					s[1] = 'x';
				else if (s[1] != 'x') {
					memmove(s+2, s, strlen(s)+1);
					s[0] = '0';
					s[1] = 'x';
				}
				s += strlen(s);
				break;
			case '%':
				*s++ = '%';
				break;
			default:
				strcpy(s, p);
				s += strlen(s);
				goto end;
			}
		} else
			*s++ = *f;
	}

 end:
	_PyString_Resize(&string, s - PyString_AS_STRING(string));
	return string;
}

PyObject *
PyString_FromFormat(const char *format, ...)
{
	PyObject* ret;
	va_list vargs;

#ifdef HAVE_STDARG_PROTOTYPES
	va_start(vargs, format);
#else
	va_start(vargs);
#endif
	ret = PyString_FromFormatV(format, vargs);
	va_end(vargs);
	return ret;
}

static void
string_dealloc(PyObject *op)
{
	Py_Type(op)->tp_free(op);
}

/* Unescape a backslash-escaped string. If unicode is non-zero,
   the string is a u-literal. If recode_encoding is non-zero,
   the string is UTF-8 encoded and should be re-encoded in the
   specified encoding.  */

PyObject *PyString_DecodeEscape(const char *s,
				Py_ssize_t len,
				const char *errors,
				Py_ssize_t unicode,
				const char *recode_encoding)
{
	int c;
	char *p, *buf;
	const char *end;
	PyObject *v;
	Py_ssize_t newlen = recode_encoding ? 4*len:len;
	v = PyString_FromStringAndSize((char *)NULL, newlen);
	if (v == NULL)
		return NULL;
	p = buf = PyString_AsString(v);
	end = s + len;
	while (s < end) {
		if (*s != '\\') {
		  non_esc:
			if (recode_encoding && (*s & 0x80)) {
				PyObject *u, *w;
				char *r;
				const char* t;
				Py_ssize_t rn;
				t = s;
				/* Decode non-ASCII bytes as UTF-8. */
				while (t < end && (*t & 0x80)) t++;
				u = PyUnicode_DecodeUTF8(s, t - s, errors);
				if(!u) goto failed;

				/* Recode them in target encoding. */
				w = PyUnicode_AsEncodedString(
					u, recode_encoding, errors);
				Py_DECREF(u);
				if (!w)	goto failed;

				/* Append bytes to output buffer. */
				assert(PyString_Check(w));
				r = PyString_AS_STRING(w);
				rn = PyString_GET_SIZE(w);
				Py_MEMCPY(p, r, rn);
				p += rn;
				Py_DECREF(w);
				s = t;
			} else {
				*p++ = *s++;
			}
			continue;
		}
		s++;
		if (s==end) {
			PyErr_SetString(PyExc_ValueError,
					"Trailing \\ in string");
			goto failed;
		}
		switch (*s++) {
		/* XXX This assumes ASCII! */
		case '\n': break;
		case '\\': *p++ = '\\'; break;
		case '\'': *p++ = '\''; break;
		case '\"': *p++ = '\"'; break;
		case 'b': *p++ = '\b'; break;
		case 'f': *p++ = '\014'; break; /* FF */
		case 't': *p++ = '\t'; break;
		case 'n': *p++ = '\n'; break;
		case 'r': *p++ = '\r'; break;
		case 'v': *p++ = '\013'; break; /* VT */
		case 'a': *p++ = '\007'; break; /* BEL, not classic C */
		case '0': case '1': case '2': case '3':
		case '4': case '5': case '6': case '7':
			c = s[-1] - '0';
			if (s < end && '0' <= *s && *s <= '7') {
				c = (c<<3) + *s++ - '0';
				if (s < end && '0' <= *s && *s <= '7')
					c = (c<<3) + *s++ - '0';
			}
			*p++ = c;
			break;
		case 'x':
			if (s+1 < end && ISXDIGIT(s[0]) && ISXDIGIT(s[1])) {
				unsigned int x = 0;
				c = Py_CHARMASK(*s);
				s++;
				if (ISDIGIT(c))
					x = c - '0';
				else if (ISLOWER(c))
					x = 10 + c - 'a';
				else
					x = 10 + c - 'A';
				x = x << 4;
				c = Py_CHARMASK(*s);
				s++;
				if (ISDIGIT(c))
					x += c - '0';
				else if (ISLOWER(c))
					x += 10 + c - 'a';
				else
					x += 10 + c - 'A';
				*p++ = x;
				break;
			}
			if (!errors || strcmp(errors, "strict") == 0) {
				PyErr_SetString(PyExc_ValueError,
						"invalid \\x escape");
				goto failed;
			}
			if (strcmp(errors, "replace") == 0) {
				*p++ = '?';
			} else if (strcmp(errors, "ignore") == 0)
				/* do nothing */;
			else {
				PyErr_Format(PyExc_ValueError,
					     "decoding error; unknown "
					     "error handling code: %.400s",
					     errors);
				goto failed;
			}
		default:
			*p++ = '\\';
			s--;
			goto non_esc; /* an arbitry number of unescaped
					 UTF-8 bytes may follow. */
		}
	}
	if (p-buf < newlen)
		_PyString_Resize(&v, p - buf);
	return v;
  failed:
	Py_DECREF(v);
	return NULL;
}

/* -------------------------------------------------------------------- */
/* object api */

static Py_ssize_t
string_getsize(register PyObject *op)
{
	char *s;
	Py_ssize_t len;
	if (PyString_AsStringAndSize(op, &s, &len))
		return -1;
	return len;
}

Py_ssize_t
PyString_Size(register PyObject *op)
{
	if (!PyString_Check(op))
		return string_getsize(op);
	return Py_Size(op);
}

/*const*/ char *
PyString_AsString(register PyObject *op)
{
	if (!PyString_Check(op)) {
		PyErr_Format(PyExc_TypeError,
		     "expected bytes, %.200s found", Py_Type(op)->tp_name);
		return NULL;
	}
	return ((PyStringObject *)op) -> ob_sval;
}

int
PyString_AsStringAndSize(register PyObject *obj,
			 register char **s,
			 register Py_ssize_t *len)
{
	if (s == NULL) {
		PyErr_BadInternalCall();
		return -1;
	}

	if (!PyString_Check(obj)) {
		PyErr_Format(PyExc_TypeError,
		     "expected bytes, %.200s found", Py_Type(obj)->tp_name);
		return -1;
	}

	*s = PyString_AS_STRING(obj);
	if (len != NULL)
		*len = PyString_GET_SIZE(obj);
	else if (strlen(*s) != (size_t)PyString_GET_SIZE(obj)) {
		PyErr_SetString(PyExc_TypeError,
				"expected bytes with no null");
		return -1;
	}
	return 0;
}

/* -------------------------------------------------------------------- */
/* Methods */

#define STRINGLIB_CHAR char

#define STRINGLIB_CMP memcmp
#define STRINGLIB_LEN PyString_GET_SIZE
#define STRINGLIB_NEW PyString_FromStringAndSize
#define STRINGLIB_STR PyString_AS_STRING
/* #define STRINGLIB_WANT_CONTAINS_OBJ 1 */

#define STRINGLIB_EMPTY nullstring
#define STRINGLIB_CHECK_EXACT PyString_CheckExact
#define STRINGLIB_MUTABLE 0

#include "stringlib/fastsearch.h"

#include "stringlib/count.h"
#include "stringlib/find.h"
#include "stringlib/partition.h"
#include "stringlib/ctype.h"
#include "stringlib/transmogrify.h"


PyObject *
PyString_Repr(PyObject *obj, int smartquotes)
{
	static const char *hexdigits = "0123456789abcdef";
	register PyStringObject* op = (PyStringObject*) obj;
	Py_ssize_t length = Py_Size(op);
	size_t newsize = 3 + 4 * length;
	PyObject *v;
	if (newsize > PY_SSIZE_T_MAX || (newsize-3) / 4 != length) {
		PyErr_SetString(PyExc_OverflowError,
			"bytes object is too large to make repr");
                return NULL;
	}
	v = PyUnicode_FromUnicode(NULL, newsize);
	if (v == NULL) {
		return NULL;
	}
	else {
		register Py_ssize_t i;
		register Py_UNICODE c;
		register Py_UNICODE *p = PyUnicode_AS_UNICODE(v);
		int quote;

		/* Figure out which quote to use; single is preferred */
		quote = '\'';
		if (smartquotes) {
			char *test, *start;
			start = PyString_AS_STRING(op);
			for (test = start; test < start+length; ++test) {
				if (*test == '"') {
					quote = '\''; /* back to single */
					goto decided;
				}
				else if (*test == '\'')
					quote = '"';
			}
			decided:
			;
		}

		*p++ = 'b', *p++ = quote;
		for (i = 0; i < length; i++) {
			/* There's at least enough room for a hex escape
			   and a closing quote. */
			assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 5);
			c = op->ob_sval[i];
			if (c == quote || c == '\\')
				*p++ = '\\', *p++ = c;
			else if (c == '\t')
				*p++ = '\\', *p++ = 't';
			else if (c == '\n')
				*p++ = '\\', *p++ = 'n';
			else if (c == '\r')
				*p++ = '\\', *p++ = 'r';
			else if (c < ' ' || c >= 0x7f) {
				*p++ = '\\';
				*p++ = 'x';
				*p++ = hexdigits[(c & 0xf0) >> 4];
				*p++ = hexdigits[c & 0xf];
			}
			else
				*p++ = c;
		}
		assert(newsize - (p - PyUnicode_AS_UNICODE(v)) >= 1);
		*p++ = quote;
		*p = '\0';
		if (PyUnicode_Resize(&v, (p - PyUnicode_AS_UNICODE(v)))) {
			Py_DECREF(v);
			return NULL;
		}
		return v;
	}
}

static PyObject *
string_repr(PyObject *op)
{
	return PyString_Repr(op, 1);
}

static PyObject *
string_str(PyObject *op)
{
	if (Py_BytesWarningFlag) {
		if (PyErr_WarnEx(PyExc_BytesWarning,
				 "str() on a bytes instance", 1))
			return NULL;
	}
	return string_repr(op);
}

static Py_ssize_t
string_length(PyStringObject *a)
{
	return Py_Size(a);
}

/* This is also used by PyString_Concat() */
static PyObject *
string_concat(PyObject *a, PyObject *b)
{
	Py_ssize_t size;
	Py_buffer va, vb;
	PyObject *result = NULL;

	va.len = -1;
	vb.len = -1;
	if (_getbuffer(a, &va) < 0  ||
	    _getbuffer(b, &vb) < 0) {
		PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
			     Py_Type(a)->tp_name, Py_Type(b)->tp_name);
		goto done;
	}

	/* Optimize end cases */
	if (va.len == 0 && PyString_CheckExact(b)) {
		result = b;
		Py_INCREF(result);
		goto done;
	}
	if (vb.len == 0 && PyString_CheckExact(a)) {
		result = a;
		Py_INCREF(result);
		goto done;
	}

	size = va.len + vb.len;
	if (size < 0) {
		PyErr_NoMemory();
		goto done;
	}

	result = PyString_FromStringAndSize(NULL, size);
	if (result != NULL) {
		memcpy(PyString_AS_STRING(result), va.buf, va.len);
		memcpy(PyString_AS_STRING(result) + va.len, vb.buf, vb.len);
	}

  done:
	if (va.len != -1)
		PyObject_ReleaseBuffer(a, &va);
	if (vb.len != -1)
		PyObject_ReleaseBuffer(b, &vb);
	return result;
}

static PyObject *
string_repeat(register PyStringObject *a, register Py_ssize_t n)
{
	register Py_ssize_t i;
	register Py_ssize_t j;
	register Py_ssize_t size;
	register PyStringObject *op;
	size_t nbytes;
	if (n < 0)
		n = 0;
	/* watch out for overflows:  the size can overflow int,
	 * and the # of bytes needed can overflow size_t
	 */
	size = Py_Size(a) * n;
	if (n && size / n != Py_Size(a)) {
		PyErr_SetString(PyExc_OverflowError,
			"repeated string is too long");
		return NULL;
	}
	if (size == Py_Size(a) && PyString_CheckExact(a)) {
		Py_INCREF(a);
		return (PyObject *)a;
	}
	nbytes = (size_t)size;
	if (nbytes + sizeof(PyStringObject) <= nbytes) {
		PyErr_SetString(PyExc_OverflowError,
			"repeated string is too long");
		return NULL;
	}
	op = (PyStringObject *)
		PyObject_MALLOC(sizeof(PyStringObject) + nbytes);
	if (op == NULL)
		return PyErr_NoMemory();
	PyObject_INIT_VAR(op, &PyString_Type, size);
	op->ob_shash = -1;
	op->ob_sval[size] = '\0';
	if (Py_Size(a) == 1 && n > 0) {
		memset(op->ob_sval, a->ob_sval[0] , n);
		return (PyObject *) op;
	}
	i = 0;
	if (i < size) {
		Py_MEMCPY(op->ob_sval, a->ob_sval, Py_Size(a));
		i = Py_Size(a);
	}
	while (i < size) {
		j = (i <= size-i)  ?  i  :  size-i;
		Py_MEMCPY(op->ob_sval+i, op->ob_sval, j);
		i += j;
	}
	return (PyObject *) op;
}

static int
string_contains(PyObject *self, PyObject *arg)
{
    Py_ssize_t ival = PyNumber_AsSsize_t(arg, PyExc_ValueError);
    if (ival == -1 && PyErr_Occurred()) {
        Py_buffer varg;
        int pos;
        PyErr_Clear();
        if (_getbuffer(arg, &varg) < 0)
            return -1;
        pos = stringlib_find(PyString_AS_STRING(self), Py_Size(self),
                             varg.buf, varg.len, 0);
        PyObject_ReleaseBuffer(arg, &varg);
        return pos >= 0;
    }
    if (ival < 0 || ival >= 256) {
        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
        return -1;
    }

    return memchr(PyString_AS_STRING(self), ival, Py_Size(self)) != NULL;
}

static PyObject *
string_item(PyStringObject *a, register Py_ssize_t i)
{
	if (i < 0 || i >= Py_Size(a)) {
		PyErr_SetString(PyExc_IndexError, "string index out of range");
		return NULL;
	}
	return PyInt_FromLong((unsigned char)a->ob_sval[i]);
}

static PyObject*
string_richcompare(PyStringObject *a, PyStringObject *b, int op)
{
	int c;
	Py_ssize_t len_a, len_b;
	Py_ssize_t min_len;
	PyObject *result;

	/* Make sure both arguments are strings. */
	if (!(PyString_Check(a) && PyString_Check(b))) {
		if (Py_BytesWarningFlag && (op == Py_EQ) &&
		    (PyObject_IsInstance((PyObject*)a,
					 (PyObject*)&PyUnicode_Type) ||
		    PyObject_IsInstance((PyObject*)b,
					 (PyObject*)&PyUnicode_Type))) {
			if (PyErr_WarnEx(PyExc_BytesWarning,
				    "Comparsion between bytes and string", 1))
				return NULL;
		}
		result = Py_NotImplemented;
		goto out;
	}
	if (a == b) {
		switch (op) {
		case Py_EQ:case Py_LE:case Py_GE:
			result = Py_True;
			goto out;
		case Py_NE:case Py_LT:case Py_GT:
			result = Py_False;
			goto out;
		}
	}
	if (op == Py_EQ) {
		/* Supporting Py_NE here as well does not save
		   much time, since Py_NE is rarely used.  */
		if (Py_Size(a) == Py_Size(b)
		    && (a->ob_sval[0] == b->ob_sval[0]
			&& memcmp(a->ob_sval, b->ob_sval, Py_Size(a)) == 0)) {
			result = Py_True;
		} else {
			result = Py_False;
		}
		goto out;
	}
	len_a = Py_Size(a); len_b = Py_Size(b);
	min_len = (len_a < len_b) ? len_a : len_b;
	if (min_len > 0) {
		c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
		if (c==0)
			c = memcmp(a->ob_sval, b->ob_sval, min_len);
	} else
		c = 0;
	if (c == 0)
		c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
	switch (op) {
	case Py_LT: c = c <  0; break;
	case Py_LE: c = c <= 0; break;
	case Py_EQ: assert(0);  break; /* unreachable */
	case Py_NE: c = c != 0; break;
	case Py_GT: c = c >  0; break;
	case Py_GE: c = c >= 0; break;
	default:
		result = Py_NotImplemented;
		goto out;
	}
	result = c ? Py_True : Py_False;
  out:
	Py_INCREF(result);
	return result;
}

int
_PyString_Eq(PyObject *o1, PyObject *o2)
{
	PyStringObject *a = (PyStringObject*) o1;
	PyStringObject *b = (PyStringObject*) o2;
	return Py_Size(a) == Py_Size(b)
		&& *a->ob_sval == *b->ob_sval
		&& memcmp(a->ob_sval, b->ob_sval, Py_Size(a)) == 0;
}

static long
string_hash(PyStringObject *a)
{
	register Py_ssize_t len;
	register unsigned char *p;
	register long x;

	if (a->ob_shash != -1)
		return a->ob_shash;
	len = Py_Size(a);
	p = (unsigned char *) a->ob_sval;
	x = *p << 7;
	while (--len >= 0)
		x = (1000003*x) ^ *p++;
	x ^= Py_Size(a);
	if (x == -1)
		x = -2;
	a->ob_shash = x;
	return x;
}

static PyObject*
string_subscript(PyStringObject* self, PyObject* item)
{
	if (PyIndex_Check(item)) {
		Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
		if (i == -1 && PyErr_Occurred())
			return NULL;
		if (i < 0)
			i += PyString_GET_SIZE(self);
		if (i < 0 || i >= PyString_GET_SIZE(self)) {
			PyErr_SetString(PyExc_IndexError,
					"string index out of range");
			return NULL;
		}
		return PyInt_FromLong((unsigned char)self->ob_sval[i]);
	}
	else if (PySlice_Check(item)) {
		Py_ssize_t start, stop, step, slicelength, cur, i;
		char* source_buf;
		char* result_buf;
		PyObject* result;

		if (PySlice_GetIndicesEx((PySliceObject*)item,
				 PyString_GET_SIZE(self),
				 &start, &stop, &step, &slicelength) < 0) {
			return NULL;
		}

		if (slicelength <= 0) {
			return PyString_FromStringAndSize("", 0);
		}
		else if (start == 0 && step == 1 &&
			 slicelength == PyString_GET_SIZE(self) &&
			 PyString_CheckExact(self)) {
			Py_INCREF(self);
			return (PyObject *)self;
		}
		else if (step == 1) {
			return PyString_FromStringAndSize(
				PyString_AS_STRING(self) + start,
				slicelength);
		}
		else {
			source_buf = PyString_AsString((PyObject*)self);
			result_buf = (char *)PyMem_Malloc(slicelength);
			if (result_buf == NULL)
				return PyErr_NoMemory();

			for (cur = start, i = 0; i < slicelength;
			     cur += step, i++) {
				result_buf[i] = source_buf[cur];
			}

			result = PyString_FromStringAndSize(result_buf,
							    slicelength);
			PyMem_Free(result_buf);
			return result;
		}
	}
	else {
		PyErr_Format(PyExc_TypeError,
			     "string indices must be integers, not %.200s",
			     Py_Type(item)->tp_name);
		return NULL;
	}
}

static int
string_buffer_getbuffer(PyStringObject *self, Py_buffer *view, int flags)
{
	return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_Size(self),
				 0, flags);
}

static PySequenceMethods string_as_sequence = {
	(lenfunc)string_length, /*sq_length*/
	(binaryfunc)string_concat, /*sq_concat*/
	(ssizeargfunc)string_repeat, /*sq_repeat*/
	(ssizeargfunc)string_item, /*sq_item*/
	0,		/*sq_slice*/
	0,		/*sq_ass_item*/
	0,		/*sq_ass_slice*/
	(objobjproc)string_contains /*sq_contains*/
};

static PyMappingMethods string_as_mapping = {
	(lenfunc)string_length,
	(binaryfunc)string_subscript,
	0,
};

static PyBufferProcs string_as_buffer = {
	(getbufferproc)string_buffer_getbuffer,
	NULL,
};


#define LEFTSTRIP 0
#define RIGHTSTRIP 1
#define BOTHSTRIP 2

/* Arrays indexed by above */
static const char *stripformat[] = {"|O:lstrip", "|O:rstrip", "|O:strip"};

#define STRIPNAME(i) (stripformat[i]+3)


/* Don't call if length < 2 */
#define Py_STRING_MATCH(target, offset, pattern, length)	\
  (target[offset] == pattern[0] &&				\
   target[offset+length-1] == pattern[length-1] &&		\
   !memcmp(target+offset+1, pattern+1, length-2) )


/* Overallocate the initial list to reduce the number of reallocs for small
   split sizes.  Eg, "A A A A A A A A A A".split() (10 elements) has three
   resizes, to sizes 4, 8, then 16.  Most observed string splits are for human
   text (roughly 11 words per line) and field delimited data (usually 1-10
   fields).  For large strings the split algorithms are bandwidth limited
   so increasing the preallocation likely will not improve things.*/

#define MAX_PREALLOC 12

/* 5 splits gives 6 elements */
#define PREALLOC_SIZE(maxsplit) \
	(maxsplit >= MAX_PREALLOC ? MAX_PREALLOC : maxsplit+1)

#define SPLIT_ADD(data, left, right) {				\
	str = PyString_FromStringAndSize((data) + (left),	\
					 (right) - (left));	\
	if (str == NULL)					\
		goto onError;					\
	if (count < MAX_PREALLOC) {				\
		PyList_SET_ITEM(list, count, str);		\
	} else {						\
		if (PyList_Append(list, str)) {			\
			Py_DECREF(str);				\
			goto onError;				\
		}						\
		else						\
			Py_DECREF(str);				\
	}							\
	count++; }

/* Always force the list to the expected size. */
#define FIX_PREALLOC_SIZE(list) Py_Size(list) = count

#define SKIP_SPACE(s, i, len)    { while (i<len &&  ISSPACE(s[i])) i++; }
#define SKIP_NONSPACE(s, i, len) { while (i<len && !ISSPACE(s[i])) i++; }
#define RSKIP_SPACE(s, i)        { while (i>=0  &&  ISSPACE(s[i])) i--; }
#define RSKIP_NONSPACE(s, i)     { while (i>=0  && !ISSPACE(s[i])) i--; }

Py_LOCAL_INLINE(PyObject *)
split_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxsplit)
{
	Py_ssize_t i, j, count=0;
	PyObject *str;
	PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));

	if (list == NULL)
		return NULL;

	i = j = 0;

	while (maxsplit-- > 0) {
		SKIP_SPACE(s, i, len);
		if (i==len) break;
		j = i; i++;
		SKIP_NONSPACE(s, i, len);
		SPLIT_ADD(s, j, i);
	}

	if (i < len) {
		/* Only occurs when maxsplit was reached */
		/* Skip any remaining whitespace and copy to end of string */
		SKIP_SPACE(s, i, len);
		if (i != len)
			SPLIT_ADD(s, i, len);
	}
	FIX_PREALLOC_SIZE(list);
	return list;
  onError:
	Py_DECREF(list);
	return NULL;
}

Py_LOCAL_INLINE(PyObject *)
split_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
{
	register Py_ssize_t i, j, count=0;
	PyObject *str;
	PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));

	if (list == NULL)
		return NULL;

	i = j = 0;
	while ((j < len) && (maxcount-- > 0)) {
		for(; j<len; j++) {
			/* I found that using memchr makes no difference */
			if (s[j] == ch) {
				SPLIT_ADD(s, i, j);
				i = j = j + 1;
				break;
			}
		}
	}
	if (i <= len) {
		SPLIT_ADD(s, i, len);
	}
	FIX_PREALLOC_SIZE(list);
	return list;

  onError:
	Py_DECREF(list);
	return NULL;
}

PyDoc_STRVAR(split__doc__,
"B.split([sep[, maxsplit]]) -> list of bytes\n\
\n\
Return a list of the sections in B, using sep as the delimiter.\n\
If sep is not given, B is split on ASCII whitespace characters\n\
(space, tab, return, newline, formfeed, vertical tab).\n\
If maxsplit is given, at most maxsplit splits are done.");

static PyObject *
string_split(PyStringObject *self, PyObject *args)
{
	Py_ssize_t len = PyString_GET_SIZE(self), n, i, j;
	Py_ssize_t maxsplit = -1, count=0;
	const char *s = PyString_AS_STRING(self), *sub;
	Py_buffer vsub;
	PyObject *list, *str, *subobj = Py_None;
#ifdef USE_FAST
	Py_ssize_t pos;
#endif

	if (!PyArg_ParseTuple(args, "|On:split", &subobj, &maxsplit))
		return NULL;
	if (maxsplit < 0)
		maxsplit = PY_SSIZE_T_MAX;
	if (subobj == Py_None)
		return split_whitespace(s, len, maxsplit);
	if (_getbuffer(subobj, &vsub) < 0)
		return NULL;
	sub = vsub.buf;
	n = vsub.len;

	if (n == 0) {
		PyErr_SetString(PyExc_ValueError, "empty separator");
		PyObject_ReleaseBuffer(subobj, &vsub);
		return NULL;
	}
	else if (n == 1) {
		char ch = sub[0];
		PyObject_ReleaseBuffer(subobj, &vsub);
		return split_char(s, len, ch, maxsplit);
	}

	list = PyList_New(PREALLOC_SIZE(maxsplit));
	if (list == NULL) {
		PyObject_ReleaseBuffer(subobj, &vsub);
		return NULL;
	}

#ifdef USE_FAST
	i = j = 0;
	while (maxsplit-- > 0) {
		pos = fastsearch(s+i, len-i, sub, n, FAST_SEARCH);
		if (pos < 0)
			break;
		j = i+pos;
		SPLIT_ADD(s, i, j);
		i = j + n;
	}
#else
	i = j = 0;
	while ((j+n <= len) && (maxsplit-- > 0)) {
		for (; j+n <= len; j++) {
			if (Py_STRING_MATCH(s, j, sub, n)) {
				SPLIT_ADD(s, i, j);
				i = j = j + n;
				break;
			}
		}
	}
#endif
	SPLIT_ADD(s, i, len);
	FIX_PREALLOC_SIZE(list);
	PyObject_ReleaseBuffer(subobj, &vsub);
	return list;

 onError:
	Py_DECREF(list);
	PyObject_ReleaseBuffer(subobj, &vsub);
	return NULL;
}

PyDoc_STRVAR(partition__doc__,
"B.partition(sep) -> (head, sep, tail)\n\
\n\
Searches for the separator sep in B, and returns the part before it,\n\
the separator itself, and the part after it.  If the separator is not\n\
found, returns B and two empty bytes objects.");

static PyObject *
string_partition(PyStringObject *self, PyObject *sep_obj)
{
	const char *sep;
	Py_ssize_t sep_len;

	if (PyString_Check(sep_obj)) {
		sep = PyString_AS_STRING(sep_obj);
		sep_len = PyString_GET_SIZE(sep_obj);
	}
	else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
		return NULL;

	return stringlib_partition(
		(PyObject*) self,
		PyString_AS_STRING(self), PyString_GET_SIZE(self),
		sep_obj, sep, sep_len
		);
}

PyDoc_STRVAR(rpartition__doc__,
"B.rpartition(sep) -> (tail, sep, head)\n\
\n\
Searches for the separator sep in B, starting at the end of B,\n\
and returns the part before it, the separator itself, and the\n\
part after it.  If the separator is not found, returns two empty\n\
bytes objects and B.");

static PyObject *
string_rpartition(PyStringObject *self, PyObject *sep_obj)
{
	const char *sep;
	Py_ssize_t sep_len;

	if (PyString_Check(sep_obj)) {
		sep = PyString_AS_STRING(sep_obj);
		sep_len = PyString_GET_SIZE(sep_obj);
	}
	else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
		return NULL;

	return stringlib_rpartition(
		(PyObject*) self,
		PyString_AS_STRING(self), PyString_GET_SIZE(self),
		sep_obj, sep, sep_len
		);
}

Py_LOCAL_INLINE(PyObject *)
rsplit_whitespace(const char *s, Py_ssize_t len, Py_ssize_t maxsplit)
{
	Py_ssize_t i, j, count=0;
	PyObject *str;
	PyObject *list = PyList_New(PREALLOC_SIZE(maxsplit));

	if (list == NULL)
		return NULL;

	i = j = len-1;

	while (maxsplit-- > 0) {
		RSKIP_SPACE(s, i);
		if (i<0) break;
		j = i; i--;
		RSKIP_NONSPACE(s, i);
		SPLIT_ADD(s, i + 1, j + 1);
	}
	if (i >= 0) {
		/* Only occurs when maxsplit was reached.  Skip any remaining
		   whitespace and copy to beginning of string. */
		RSKIP_SPACE(s, i);
		if (i >= 0)
			SPLIT_ADD(s, 0, i + 1);

	}
	FIX_PREALLOC_SIZE(list);
	if (PyList_Reverse(list) < 0)
		goto onError;
	return list;
  onError:
	Py_DECREF(list);
	return NULL;
}

Py_LOCAL_INLINE(PyObject *)
rsplit_char(const char *s, Py_ssize_t len, char ch, Py_ssize_t maxcount)
{
	register Py_ssize_t i, j, count=0;
	PyObject *str;
	PyObject *list = PyList_New(PREALLOC_SIZE(maxcount));

	if (list == NULL)
		return NULL;

	i = j = len - 1;
	while ((i >= 0) && (maxcount-- > 0)) {
		for (; i >= 0; i--) {
			if (s[i] == ch) {
				SPLIT_ADD(s, i + 1, j + 1);
				j = i = i - 1;
				break;
			}
		}
	}
	if (j >= -1) {
		SPLIT_ADD(s, 0, j + 1);
	}
	FIX_PREALLOC_SIZE(list);
	if (PyList_Reverse(list) < 0)
		goto onError;
	return list;

 onError:
	Py_DECREF(list);
	return NULL;
}

PyDoc_STRVAR(rsplit__doc__,
"B.rsplit([sep[, maxsplit]]) -> list of strings\n\
\n\
Return a list of the sections in B, using sep as the delimiter,\n\
starting at the end of B and working to the front.\n\
If sep is not given, B is split on ASCII whitespace characters\n\
(space, tab, return, newline, formfeed, vertical tab).\n\
If maxsplit is given, at most maxsplit splits are done.");


static PyObject *
string_rsplit(PyStringObject *self, PyObject *args)
{
	Py_ssize_t len = PyString_GET_SIZE(self), n, i, j;
	Py_ssize_t maxsplit = -1, count=0;
	const char *s = PyString_AS_STRING(self), *sub;
	Py_buffer vsub;
	PyObject *list, *str, *subobj = Py_None;

	if (!PyArg_ParseTuple(args, "|On:rsplit", &subobj, &maxsplit))
		return NULL;
	if (maxsplit < 0)
		maxsplit = PY_SSIZE_T_MAX;
	if (subobj == Py_None)
		return rsplit_whitespace(s, len, maxsplit);
	if (_getbuffer(subobj, &vsub) < 0)
		return NULL;
	sub = vsub.buf;
	n = vsub.len;

	if (n == 0) {
		PyErr_SetString(PyExc_ValueError, "empty separator");
		PyObject_ReleaseBuffer(subobj, &vsub);
		return NULL;
	}
	else if (n == 1) {
		char ch = sub[0];
		PyObject_ReleaseBuffer(subobj, &vsub);
		return rsplit_char(s, len, ch, maxsplit);
	}

	list = PyList_New(PREALLOC_SIZE(maxsplit));
	if (list == NULL) {
		PyObject_ReleaseBuffer(subobj, &vsub);
		return NULL;
	}

	j = len;
	i = j - n;

	while ( (i >= 0) && (maxsplit-- > 0) ) {
		for (; i>=0; i--) {
			if (Py_STRING_MATCH(s, i, sub, n)) {
				SPLIT_ADD(s, i + n, j);
				j = i;
				i -= n;
				break;
			}
		}
	}
	SPLIT_ADD(s, 0, j);
	FIX_PREALLOC_SIZE(list);
	if (PyList_Reverse(list) < 0)
		goto onError;
	PyObject_ReleaseBuffer(subobj, &vsub);
	return list;

onError:
	Py_DECREF(list);
	PyObject_ReleaseBuffer(subobj, &vsub);
	return NULL;
}

#undef SPLIT_ADD
#undef MAX_PREALLOC
#undef PREALLOC_SIZE


PyDoc_STRVAR(join__doc__,
"B.join(iterable_of_bytes) -> bytes\n\
\n\
Concatenates any number of bytes objects, with B in between each pair.\n\
Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'.");

static PyObject *
string_join(PyObject *self, PyObject *orig)
{
	char *sep = PyString_AS_STRING(self);
	const Py_ssize_t seplen = PyString_GET_SIZE(self);
	PyObject *res = NULL;
	char *p;
	Py_ssize_t seqlen = 0;
	size_t sz = 0;
	Py_ssize_t i;
	PyObject *seq, *item;

	seq = PySequence_Fast(orig, "");
	if (seq == NULL) {
		return NULL;
	}

	seqlen = PySequence_Size(seq);
	if (seqlen == 0) {
		Py_DECREF(seq);
		return PyString_FromString("");
	}
	if (seqlen == 1) {
		item = PySequence_Fast_GET_ITEM(seq, 0);
		if (PyString_CheckExact(item)) {
			Py_INCREF(item);
			Py_DECREF(seq);
			return item;
		}
	}

	/* There are at least two things to join, or else we have a subclass
	 * of the builtin types in the sequence.
	 * Do a pre-pass to figure out the total amount of space we'll
	 * need (sz), and see whether all argument are bytes.
	 */
	/* XXX Shouldn't we use _getbuffer() on these items instead? */
	for (i = 0; i < seqlen; i++) {
		const size_t old_sz = sz;
		item = PySequence_Fast_GET_ITEM(seq, i);
		if (!PyString_Check(item) && !PyBytes_Check(item)) {
			PyErr_Format(PyExc_TypeError,
				     "sequence item %zd: expected bytes,"
				     " %.80s found",
				     i, Py_Type(item)->tp_name);
			Py_DECREF(seq);
			return NULL;
		}
		sz += Py_Size(item);
		if (i != 0)
			sz += seplen;
		if (sz < old_sz || sz > PY_SSIZE_T_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			    "join() result is too long for a Python string");
			Py_DECREF(seq);
			return NULL;
		}
	}

	/* Allocate result space. */
	res = PyString_FromStringAndSize((char*)NULL, sz);
	if (res == NULL) {
		Py_DECREF(seq);
		return NULL;
	}

	/* Catenate everything. */
	/* I'm not worried about a PyBytes item growing because there's
	   nowhere in this function where we release the GIL. */
	p = PyString_AS_STRING(res);
	for (i = 0; i < seqlen; ++i) {
		size_t n;
                char *q;
		if (i) {
			Py_MEMCPY(p, sep, seplen);
			p += seplen;
		}
		item = PySequence_Fast_GET_ITEM(seq, i);
		n = Py_Size(item);
                if (PyString_Check(item))
			q = PyString_AS_STRING(item);
		else
			q = PyBytes_AS_STRING(item);
		Py_MEMCPY(p, q, n);
		p += n;
	}

	Py_DECREF(seq);
	return res;
}

PyObject *
_PyString_Join(PyObject *sep, PyObject *x)
{
	assert(sep != NULL && PyString_Check(sep));
	assert(x != NULL);
	return string_join(sep, x);
}

Py_LOCAL_INLINE(void)
string_adjust_indices(Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t len)
{
	if (*end > len)
		*end = len;
	else if (*end < 0)
		*end += len;
	if (*end < 0)
		*end = 0;
	if (*start < 0)
		*start += len;
	if (*start < 0)
		*start = 0;
}

Py_LOCAL_INLINE(Py_ssize_t)
string_find_internal(PyStringObject *self, PyObject *args, int dir)
{
	PyObject *subobj;
	const char *sub;
	Py_ssize_t sub_len;
	Py_ssize_t start=0, end=PY_SSIZE_T_MAX;
	PyObject *obj_start=Py_None, *obj_end=Py_None;

	if (!PyArg_ParseTuple(args, "O|OO:find/rfind/index/rindex", &subobj,
		&obj_start, &obj_end))
		return -2;
	/* To support None in "start" and "end" arguments, meaning
	   the same as if they were not passed.
	*/
	if (obj_start != Py_None)
		if (!_PyEval_SliceIndex(obj_start, &start))
	        return -2;
	if (obj_end != Py_None)
		if (!_PyEval_SliceIndex(obj_end, &end))
	        return -2;

	if (PyString_Check(subobj)) {
		sub = PyString_AS_STRING(subobj);
		sub_len = PyString_GET_SIZE(subobj);
	}
	else if (PyObject_AsCharBuffer(subobj, &sub, &sub_len))
		/* XXX - the "expected a character buffer object" is pretty
		   confusing for a non-expert.  remap to something else ? */
		return -2;

	if (dir > 0)
		return stringlib_find_slice(
			PyString_AS_STRING(self), PyString_GET_SIZE(self),
			sub, sub_len, start, end);
	else
		return stringlib_rfind_slice(
			PyString_AS_STRING(self), PyString_GET_SIZE(self),
			sub, sub_len, start, end);
}


PyDoc_STRVAR(find__doc__,
"B.find(sub [,start [,end]]) -> int\n\
\n\
Return the lowest index in S where substring sub is found,\n\
such that sub is contained within s[start:end].  Optional\n\
arguments start and end are interpreted as in slice notation.\n\
\n\
Return -1 on failure.");

static PyObject *
string_find(PyStringObject *self, PyObject *args)
{
	Py_ssize_t result = string_find_internal(self, args, +1);
	if (result == -2)
		return NULL;
	return PyInt_FromSsize_t(result);
}


PyDoc_STRVAR(index__doc__,
"B.index(sub [,start [,end]]) -> int\n\
\n\
Like B.find() but raise ValueError when the substring is not found.");

static PyObject *
string_index(PyStringObject *self, PyObject *args)
{
	Py_ssize_t result = string_find_internal(self, args, +1);
	if (result == -2)
		return NULL;
	if (result == -1) {
		PyErr_SetString(PyExc_ValueError,
				"substring not found");
		return NULL;
	}
	return PyInt_FromSsize_t(result);
}


PyDoc_STRVAR(rfind__doc__,
"B.rfind(sub [,start [,end]]) -> int\n\
\n\
Return the highest index in B where substring sub is found,\n\
such that sub is contained within s[start:end].  Optional\n\
arguments start and end are interpreted as in slice notation.\n\
\n\
Return -1 on failure.");

static PyObject *
string_rfind(PyStringObject *self, PyObject *args)
{
	Py_ssize_t result = string_find_internal(self, args, -1);
	if (result == -2)
		return NULL;
	return PyInt_FromSsize_t(result);
}


PyDoc_STRVAR(rindex__doc__,
"B.rindex(sub [,start [,end]]) -> int\n\
\n\
Like B.rfind() but raise ValueError when the substring is not found.");

static PyObject *
string_rindex(PyStringObject *self, PyObject *args)
{
	Py_ssize_t result = string_find_internal(self, args, -1);
	if (result == -2)
		return NULL;
	if (result == -1) {
		PyErr_SetString(PyExc_ValueError,
				"substring not found");
		return NULL;
	}
	return PyInt_FromSsize_t(result);
}


Py_LOCAL_INLINE(PyObject *)
do_xstrip(PyStringObject *self, int striptype, PyObject *sepobj)
{
	Py_buffer vsep;
	char *s = PyString_AS_STRING(self);
	Py_ssize_t len = PyString_GET_SIZE(self);
	char *sep;
	Py_ssize_t seplen;
	Py_ssize_t i, j;

	if (_getbuffer(sepobj, &vsep) < 0)
		return NULL;
	sep = vsep.buf;
	seplen = vsep.len;

	i = 0;
	if (striptype != RIGHTSTRIP) {
		while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) {
			i++;
		}
	}

	j = len;
	if (striptype != LEFTSTRIP) {
		do {
			j--;
		} while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen));
		j++;
	}

	PyObject_ReleaseBuffer(sepobj, &vsep);

	if (i == 0 && j == len && PyString_CheckExact(self)) {
		Py_INCREF(self);
		return (PyObject*)self;
	}
	else
		return PyString_FromStringAndSize(s+i, j-i);
}


Py_LOCAL_INLINE(PyObject *)
do_strip(PyStringObject *self, int striptype)
{
	char *s = PyString_AS_STRING(self);
	Py_ssize_t len = PyString_GET_SIZE(self), i, j;

	i = 0;
	if (striptype != RIGHTSTRIP) {
		while (i < len && ISSPACE(s[i])) {
			i++;
		}
	}

	j = len;
	if (striptype != LEFTSTRIP) {
		do {
			j--;
		} while (j >= i && ISSPACE(s[j]));
		j++;
	}

	if (i == 0 && j == len && PyString_CheckExact(self)) {
		Py_INCREF(self);
		return (PyObject*)self;
	}
	else
		return PyString_FromStringAndSize(s+i, j-i);
}


Py_LOCAL_INLINE(PyObject *)
do_argstrip(PyStringObject *self, int striptype, PyObject *args)
{
	PyObject *sep = NULL;

	if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
		return NULL;

	if (sep != NULL && sep != Py_None) {
		return do_xstrip(self, striptype, sep);
	}
	return do_strip(self, striptype);
}


PyDoc_STRVAR(strip__doc__,
"B.strip([bytes]) -> bytes\n\
\n\
Strip leading and trailing bytes contained in the argument.\n\
If the argument is omitted, strip trailing ASCII whitespace.");
static PyObject *
string_strip(PyStringObject *self, PyObject *args)
{
	if (PyTuple_GET_SIZE(args) == 0)
		return do_strip(self, BOTHSTRIP); /* Common case */
	else
		return do_argstrip(self, BOTHSTRIP, args);
}


PyDoc_STRVAR(lstrip__doc__,
"B.lstrip([bytes]) -> bytes\n\
\n\
Strip leading bytes contained in the argument.\n\
If the argument is omitted, strip leading ASCII whitespace.");
static PyObject *
string_lstrip(PyStringObject *self, PyObject *args)
{
	if (PyTuple_GET_SIZE(args) == 0)
		return do_strip(self, LEFTSTRIP); /* Common case */
	else
		return do_argstrip(self, LEFTSTRIP, args);
}


PyDoc_STRVAR(rstrip__doc__,
"B.rstrip([bytes]) -> bytes\n\
\n\
Strip trailing bytes contained in the argument.\n\
If the argument is omitted, strip trailing ASCII whitespace.");
static PyObject *
string_rstrip(PyStringObject *self, PyObject *args)
{
	if (PyTuple_GET_SIZE(args) == 0)
		return do_strip(self, RIGHTSTRIP); /* Common case */
	else
		return do_argstrip(self, RIGHTSTRIP, args);
}


PyDoc_STRVAR(count__doc__,
"B.count(sub [,start [,end]]) -> int\n\
\n\
Return the number of non-overlapping occurrences of substring sub in\n\
string S[start:end].  Optional arguments start and end are interpreted\n\
as in slice notation.");

static PyObject *
string_count(PyStringObject *self, PyObject *args)
{
	PyObject *sub_obj;
	const char *str = PyString_AS_STRING(self), *sub;
	Py_ssize_t sub_len;
	Py_ssize_t start = 0, end = PY_SSIZE_T_MAX;

	if (!PyArg_ParseTuple(args, "O|O&O&:count", &sub_obj,
		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
		return NULL;

	if (PyString_Check(sub_obj)) {
		sub = PyString_AS_STRING(sub_obj);
		sub_len = PyString_GET_SIZE(sub_obj);
	}
	else if (PyObject_AsCharBuffer(sub_obj, &sub, &sub_len))
		return NULL;

	string_adjust_indices(&start, &end, PyString_GET_SIZE(self));

	return PyInt_FromSsize_t(
		stringlib_count(str + start, end - start, sub, sub_len)
		);
}


PyDoc_STRVAR(translate__doc__,
"B.translate(table[, deletechars]) -> bytes\n\
\n\
Return a copy of B, where all characters occurring in the\n\
optional argument deletechars are removed, and the remaining\n\
characters have been mapped through the given translation\n\
table, which must be a bytes object of length 256.");

static PyObject *
string_translate(PyStringObject *self, PyObject *args)
{
	register char *input, *output;
	const char *table;
	register Py_ssize_t i, c, changed = 0;
	PyObject *input_obj = (PyObject*)self;
	const char *output_start, *del_table=NULL;
	Py_ssize_t inlen, tablen, dellen = 0;
	PyObject *result;
	int trans_table[256];
	PyObject *tableobj, *delobj = NULL;

	if (!PyArg_UnpackTuple(args, "translate", 1, 2,
			      &tableobj, &delobj))
		return NULL;

	if (PyString_Check(tableobj)) {
		table = PyString_AS_STRING(tableobj);
		tablen = PyString_GET_SIZE(tableobj);
	}
	else if (tableobj == Py_None) {
		table = NULL;
		tablen = 256;
	}
	else if (PyObject_AsCharBuffer(tableobj, &table, &tablen))
		return NULL;

	if (tablen != 256) {
		PyErr_SetString(PyExc_ValueError,
		  "translation table must be 256 characters long");
		return NULL;
	}

	if (delobj != NULL) {
		if (PyString_Check(delobj)) {
			del_table = PyString_AS_STRING(delobj);
			dellen = PyString_GET_SIZE(delobj);
		}
		else if (PyUnicode_Check(delobj)) {
			PyErr_SetString(PyExc_TypeError,
			"deletions are implemented differently for unicode");
			return NULL;
		}
		else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen))
			return NULL;
	}
	else {
		del_table = NULL;
		dellen = 0;
	}

	inlen = PyString_GET_SIZE(input_obj);
	result = PyString_FromStringAndSize((char *)NULL, inlen);
	if (result == NULL)
		return NULL;
	output_start = output = PyString_AsString(result);
	input = PyString_AS_STRING(input_obj);

	if (dellen == 0 && table != NULL) {
		/* If no deletions are required, use faster code */
		for (i = inlen; --i >= 0; ) {
			c = Py_CHARMASK(*input++);
			if (Py_CHARMASK((*output++ = table[c])) != c)
				changed = 1;
		}
		if (changed || !PyString_CheckExact(input_obj))
			return result;
		Py_DECREF(result);
		Py_INCREF(input_obj);
		return input_obj;
	}

	if (table == NULL) {
		for (i = 0; i < 256; i++)
			trans_table[i] = Py_CHARMASK(i);
	} else {
		for (i = 0; i < 256; i++)
			trans_table[i] = Py_CHARMASK(table[i]);
	}

	for (i = 0; i < dellen; i++)
		trans_table[(int) Py_CHARMASK(del_table[i])] = -1;

	for (i = inlen; --i >= 0; ) {
		c = Py_CHARMASK(*input++);
		if (trans_table[c] != -1)
			if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
				continue;
		changed = 1;
	}
	if (!changed && PyString_CheckExact(input_obj)) {
		Py_DECREF(result);
		Py_INCREF(input_obj);
		return input_obj;
	}
	/* Fix the size of the resulting string */
	if (inlen > 0)
		_PyString_Resize(&result, output - output_start);
	return result;
}


#define FORWARD 1
#define REVERSE -1

/* find and count characters and substrings */

#define findchar(target, target_len, c)				\
  ((char *)memchr((const void *)(target), c, target_len))

/* String ops must return a string.  */
/* If the object is subclass of string, create a copy */
Py_LOCAL(PyStringObject *)
return_self(PyStringObject *self)
{
	if (PyString_CheckExact(self)) {
		Py_INCREF(self);
		return self;
	}
	return (PyStringObject *)PyString_FromStringAndSize(
		PyString_AS_STRING(self),
		PyString_GET_SIZE(self));
}

Py_LOCAL_INLINE(Py_ssize_t)
countchar(const char *target, int target_len, char c, Py_ssize_t maxcount)
{
	Py_ssize_t count=0;
	const char *start=target;
	const char *end=target+target_len;

	while ( (start=findchar(start, end-start, c)) != NULL ) {
		count++;
		if (count >= maxcount)
			break;
		start += 1;
	}
	return count;
}

Py_LOCAL(Py_ssize_t)
findstring(const char *target, Py_ssize_t target_len,
	   const char *pattern, Py_ssize_t pattern_len,
	   Py_ssize_t start,
	   Py_ssize_t end,
	   int direction)
{
	if (start < 0) {
		start += target_len;
		if (start < 0)
			start = 0;
	}
	if (end > target_len) {
		end = target_len;
	} else if (end < 0) {
		end += target_len;
		if (end < 0)
			end = 0;
	}

	/* zero-length substrings always match at the first attempt */
	if (pattern_len == 0)
		return (direction > 0) ? start : end;

	end -= pattern_len;

	if (direction < 0) {
		for (; end >= start; end--)
			if (Py_STRING_MATCH(target, end, pattern, pattern_len))
				return end;
	} else {
		for (; start <= end; start++)
			if (Py_STRING_MATCH(target, start,pattern,pattern_len))
				return start;
	}
	return -1;
}

Py_LOCAL_INLINE(Py_ssize_t)
countstring(const char *target, Py_ssize_t target_len,
	    const char *pattern, Py_ssize_t pattern_len,
	    Py_ssize_t start,
	    Py_ssize_t end,
	    int direction, Py_ssize_t maxcount)
{
	Py_ssize_t count=0;

	if (start < 0) {
		start += target_len;
		if (start < 0)
			start = 0;
	}
	if (end > target_len) {
		end = target_len;
	} else if (end < 0) {
		end += target_len;
		if (end < 0)
			end = 0;
	}

	/* zero-length substrings match everywhere */
	if (pattern_len == 0 || maxcount == 0) {
		if (target_len+1 < maxcount)
			return target_len+1;
		return maxcount;
	}

	end -= pattern_len;
	if (direction < 0) {
		for (; (end >= start); end--)
			if (Py_STRING_MATCH(target, end,pattern,pattern_len)) {
				count++;
				if (--maxcount <= 0) break;
				end -= pattern_len-1;
			}
	} else {
		for (; (start <= end); start++)
			if (Py_STRING_MATCH(target, start,
					    pattern, pattern_len)) {
				count++;
				if (--maxcount <= 0)
					break;
				start += pattern_len-1;
			}
	}
	return count;
}


/* Algorithms for different cases of string replacement */

/* len(self)>=1, from="", len(to)>=1, maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_interleave(PyStringObject *self,
		   const char *to_s, Py_ssize_t to_len,
		   Py_ssize_t maxcount)
{
	char *self_s, *result_s;
	Py_ssize_t self_len, result_len;
	Py_ssize_t count, i, product;
	PyStringObject *result;

	self_len = PyString_GET_SIZE(self);

	/* 1 at the end plus 1 after every character */
	count = self_len+1;
	if (maxcount < count)
		count = maxcount;

	/* Check for overflow */
	/*   result_len = count * to_len + self_len; */
	product = count * to_len;
	if (product / to_len != count) {
		PyErr_SetString(PyExc_OverflowError,
				"replace string is too long");
		return NULL;
	}
	result_len = product + self_len;
	if (result_len < 0) {
		PyErr_SetString(PyExc_OverflowError,
				"replace string is too long");
		return NULL;
	}

	if (! (result = (PyStringObject *)
	                 PyString_FromStringAndSize(NULL, result_len)) )
		return NULL;

	self_s = PyString_AS_STRING(self);
	result_s = PyString_AS_STRING(result);

	/* TODO: special case single character, which doesn't need memcpy */

	/* Lay the first one down (guaranteed this will occur) */
	Py_MEMCPY(result_s, to_s, to_len);
	result_s += to_len;
	count -= 1;

	for (i=0; i<count; i++) {
		*result_s++ = *self_s++;
		Py_MEMCPY(result_s, to_s, to_len);
		result_s += to_len;
	}

	/* Copy the rest of the original string */
	Py_MEMCPY(result_s, self_s, self_len-i);

	return result;
}

/* Special case for deleting a single character */
/* len(self)>=1, len(from)==1, to="", maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_delete_single_character(PyStringObject *self,
				char from_c, Py_ssize_t maxcount)
{
	char *self_s, *result_s;
	char *start, *next, *end;
	Py_ssize_t self_len, result_len;
	Py_ssize_t count;
	PyStringObject *result;

	self_len = PyString_GET_SIZE(self);
	self_s = PyString_AS_STRING(self);

	count = countchar(self_s, self_len, from_c, maxcount);
	if (count == 0) {
		return return_self(self);
	}

	result_len = self_len - count;  /* from_len == 1 */
	assert(result_len>=0);

	if ( (result = (PyStringObject *)
	                PyString_FromStringAndSize(NULL, result_len)) == NULL)
		return NULL;
	result_s = PyString_AS_STRING(result);

	start = self_s;
	end = self_s + self_len;
	while (count-- > 0) {
		next = findchar(start, end-start, from_c);
		if (next == NULL)
			break;
		Py_MEMCPY(result_s, start, next-start);
		result_s += (next-start);
		start = next+1;
	}
	Py_MEMCPY(result_s, start, end-start);

	return result;
}

/* len(self)>=1, len(from)>=2, to="", maxcount>=1 */

Py_LOCAL(PyStringObject *)
replace_delete_substring(PyStringObject *self,
			 const char *from_s, Py_ssize_t from_len,
			 Py_ssize_t maxcount) {
	char *self_s, *result_s;
	char *start, *next, *end;
	Py_ssize_t self_len, result_len;
	Py_ssize_t count, offset;
	PyStringObject *result;

	self_len = PyString_GET_SIZE(self);
	self_s = PyString_AS_STRING(self);

	count = countstring(self_s, self_len,
			    from_s, from_len,
			    0, self_len, 1,
			    maxcount);

	if (count == 0) {
		/* no matches */
		return return_self(self);
	}

	result_len = self_len - (count * from_len);
	assert (result_len>=0);

	if ( (result = (PyStringObject *)
	      PyString_FromStringAndSize(NULL, result_len)) == NULL )
		return NULL;

	result_s = PyString_AS_STRING(result);

	start = self_s;
	end = self_s + self_len;
	while (count-- > 0) {
		offset = findstring(start, end-start,
				    from_s, from_len,
				    0, end-start, FORWARD);
		if (offset == -1)
			break;
		next = start + offset;

		Py_MEMCPY(result_s, start, next-start);

		result_s += (next-start);
		start = next+from_len;
	}
	Py_MEMCPY(result_s, start, end-start);
	return result;
}

/* len(self)>=1, len(from)==len(to)==1, maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_single_character_in_place(PyStringObject *self,
				  char from_c, char to_c,
				  Py_ssize_t maxcount)
{
	char *self_s, *result_s, *start, *end, *next;
	Py_ssize_t self_len;
	PyStringObject *result;

	/* The result string will be the same size */
	self_s = PyString_AS_STRING(self);
	self_len = PyString_GET_SIZE(self);

	next = findchar(self_s, self_len, from_c);

	if (next == NULL) {
		/* No matches; return the original string */
		return return_self(self);
	}

	/* Need to make a new string */
	result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
	if (result == NULL)
		return NULL;
	result_s = PyString_AS_STRING(result);
	Py_MEMCPY(result_s, self_s, self_len);

	/* change everything in-place, starting with this one */
	start =  result_s + (next-self_s);
	*start = to_c;
	start++;
	end = result_s + self_len;

	while (--maxcount > 0) {
		next = findchar(start, end-start, from_c);
		if (next == NULL)
			break;
		*next = to_c;
		start = next+1;
	}

	return result;
}

/* len(self)>=1, len(from)==len(to)>=2, maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_substring_in_place(PyStringObject *self,
			   const char *from_s, Py_ssize_t from_len,
			   const char *to_s, Py_ssize_t to_len,
			   Py_ssize_t maxcount)
{
	char *result_s, *start, *end;
	char *self_s;
	Py_ssize_t self_len, offset;
	PyStringObject *result;

	/* The result string will be the same size */

	self_s = PyString_AS_STRING(self);
	self_len = PyString_GET_SIZE(self);

	offset = findstring(self_s, self_len,
			    from_s, from_len,
			    0, self_len, FORWARD);
	if (offset == -1) {
		/* No matches; return the original string */
		return return_self(self);
	}

	/* Need to make a new string */
	result = (PyStringObject *) PyString_FromStringAndSize(NULL, self_len);
	if (result == NULL)
		return NULL;
	result_s = PyString_AS_STRING(result);
	Py_MEMCPY(result_s, self_s, self_len);

	/* change everything in-place, starting with this one */
	start =  result_s + offset;
	Py_MEMCPY(start, to_s, from_len);
	start += from_len;
	end = result_s + self_len;

	while ( --maxcount > 0) {
		offset = findstring(start, end-start,
				    from_s, from_len,
				    0, end-start, FORWARD);
		if (offset==-1)
			break;
		Py_MEMCPY(start+offset, to_s, from_len);
		start += offset+from_len;
	}

	return result;
}

/* len(self)>=1, len(from)==1, len(to)>=2, maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_single_character(PyStringObject *self,
			 char from_c,
			 const char *to_s, Py_ssize_t to_len,
			 Py_ssize_t maxcount)
{
	char *self_s, *result_s;
	char *start, *next, *end;
	Py_ssize_t self_len, result_len;
	Py_ssize_t count, product;
	PyStringObject *result;

	self_s = PyString_AS_STRING(self);
	self_len = PyString_GET_SIZE(self);

	count = countchar(self_s, self_len, from_c, maxcount);
	if (count == 0) {
		/* no matches, return unchanged */
		return return_self(self);
	}

	/* use the difference between current and new, hence the "-1" */
	/*   result_len = self_len + count * (to_len-1)  */
	product = count * (to_len-1);
	if (product / (to_len-1) != count) {
		PyErr_SetString(PyExc_OverflowError,
				"replace string is too long");
		return NULL;
	}
	result_len = self_len + product;
	if (result_len < 0) {
		PyErr_SetString(PyExc_OverflowError,
				"replace string is too long");
		return NULL;
	}

	if ( (result = (PyStringObject *)
	      PyString_FromStringAndSize(NULL, result_len)) == NULL)
		return NULL;
	result_s = PyString_AS_STRING(result);

	start = self_s;
	end = self_s + self_len;
	while (count-- > 0) {
		next = findchar(start, end-start, from_c);
		if (next == NULL)
			break;

		if (next == start) {
			/* replace with the 'to' */
			Py_MEMCPY(result_s, to_s, to_len);
			result_s += to_len;
			start += 1;
		} else {
			/* copy the unchanged old then the 'to' */
			Py_MEMCPY(result_s, start, next-start);
			result_s += (next-start);
			Py_MEMCPY(result_s, to_s, to_len);
			result_s += to_len;
			start = next+1;
		}
	}
	/* Copy the remainder of the remaining string */
	Py_MEMCPY(result_s, start, end-start);

	return result;
}

/* len(self)>=1, len(from)>=2, len(to)>=2, maxcount>=1 */
Py_LOCAL(PyStringObject *)
replace_substring(PyStringObject *self,
		  const char *from_s, Py_ssize_t from_len,
		  const char *to_s, Py_ssize_t to_len,
		  Py_ssize_t maxcount) {
	char *self_s, *result_s;
	char *start, *next, *end;
	Py_ssize_t self_len, result_len;
	Py_ssize_t count, offset, product;
	PyStringObject *result;

	self_s = PyString_AS_STRING(self);
	self_len = PyString_GET_SIZE(self);

	count = countstring(self_s, self_len,
			    from_s, from_len,
			    0, self_len, FORWARD, maxcount);
	if (count == 0) {
		/* no matches, return unchanged */
		return return_self(self);
	}

	/* Check for overflow */
	/*    result_len = self_len + count * (to_len-from_len) */
	product = count * (to_len-from_len);
	if (product / (to_len-from_len) != count) {
		PyErr_SetString(PyExc_OverflowError,
				"replace string is too long");
		return NULL;
	}
	result_len = self_len + product;
	if (result_len < 0) {
		PyErr_SetString(PyExc_OverflowError,
				"replace string is too long");
		return NULL;
	}

	if ( (result = (PyStringObject *)
	      PyString_FromStringAndSize(NULL, result_len)) == NULL)
		return NULL;
	result_s = PyString_AS_STRING(result);

	start = self_s;
	end = self_s + self_len;
	while (count-- > 0) {
		offset = findstring(start, end-start,
				    from_s, from_len,
				    0, end-start, FORWARD);
		if (offset == -1)
			break;
		next = start+offset;
		if (next == start) {
			/* replace with the 'to' */
			Py_MEMCPY(result_s, to_s, to_len);
			result_s += to_len;
			start += from_len;
		} else {
			/* copy the unchanged old then the 'to' */
			Py_MEMCPY(result_s, start, next-start);
			result_s += (next-start);
			Py_MEMCPY(result_s, to_s, to_len);
			result_s += to_len;
			start = next+from_len;
		}
	}
	/* Copy the remainder of the remaining string */
	Py_MEMCPY(result_s, start, end-start);

	return result;
}


Py_LOCAL(PyStringObject *)
replace(PyStringObject *self,
	const char *from_s, Py_ssize_t from_len,
	const char *to_s, Py_ssize_t to_len,
	Py_ssize_t maxcount)
{
	if (maxcount < 0) {
		maxcount = PY_SSIZE_T_MAX;
	} else if (maxcount == 0 || PyString_GET_SIZE(self) == 0) {
		/* nothing to do; return the original string */
		return return_self(self);
	}

	if (maxcount == 0 ||
	    (from_len == 0 && to_len == 0)) {
		/* nothing to do; return the original string */
		return return_self(self);
	}

	/* Handle zero-length special cases */

	if (from_len == 0) {
		/* insert the 'to' string everywhere.   */
		/*    >>> "Python".replace("", ".")     */
		/*    '.P.y.t.h.o.n.'                   */
		return replace_interleave(self, to_s, to_len, maxcount);
	}

	/* Except for "".replace("", "A") == "A" there is no way beyond this */
	/* point for an empty self string to generate a non-empty string */
	/* Special case so the remaining code always gets a non-empty string */
	if (PyString_GET_SIZE(self) == 0) {
		return return_self(self);
	}

	if (to_len == 0) {
		/* delete all occurances of 'from' string */
		if (from_len == 1) {
			return replace_delete_single_character(
				self, from_s[0], maxcount);
		} else {
			return replace_delete_substring(self, from_s,
							from_len, maxcount);
		}
	}

	/* Handle special case where both strings have the same length */

	if (from_len == to_len) {
		if (from_len == 1) {
			return replace_single_character_in_place(
				self,
				from_s[0],
				to_s[0],
				maxcount);
		} else {
			return replace_substring_in_place(
				self, from_s, from_len, to_s, to_len,
				maxcount);
		}
	}

	/* Otherwise use the more generic algorithms */
	if (from_len == 1) {
		return replace_single_character(self, from_s[0],
						to_s, to_len, maxcount);
	} else {
		/* len('from')>=2, len('to')>=1 */
		return replace_substring(self, from_s, from_len, to_s, to_len,
					 maxcount);
	}
}

PyDoc_STRVAR(replace__doc__,
"B.replace(old, new[, count]) -> bytes\n\
\n\
Return a copy of B with all occurrences of subsection\n\
old replaced by new.  If the optional argument count is\n\
given, only the first count occurrences are replaced.");

static PyObject *
string_replace(PyStringObject *self, PyObject *args)
{
	Py_ssize_t count = -1;
	PyObject *from, *to;
	const char *from_s, *to_s;
	Py_ssize_t from_len, to_len;

	if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
		return NULL;

	if (PyString_Check(from)) {
		from_s = PyString_AS_STRING(from);
		from_len = PyString_GET_SIZE(from);
	}
	else if (PyObject_AsCharBuffer(from, &from_s, &from_len))
		return NULL;

	if (PyString_Check(to)) {
		to_s = PyString_AS_STRING(to);
		to_len = PyString_GET_SIZE(to);
	}
	else if (PyObject_AsCharBuffer(to, &to_s, &to_len))
		return NULL;

	return (PyObject *)replace((PyStringObject *) self,
				   from_s, from_len,
				   to_s, to_len, count);
}

/** End DALKE **/

/* Matches the end (direction >= 0) or start (direction < 0) of self
 * against substr, using the start and end arguments. Returns
 * -1 on error, 0 if not found and 1 if found.
 */
Py_LOCAL(int)
_string_tailmatch(PyStringObject *self, PyObject *substr, Py_ssize_t start,
		  Py_ssize_t end, int direction)
{
	Py_ssize_t len = PyString_GET_SIZE(self);
	Py_ssize_t slen;
	const char* sub;
	const char* str;

	if (PyString_Check(substr)) {
		sub = PyString_AS_STRING(substr);
		slen = PyString_GET_SIZE(substr);
	}
	else if (PyObject_AsCharBuffer(substr, &sub, &slen))
		return -1;
	str = PyString_AS_STRING(self);

	string_adjust_indices(&start, &end, len);

	if (direction < 0) {
		/* startswith */
		if (start+slen > len)
			return 0;
	} else {
		/* endswith */
		if (end-start < slen || start > len)
			return 0;

		if (end-slen > start)
			start = end - slen;
	}
	if (end-start >= slen)
		return ! memcmp(str+start, sub, slen);
	return 0;
}


PyDoc_STRVAR(startswith__doc__,
"B.startswith(prefix [,start [,end]]) -> bool\n\
\n\
Return True if B starts with the specified prefix, False otherwise.\n\
With optional start, test B beginning at that position.\n\
With optional end, stop comparing B at that position.\n\
prefix can also be a tuple of strings to try.");

static PyObject *
string_startswith(PyStringObject *self, PyObject *args)
{
	Py_ssize_t start = 0;
	Py_ssize_t end = PY_SSIZE_T_MAX;
	PyObject *subobj;
	int result;

	if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
		return NULL;
	if (PyTuple_Check(subobj)) {
		Py_ssize_t i;
		for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
			result = _string_tailmatch(self,
					PyTuple_GET_ITEM(subobj, i),
					start, end, -1);
			if (result == -1)
				return NULL;
			else if (result) {
				Py_RETURN_TRUE;
			}
		}
		Py_RETURN_FALSE;
	}
	result = _string_tailmatch(self, subobj, start, end, -1);
	if (result == -1)
		return NULL;
	else
		return PyBool_FromLong(result);
}


PyDoc_STRVAR(endswith__doc__,
"B.endswith(suffix [,start [,end]]) -> bool\n\
\n\
Return True if B ends with the specified suffix, False otherwise.\n\
With optional start, test B beginning at that position.\n\
With optional end, stop comparing B at that position.\n\
suffix can also be a tuple of strings to try.");

static PyObject *
string_endswith(PyStringObject *self, PyObject *args)
{
	Py_ssize_t start = 0;
	Py_ssize_t end = PY_SSIZE_T_MAX;
	PyObject *subobj;
	int result;

	if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
		_PyEval_SliceIndex, &start, _PyEval_SliceIndex, &end))
		return NULL;
	if (PyTuple_Check(subobj)) {
		Py_ssize_t i;
		for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
			result = _string_tailmatch(self,
					PyTuple_GET_ITEM(subobj, i),
					start, end, +1);
			if (result == -1)
				return NULL;
			else if (result) {
				Py_RETURN_TRUE;
			}
		}
		Py_RETURN_FALSE;
	}
	result = _string_tailmatch(self, subobj, start, end, +1);
	if (result == -1)
		return NULL;
	else
		return PyBool_FromLong(result);
}


PyDoc_STRVAR(decode__doc__,
"B.decode([encoding[, errors]]) -> object\n\
\n\
Decodes S using the codec registered for encoding. encoding defaults\n\
to the default encoding. errors may be given to set a different error\n\
handling scheme.  Default is 'strict' meaning that encoding errors raise\n\
a UnicodeDecodeError.  Other possible values are 'ignore' and 'replace'\n\
as well as any other name registerd with codecs.register_error that is\n\
able to handle UnicodeDecodeErrors.");

static PyObject *
string_decode(PyObject *self, PyObject *args)
{
	const char *encoding = NULL;
	const char *errors = NULL;

	if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
		return NULL;
	if (encoding == NULL)
		encoding = PyUnicode_GetDefaultEncoding();
	return PyCodec_Decode(self, encoding, errors);
}


PyDoc_STRVAR(fromhex_doc,
"bytes.fromhex(string) -> bytes\n\
\n\
Create a bytes object from a string of hexadecimal numbers.\n\
Spaces between two numbers are accepted.\n\
Example: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'.");

static int
hex_digit_to_int(Py_UNICODE c)
{
	if (c >= 128)
		return -1;
	if (ISDIGIT(c))
		return c - '0';
	else {
		if (ISUPPER(c))
			c = TOLOWER(c);
		if (c >= 'a' && c <= 'f')
			return c - 'a' + 10;
	}
	return -1;
}

static PyObject *
string_fromhex(PyObject *cls, PyObject *args)
{
	PyObject *newstring, *hexobj;
	char *buf;
	Py_UNICODE *hex;
	Py_ssize_t hexlen, byteslen, i, j;
	int top, bot;

	if (!PyArg_ParseTuple(args, "U:fromhex", &hexobj))
		return NULL;
	assert(PyUnicode_Check(hexobj));
	hexlen = PyUnicode_GET_SIZE(hexobj);
	hex = PyUnicode_AS_UNICODE(hexobj);
	byteslen = hexlen/2; /* This overestimates if there are spaces */
	newstring = PyString_FromStringAndSize(NULL, byteslen);
	if (!newstring)
		return NULL;
	buf = PyString_AS_STRING(newstring);
	for (i = j = 0; i < hexlen; i += 2) {
		/* skip over spaces in the input */
		while (hex[i] == ' ')
			i++;
		if (i >= hexlen)
			break;
		top = hex_digit_to_int(hex[i]);
		bot = hex_digit_to_int(hex[i+1]);
		if (top == -1 || bot == -1) {
			PyErr_Format(PyExc_ValueError,
				     "non-hexadecimal number found in "
				     "fromhex() arg at position %zd", i);
			goto error;
		}
		buf[j++] = (top << 4) + bot;
	}
	if (_PyString_Resize(&newstring, j) < 0)
		goto error;
	return newstring;

  error:
	Py_XDECREF(newstring);
	return NULL;
}


static PyObject *
string_getnewargs(PyStringObject *v)
{
	return Py_BuildValue("(s#)", v->ob_sval, Py_Size(v));
}


static PyMethodDef
string_methods[] = {
	{"__getnewargs__",	(PyCFunction)string_getnewargs,	METH_NOARGS},
	{"capitalize", (PyCFunction)stringlib_capitalize, METH_NOARGS,
	 _Py_capitalize__doc__},
	{"center", (PyCFunction)stringlib_center, METH_VARARGS, center__doc__},
	{"count", (PyCFunction)string_count, METH_VARARGS, count__doc__},
	{"decode", (PyCFunction)string_decode, METH_VARARGS, decode__doc__},
	{"endswith", (PyCFunction)string_endswith, METH_VARARGS,
         endswith__doc__},
	{"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
	 expandtabs__doc__},
	{"find", (PyCFunction)string_find, METH_VARARGS, find__doc__},
        {"fromhex", (PyCFunction)string_fromhex, METH_VARARGS|METH_CLASS,
         fromhex_doc},
	{"index", (PyCFunction)string_index, METH_VARARGS, index__doc__},
	{"isalnum", (PyCFunction)stringlib_isalnum, METH_NOARGS,
         _Py_isalnum__doc__},
	{"isalpha", (PyCFunction)stringlib_isalpha, METH_NOARGS,
         _Py_isalpha__doc__},
	{"isdigit", (PyCFunction)stringlib_isdigit, METH_NOARGS,
         _Py_isdigit__doc__},
	{"islower", (PyCFunction)stringlib_islower, METH_NOARGS,
         _Py_islower__doc__},
	{"isspace", (PyCFunction)stringlib_isspace, METH_NOARGS,
         _Py_isspace__doc__},
	{"istitle", (PyCFunction)stringlib_istitle, METH_NOARGS,
         _Py_istitle__doc__},
	{"isupper", (PyCFunction)stringlib_isupper, METH_NOARGS,
         _Py_isupper__doc__},
	{"join", (PyCFunction)string_join, METH_O, join__doc__},
	{"ljust", (PyCFunction)stringlib_ljust, METH_VARARGS, ljust__doc__},
	{"lower", (PyCFunction)stringlib_lower, METH_NOARGS, _Py_lower__doc__},
	{"lstrip", (PyCFunction)string_lstrip, METH_VARARGS, lstrip__doc__},
	{"partition", (PyCFunction)string_partition, METH_O, partition__doc__},
	{"replace", (PyCFunction)string_replace, METH_VARARGS, replace__doc__},
	{"rfind", (PyCFunction)string_rfind, METH_VARARGS, rfind__doc__},
	{"rindex", (PyCFunction)string_rindex, METH_VARARGS, rindex__doc__},
	{"rjust", (PyCFunction)stringlib_rjust, METH_VARARGS, rjust__doc__},
	{"rpartition", (PyCFunction)string_rpartition, METH_O,
	 rpartition__doc__},
	{"rsplit", (PyCFunction)string_rsplit, METH_VARARGS, rsplit__doc__},
	{"rstrip", (PyCFunction)string_rstrip, METH_VARARGS, rstrip__doc__},
	{"split", (PyCFunction)string_split, METH_VARARGS, split__doc__},
	{"splitlines", (PyCFunction)stringlib_splitlines, METH_VARARGS,
	 splitlines__doc__},
	{"startswith", (PyCFunction)string_startswith, METH_VARARGS,
         startswith__doc__},
	{"strip", (PyCFunction)string_strip, METH_VARARGS, strip__doc__},
	{"swapcase", (PyCFunction)stringlib_swapcase, METH_NOARGS,
	 _Py_swapcase__doc__},
	{"title", (PyCFunction)stringlib_title, METH_NOARGS, _Py_title__doc__},
	{"translate", (PyCFunction)string_translate, METH_VARARGS,
	 translate__doc__},
	{"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
	{"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
	{NULL,     NULL}		     /* sentinel */
};

static PyObject *
str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

static PyObject *
string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *x = NULL, *it;
	const char *encoding = NULL;
	const char *errors = NULL;
	PyObject *new = NULL;
	Py_ssize_t i, size;
	static char *kwlist[] = {"source", "encoding", "errors", 0};

	if (type != &PyString_Type)
		return str_subtype_new(type, args, kwds);
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x,
					 &encoding, &errors))
		return NULL;
	if (x == NULL) {
		if (encoding != NULL || errors != NULL) {
			PyErr_SetString(PyExc_TypeError,
					"encoding or errors without sequence "
					"argument");
			return NULL;
		}
		return PyString_FromString("");
	}

	if (PyUnicode_Check(x)) {
		/* Encode via the codec registry */
		if (encoding == NULL) {
			PyErr_SetString(PyExc_TypeError,
					"string argument without an encoding");
			return NULL;
		}
		new = PyCodec_Encode(x, encoding, errors);
		if (new == NULL)
			return NULL;
		assert(PyString_Check(new));
		return new;
	}

	/* If it's not unicode, there can't be encoding or errors */
	if (encoding != NULL || errors != NULL) {
		PyErr_SetString(PyExc_TypeError,
			"encoding or errors without a string argument");
		return NULL;
	}

	/* Is it an int? */
	size = PyNumber_AsSsize_t(x, PyExc_ValueError);
	if (size == -1 && PyErr_Occurred()) {
		PyErr_Clear();
	}
	else {
		if (size < 0) {
			PyErr_SetString(PyExc_ValueError, "negative count");
			return NULL;
		}
		new = PyString_FromStringAndSize(NULL, size);
		if (new == NULL) {
			return NULL;
		}
		if (size > 0) {
			memset(((PyStringObject*)new)->ob_sval, 0, size);
		}
		return new;
	}

	/* Use the modern buffer interface */
	if (PyObject_CheckBuffer(x)) {
		Py_buffer view;
		if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0)
			return NULL;
		new = PyString_FromStringAndSize(NULL, view.len);
		if (!new)
			goto fail;
		// XXX(brett.cannon): Better way to get to internal buffer?
		if (PyBuffer_ToContiguous(((PyStringObject *)new)->ob_sval,
					  &view, view.len, 'C') < 0)
			goto fail;
		PyObject_ReleaseBuffer(x, &view);
		return new;
	  fail:
		Py_XDECREF(new);
		PyObject_ReleaseBuffer(x, &view);
		return NULL;
	}

	/* For iterator version, create a string object and resize as needed */
	/* XXX(gb): is 64 a good value? also, optimize if length is known */
	/* XXX(guido): perhaps use Pysequence_Fast() -- I can't imagine the
	   input being a truly long iterator. */
	size = 64;
	new = PyString_FromStringAndSize(NULL, size);
	if (new == NULL)
		return NULL;

	/* XXX Optimize this if the arguments is a list, tuple */

	/* Get the iterator */
	it = PyObject_GetIter(x);
	if (it == NULL)
		goto error;

	/* Run the iterator to exhaustion */
	for (i = 0; ; i++) {
		PyObject *item;
		Py_ssize_t value;

		/* Get the next item */
		item = PyIter_Next(it);
		if (item == NULL) {
			if (PyErr_Occurred())
				goto error;
			break;
		}

		/* Interpret it as an int (__index__) */
		value = PyNumber_AsSsize_t(item, PyExc_ValueError);
		Py_DECREF(item);
		if (value == -1 && PyErr_Occurred())
			goto error;

		/* Range check */
		if (value < 0 || value >= 256) {
			PyErr_SetString(PyExc_ValueError,
					"bytes must be in range(0, 256)");
			goto error;
		}

		/* Append the byte */
		if (i >= size) {
			size *= 2;
			if (_PyString_Resize(&new, size) < 0)
				goto error;
		}
		((PyStringObject *)new)->ob_sval[i] = value;
	}
	_PyString_Resize(&new, i);

	/* Clean up and return success */
	Py_DECREF(it);
	return new;

  error:
	/* Error handling when new != NULL */
	Py_XDECREF(it);
	Py_DECREF(new);
	return NULL;
}

static PyObject *
str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *tmp, *pnew;
	Py_ssize_t n;

	assert(PyType_IsSubtype(type, &PyString_Type));
	tmp = string_new(&PyString_Type, args, kwds);
	if (tmp == NULL)
		return NULL;
	assert(PyString_CheckExact(tmp));
	n = PyString_GET_SIZE(tmp);
	pnew = type->tp_alloc(type, n);
	if (pnew != NULL) {
		Py_MEMCPY(PyString_AS_STRING(pnew),
			  PyString_AS_STRING(tmp), n+1);
		((PyStringObject *)pnew)->ob_shash =
			((PyStringObject *)tmp)->ob_shash;
	}
	Py_DECREF(tmp);
	return pnew;
}

PyDoc_STRVAR(string_doc,
"bytes(iterable_of_ints) -> bytes.\n\
bytes(string, encoding[, errors]) -> bytes\n\
bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer.\n\
bytes(memory_view) -> bytes.\n\
\n\
Construct an immutable array of bytes from:\n\
  - an iterable yielding integers in range(256)\n\
  - a text string encoded using the specified encoding\n\
  - a bytes or a buffer object\n\
  - any object implementing the buffer API.");

static PyObject *str_iter(PyObject *seq);

PyTypeObject PyString_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"bytes",
	sizeof(PyStringObject),
	sizeof(char),
 	string_dealloc, 			/* tp_dealloc */
	0,			 		/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	(reprfunc)string_repr, 			/* tp_repr */
	0,					/* tp_as_number */
	&string_as_sequence,			/* tp_as_sequence */
	&string_as_mapping,			/* tp_as_mapping */
	(hashfunc)string_hash, 			/* tp_hash */
	0,					/* tp_call */
	string_str,				/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	&string_as_buffer,			/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
		Py_TPFLAGS_STRING_SUBCLASS,	/* tp_flags */
	string_doc,				/* tp_doc */
	0,					/* tp_traverse */
	0,					/* tp_clear */
	(richcmpfunc)string_richcompare,	/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	str_iter,				/* tp_iter */
	0,					/* tp_iternext */
	string_methods,				/* tp_methods */
	0,					/* tp_members */
	0,					/* tp_getset */
	&PyBaseObject_Type,			/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	0,					/* tp_init */
	0,					/* tp_alloc */
	string_new,				/* tp_new */
	PyObject_Del,	                	/* tp_free */
};

void
PyString_Concat(register PyObject **pv, register PyObject *w)
{
	register PyObject *v;
	assert(pv != NULL);
	if (*pv == NULL)
		return;
	if (w == NULL) {
		Py_DECREF(*pv);
		*pv = NULL;
		return;
	}
	v = string_concat(*pv, w);
	Py_DECREF(*pv);
	*pv = v;
}

void
PyString_ConcatAndDel(register PyObject **pv, register PyObject *w)
{
	PyString_Concat(pv, w);
	Py_XDECREF(w);
}


/* The following function breaks the notion that strings are immutable:
   it changes the size of a string.  We get away with this only if there
   is only one module referencing the object.  You can also think of it
   as creating a new string object and destroying the old one, only
   more efficiently.  In any case, don't use this if the string may
   already be known to some other part of the code...
   Note that if there's not enough memory to resize the string, the original
   string object at *pv is deallocated, *pv is set to NULL, an "out of
   memory" exception is set, and -1 is returned.  Else (on success) 0 is
   returned, and the value in *pv may or may not be the same as on input.
   As always, an extra byte is allocated for a trailing \0 byte (newsize
   does *not* include that), and a trailing \0 byte is stored.
*/

int
_PyString_Resize(PyObject **pv, Py_ssize_t newsize)
{
	register PyObject *v;
	register PyStringObject *sv;
	v = *pv;
	if (!PyString_Check(v) || Py_Refcnt(v) != 1 || newsize < 0) {
		*pv = 0;
		Py_DECREF(v);
		PyErr_BadInternalCall();
		return -1;
	}
	/* XXX UNREF/NEWREF interface should be more symmetrical */
	_Py_DEC_REFTOTAL;
	_Py_ForgetReference(v);
	*pv = (PyObject *)
		PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize);
	if (*pv == NULL) {
		PyObject_Del(v);
		PyErr_NoMemory();
		return -1;
	}
	_Py_NewReference(*pv);
	sv = (PyStringObject *) *pv;
	Py_Size(sv) = newsize;
	sv->ob_sval[newsize] = '\0';
	sv->ob_shash = -1;	/* invalidate cached hash value */
	return 0;
}

/* _PyString_FormatLong emulates the format codes d, u, o, x and X, and
 * the F_ALT flag, for Python's long (unbounded) ints.  It's not used for
 * Python's regular ints.
 * Return value:  a new PyString*, or NULL if error.
 *  .  *pbuf is set to point into it,
 *     *plen set to the # of chars following that.
 *     Caller must decref it when done using pbuf.
 *     The string starting at *pbuf is of the form
 *         "-"? ("0x" | "0X")? digit+
 *     "0x"/"0X" are present only for x and X conversions, with F_ALT
 *         set in flags.  The case of hex digits will be correct,
 *     There will be at least prec digits, zero-filled on the left if
 *         necessary to get that many.
 * val		object to be converted
 * flags	bitmask of format flags; only F_ALT is looked at
 * prec		minimum number of digits; 0-fill on left if needed
 * type		a character in [duoxX]; u acts the same as d
 *
 * CAUTION:  o, x and X conversions on regular ints can never
 * produce a '-' sign, but can for Python's unbounded ints.
 */
PyObject*
_PyString_FormatLong(PyObject *val, int flags, int prec, int type,
		     char **pbuf, int *plen)
{
	PyObject *result = NULL;
	char *buf;
	Py_ssize_t i;
	int sign;	/* 1 if '-', else 0 */
	int len;	/* number of characters */
	Py_ssize_t llen;
	int numdigits;	/* len == numnondigits + numdigits */
	int numnondigits = 0;

	/* Avoid exceeding SSIZE_T_MAX */
	if (prec > PY_SSIZE_T_MAX-3) {
		PyErr_SetString(PyExc_OverflowError,
				"precision too large");
		return NULL;
	}

	switch (type) {
	case 'd':
	case 'u':
		/* Special-case boolean: we want 0/1 */
		if (PyBool_Check(val))
			result = PyNumber_ToBase(val, 10);
		else
			result = Py_Type(val)->tp_str(val);
		break;
	case 'o':
		numnondigits = 2;
		result = PyNumber_ToBase(val, 8);
		break;
	case 'x':
	case 'X':
		numnondigits = 2;
		result = PyNumber_ToBase(val, 16);
		break;
	default:
		assert(!"'type' not in [duoxX]");
	}
	if (!result)
		return NULL;

	buf = PyUnicode_AsString(result);
	if (!buf) {
		Py_DECREF(result);
		return NULL;
	}

	/* To modify the string in-place, there can only be one reference. */
	if (Py_Refcnt(result) != 1) {
		PyErr_BadInternalCall();
		return NULL;
	}
	llen = PyUnicode_GetSize(result);
	if (llen > INT_MAX) {
		PyErr_SetString(PyExc_ValueError,
				"string too large in _PyString_FormatLong");
		return NULL;
	}
	len = (int)llen;
	if (buf[len-1] == 'L') {
		--len;
		buf[len] = '\0';
	}
	sign = buf[0] == '-';
	numnondigits += sign;
	numdigits = len - numnondigits;
	assert(numdigits > 0);

	/* Get rid of base marker unless F_ALT */
	if (((flags & F_ALT) == 0 &&
	    (type == 'o' || type == 'x' || type == 'X'))) {
		assert(buf[sign] == '0');
		assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' ||
		       buf[sign+1] == 'o');
		numnondigits -= 2;
		buf += 2;
		len -= 2;
		if (sign)
			buf[0] = '-';
		assert(len == numnondigits + numdigits);
		assert(numdigits > 0);
	}

	/* Fill with leading zeroes to meet minimum width. */
	if (prec > numdigits) {
		PyObject *r1 = PyString_FromStringAndSize(NULL,
					numnondigits + prec);
		char *b1;
		if (!r1) {
			Py_DECREF(result);
			return NULL;
		}
		b1 = PyString_AS_STRING(r1);
		for (i = 0; i < numnondigits; ++i)
			*b1++ = *buf++;
		for (i = 0; i < prec - numdigits; i++)
			*b1++ = '0';
		for (i = 0; i < numdigits; i++)
			*b1++ = *buf++;
		*b1 = '\0';
		Py_DECREF(result);
		result = r1;
		buf = PyString_AS_STRING(result);
		len = numnondigits + prec;
	}

	/* Fix up case for hex conversions. */
	if (type == 'X') {
		/* Need to convert all lower case letters to upper case.
		   and need to convert 0x to 0X (and -0x to -0X). */
		for (i = 0; i < len; i++)
			if (buf[i] >= 'a' && buf[i] <= 'x')
				buf[i] -= 'a'-'A';
	}
	*pbuf = buf;
	*plen = len;
	return result;
}

void
PyString_Fini(void)
{
	int i;
	for (i = 0; i < UCHAR_MAX + 1; i++) {
		Py_XDECREF(characters[i]);
		characters[i] = NULL;
	}
	Py_XDECREF(nullstring);
	nullstring = NULL;
}

/*********************** Str Iterator ****************************/

typedef struct {
	PyObject_HEAD
	Py_ssize_t it_index;
	PyStringObject *it_seq; /* Set to NULL when iterator is exhausted */
} striterobject;

static void
striter_dealloc(striterobject *it)
{
	_PyObject_GC_UNTRACK(it);
	Py_XDECREF(it->it_seq);
	PyObject_GC_Del(it);
}

static int
striter_traverse(striterobject *it, visitproc visit, void *arg)
{
	Py_VISIT(it->it_seq);
	return 0;
}

static PyObject *
striter_next(striterobject *it)
{
	PyStringObject *seq;
	PyObject *item;

	assert(it != NULL);
	seq = it->it_seq;
	if (seq == NULL)
		return NULL;
	assert(PyString_Check(seq));

	if (it->it_index < PyString_GET_SIZE(seq)) {
		item = PyInt_FromLong(
			(unsigned char)seq->ob_sval[it->it_index]);
		if (item != NULL)
			++it->it_index;
		return item;
	}

	Py_DECREF(seq);
	it->it_seq = NULL;
	return NULL;
}

static PyObject *
striter_len(striterobject *it)
{
	Py_ssize_t len = 0;
	if (it->it_seq)
		len = PyString_GET_SIZE(it->it_seq) - it->it_index;
	return PyInt_FromSsize_t(len);
}

PyDoc_STRVAR(length_hint_doc,
	     "Private method returning an estimate of len(list(it)).");

static PyMethodDef striter_methods[] = {
	{"__length_hint__", (PyCFunction)striter_len, METH_NOARGS,
	 length_hint_doc},
 	{NULL,		NULL}		/* sentinel */
};

PyTypeObject PyStringIter_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"bytes_iterator",			/* tp_name */
	sizeof(striterobject),			/* tp_basicsize */
	0,					/* tp_itemsize */
	/* methods */
	(destructor)striter_dealloc,		/* tp_dealloc */
	0,					/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,					/* tp_compare */
	0,					/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
	0,					/* tp_doc */
	(traverseproc)striter_traverse,	/* tp_traverse */
	0,					/* tp_clear */
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	PyObject_SelfIter,			/* tp_iter */
	(iternextfunc)striter_next,		/* tp_iternext */
	striter_methods,			/* tp_methods */
	0,
};

static PyObject *
str_iter(PyObject *seq)
{
	striterobject *it;

	if (!PyString_Check(seq)) {
		PyErr_BadInternalCall();
		return NULL;
	}
	it = PyObject_GC_New(striterobject, &PyStringIter_Type);
	if (it == NULL)
		return NULL;
	it->it_index = 0;
	Py_INCREF(seq);
	it->it_seq = (PyStringObject *)seq;
	_PyObject_GC_TRACK(it);
	return (PyObject *)it;
}
