Created
December 1, 2016 10:30
-
-
Save odedlaz/a71a34fd3cd6dadcb38bd01045c87008 to your computer and use it in GitHub Desktop.
_PyBytes_Resize
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* The following function breaks the notion that bytes are immutable: | |
it changes the size of a bytes object. 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 bytes object and destroying the old one, only | |
more efficiently. In any case, don't use this if the bytes object may | |
already be known to some other part of the code... | |
Note that if there's not enough memory to resize the bytes object, the | |
original bytes 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 | |
_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) | |
{ | |
PyObject *v; | |
PyBytesObject *sv; | |
v = *pv; | |
if (!PyBytes_Check(v) || newsize < 0) { | |
goto error; | |
} | |
if (Py_SIZE(v) == newsize) { | |
/* return early if newsize equals to v->ob_size */ | |
return 0; | |
} | |
if (Py_REFCNT(v) != 1) { | |
goto error; | |
} | |
/* XXX UNREF/NEWREF interface should be more symmetrical */ | |
_Py_DEC_REFTOTAL; | |
_Py_ForgetReference(v); | |
*pv = (PyObject *) | |
PyObject_REALLOC(v, PyBytesObject_SIZE + newsize); | |
if (*pv == NULL) { | |
PyObject_Del(v); | |
PyErr_NoMemory(); | |
return -1; | |
} | |
_Py_NewReference(*pv); | |
sv = (PyBytesObject *) *pv; | |
Py_SIZE(sv) = newsize; | |
sv->ob_sval[newsize] = '\0'; | |
sv->ob_shash = -1; /* invalidate cached hash value */ | |
return 0; | |
error: | |
*pv = 0; | |
Py_DECREF(v); | |
PyErr_BadInternalCall(); | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment