]> granicus.if.org Git - python/commitdiff
Add a new PyUnicode_Fill() function
authorVictor Stinner <victor.stinner@haypocalc.com>
Tue, 3 Jan 2012 23:33:50 +0000 (00:33 +0100)
committerVictor Stinner <victor.stinner@haypocalc.com>
Tue, 3 Jan 2012 23:33:50 +0000 (00:33 +0100)
It is faster than the unicode_fill() function which was implemented in
formatter_unicode.c.

Doc/c-api/unicode.rst
Include/unicodeobject.h
Objects/unicodeobject.c
Python/formatter_unicode.c

index 43e3d2fef23b271a6b459f9cb38066a2ebfd42ba..3a8b38b636a89ae4e1e7d38136eddef9276863df 100644 (file)
@@ -564,6 +564,21 @@ APIs:
    .. versionadded:: 3.3
 
 
+.. c:function:: int PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, \
+                        Py_ssize_t length, Py_UCS4 fill_char)
+
+   Fill a string with a character: write *fill_char* into
+   ``unicode[start:start+length]``.
+
+   Fail if *fill_char* is bigger than the string maximum character, or if the
+   string has more than 1 reference.
+
+   Return the number of written character, or return ``-1`` and raise an
+   exception on error.
+
+   .. versionadded:: 3.3
+
+
 .. c:function:: int PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, \
                                         Py_UCS4 character)
 
index dfd594e01509200999f7fc9bd9624192a0717e83..6255dc325d95c98730b739c622cdb42a1b9692fa 100644 (file)
@@ -623,11 +623,11 @@ PyAPI_FUNC(PyObject*) _PyUnicode_Copy(
 #endif
 
 /* Copy character from one unicode object into another, this function performs
-   character conversion when necessary and falls back to memcpy if possible.
+   character conversion when necessary and falls back to memcpy() if possible.
 
-   Fail if to is too small (smaller than how_many or smaller than
+   Fail if to is too small (smaller than *how_many* or smaller than
    len(from)-from_start), or if kind(from[from_start:from_start+how_many]) >
-   kind(to), or if to has more than 1 reference.
+   kind(to), or if *to* has more than 1 reference.
 
    Return the number of written character, or return -1 and raise an exception
    on error.
@@ -650,6 +650,23 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_CopyCharacters(
     );
 #endif
 
+/* Fill a string with a character: write fill_char into
+   unicode[start:start+length].
+
+   Fail if fill_char is bigger than the string maximum character, or if the
+   string has more than 1 reference.
+
+   Return the number of written character, or return -1 and raise an exception
+   on error. */
+#ifndef Py_LIMITED_API
+PyAPI_FUNC(Py_ssize_t) PyUnicode_Fill(
+    PyObject *unicode,
+    Py_ssize_t start,
+    Py_ssize_t length,
+    Py_UCS4 fill_char
+    );
+#endif
+
 /* Create a Unicode Object from the Py_UNICODE buffer u of the given
    size.
 
index 9a9703a4458d67c40c42cc7452707055d69b3c3f..5ca2c533e527ed79021809790dccbd6c2ba4b0c2 100644 (file)
@@ -9818,6 +9818,41 @@ PyUnicode_Join(PyObject *separator, PyObject *seq)
         } \
     } while (0)
 
+Py_ssize_t
+PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length,
+               Py_UCS4 fill_char)
+{
+    Py_ssize_t maxlen;
+    enum PyUnicode_Kind kind;
+    void *data;
+
+    if (!PyUnicode_Check(unicode)) {
+        PyErr_BadInternalCall();
+        return -1;
+    }
+    if (PyUnicode_READY(unicode) == -1)
+        return -1;
+    if (unicode_check_modifiable(unicode))
+        return -1;
+
+    if (fill_char > PyUnicode_MAX_CHAR_VALUE(unicode)) {
+        PyErr_SetString(PyExc_ValueError,
+                         "fill character is bigger than "
+                         "the string maximum character");
+        return -1;
+    }
+
+    maxlen = PyUnicode_GET_LENGTH(unicode) - start;
+    length = Py_MIN(maxlen, length);
+    if (length <= 0)
+        return 0;
+
+    kind = PyUnicode_KIND(unicode);
+    data = PyUnicode_DATA(unicode);
+    FILL(kind, data, fill_char, start, length);
+    return length;
+}
+
 static PyObject *
 pad(PyObject *self,
     Py_ssize_t left,
index 6deb3cd7fe85f239319539ad4783e6622f649df2..ef0151192b76925476917b8f5b6812f9b914d42e 100644 (file)
@@ -317,15 +317,6 @@ calc_padding(Py_ssize_t nchars, Py_ssize_t width, Py_UCS4 align,
     *n_rpadding = *n_total - nchars - *n_lpadding;
 }
 
-static void
-unicode_fill(PyObject *str, Py_ssize_t start, Py_ssize_t end, Py_UCS4 ch)
-{
-    int kind = PyUnicode_KIND(str);
-    void *data = PyUnicode_DATA(str);
-    while (start < end)
-        PyUnicode_WRITE(kind, data, start++, ch);
-}
-
 /* Do the padding, and return a pointer to where the caller-supplied
    content goes. */
 static Py_ssize_t
@@ -335,12 +326,12 @@ fill_padding(PyObject *s, Py_ssize_t start, Py_ssize_t nchars,
 {
     /* Pad on left. */
     if (n_lpadding)
-        unicode_fill(s, start, start + n_lpadding, fill_char);
+        PyUnicode_Fill(s, start, start + n_lpadding, fill_char);
 
     /* Pad on right. */
     if (n_rpadding)
-        unicode_fill(s, start + nchars + n_lpadding,
-                     start + nchars + n_lpadding + n_rpadding, fill_char);
+        PyUnicode_Fill(s, start + nchars + n_lpadding,
+                       start + nchars + n_lpadding + n_rpadding, fill_char);
 
     /* Pointer to the user content. */
     return start + n_lpadding;
@@ -557,7 +548,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
 #endif
 
     if (spec->n_lpadding) {
-        unicode_fill(out, pos, pos + spec->n_lpadding, fill_char);
+        PyUnicode_Fill(out, pos, pos + spec->n_lpadding, fill_char);
         pos += spec->n_lpadding;
     }
     if (spec->n_sign == 1) {
@@ -581,7 +572,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
         pos += spec->n_prefix;
     }
     if (spec->n_spadding) {
-        unicode_fill(out, pos, pos + spec->n_spadding, fill_char);
+        PyUnicode_Fill(out, pos, pos + spec->n_spadding, fill_char);
         pos += spec->n_spadding;
     }
 
@@ -640,7 +631,7 @@ fill_number(PyObject *out, Py_ssize_t pos, const NumberFieldWidths *spec,
     }
 
     if (spec->n_rpadding) {
-        unicode_fill(out, pos, pos + spec->n_rpadding, fill_char);
+        PyUnicode_Fill(out, pos, pos + spec->n_rpadding, fill_char);
         pos += spec->n_rpadding;
     }
     return 0;