static PyObject * PyZlib_objcompress(compobject *self, PyObject *args) { int err, inplen; Py_ssize_t length = DEFAULTALLOC; PyObject *RetVal; Byte *input; unsigned long start_total_out; if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen)) return NULL; if (!(RetVal = PyString_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB start_total_out = self->zst.total_out; self->zst.avail_in = inplen; self->zst.next_in = input; self->zst.avail_out = length; self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), Z_NO_FLUSH); Py_END_ALLOW_THREADS /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { if (_PyString_Resize(&RetVal, length << 1) < 0) goto error; self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \ + length; self->zst.avail_out = length; length = length << 1; Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), Z_NO_FLUSH); Py_END_ALLOW_THREADS } /* We will only get Z_BUF_ERROR if the output buffer was full but there wasn't more output when we tried again, so it is not an error condition. */ if (err != Z_OK && err != Z_BUF_ERROR) { zlib_error(self->zst, err, "while compressing"); Py_DECREF(RetVal); RetVal = NULL; goto error; } _PyString_Resize(&RetVal, self->zst.total_out - start_total_out); error: LEAVE_ZLIB return RetVal; }
static PyObject * PyZlib_unflush(compobject *self, PyObject *args) { int err, length = DEFAULTALLOC; PyObject * retval = NULL; unsigned long start_total_out; if (!PyArg_ParseTuple(args, "|i:flush", &length)) return NULL; if (!(retval = PyString_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB start_total_out = self->zst.total_out; self->zst.avail_out = length; self->zst.next_out = (Byte *)PyString_AS_STRING(retval); Py_BEGIN_ALLOW_THREADS err = inflate(&(self->zst), Z_FINISH); Py_END_ALLOW_THREADS /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while ((err == Z_OK || err == Z_BUF_ERROR) && self->zst.avail_out == 0) { if (_PyString_Resize(&retval, length << 1) < 0) goto error; self->zst.next_out = (Byte *)PyString_AS_STRING(retval) + length; self->zst.avail_out = length; length = length << 1; Py_BEGIN_ALLOW_THREADS err = inflate(&(self->zst), Z_FINISH); Py_END_ALLOW_THREADS } /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free various data structures. Note we should only get Z_STREAM_END when flushmode is Z_FINISH */ if (err == Z_STREAM_END) { err = inflateEnd(&(self->zst)); self->is_initialised = 0; if (err != Z_OK) { zlib_error(self->zst, err, "from inflateEnd()"); Py_DECREF(retval); retval = NULL; goto error; } } _PyString_Resize(&retval, self->zst.total_out - start_total_out); error: LEAVE_ZLIB return retval; }
static PyObject * PyZlib_objcompress(compobject *self, PyObject *args) { int err = Z_OK, inplen; int length = DEFAULTALLOC; PyObject *RetVal; Byte *input; unsigned long start_total_out; if (!PyArg_ParseTuple(args, "s#:compress", &input, &inplen)) return NULL; self->zst.avail_in = inplen; self->zst.next_in = input; if (!(RetVal = PyString_FromStringAndSize(NULL, length))) { PyErr_SetString(PyExc_MemoryError, "Can't allocate memory to compress data"); return NULL; } start_total_out = self->zst.total_out; self->zst.next_out = (unsigned char *)PyString_AsString(RetVal); self->zst.avail_out = length; while (self->zst.avail_in != 0 && err == Z_OK) { err = deflate(&(self->zst), Z_NO_FLUSH); if (self->zst.avail_out <= 0) { if (_PyString_Resize(&RetVal, length << 1) == -1) { PyErr_SetString(PyExc_MemoryError, "Can't allocate memory to compress data"); return NULL; } self->zst.next_out = (unsigned char *)PyString_AsString(RetVal) + length; self->zst.avail_out = length; length = length << 1; } } if (err != Z_OK) { if (self->zst.msg == Z_NULL) PyErr_Format(ZlibError, "Error %i while compressing", err); else PyErr_Format(ZlibError, "Error %i while compressing: %.200s", err, self->zst.msg); Py_DECREF(RetVal); return NULL; } _PyString_Resize(&RetVal, self->zst.total_out - start_total_out); return RetVal; }
static PyObject * fsimage_file_read(fsimage_file_t *file, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "size", "offset", NULL }; int bufsize; int size = 0; uint64_t offset = 0; ssize_t bytesread = 0; PyObject * buffer; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iL", kwlist, &size, &offset)) return (NULL); bufsize = size ? size : 4096; if ((buffer = PyString_FromStringAndSize(NULL, bufsize)) == NULL) return (NULL); while (1) { int err; void *buf = PyString_AS_STRING(buffer) + bytesread; err = fsi_pread_file(file->file, buf, bufsize, bytesread + offset); if (err == -1) { Py_DECREF(buffer); PyErr_SetFromErrno(PyExc_IOError); return (NULL); } else if (err == 0) { break; } bytesread += err; if (size != 0) { bufsize -= bytesread; if (bufsize == 0) break; } else { if (_PyString_Resize(&buffer, bytesread + bufsize) < 0) return (NULL); } } _PyString_Resize(&buffer, bytesread); return (buffer); }
static PyObject * CD_readda(cdplayerobject *self, PyObject *args) { int numframes, n; PyObject *result; if (!PyArg_ParseTuple(args, "i:readda", &numframes)) return NULL; result = PyString_FromStringAndSize(NULL, numframes * sizeof(CDFRAME)); if (result == NULL) return NULL; n = CDreadda(self->ob_cdplayer, (CDFRAME *) PyString_AsString(result), numframes); if (n == -1) { Py_DECREF(result); PyErr_SetFromErrno(CdError); return NULL; } if (n < numframes) _PyString_Resize(&result, n * sizeof(CDFRAME)); return result; }
/** Convert a Python decimal.Decimal to MySQL DECIMAL. Convert a Python decimal.Decimal to MySQL DECIMAL. This function also removes the 'L' suffix from the resulting string when using Python v2. @param obj PyObject to be converted @return Converted decimal as string @retval PyBytes Python v3 @retval PyString Python v2 */ PyObject* pytomy_decimal(PyObject *obj) { #ifdef PY3 return PyBytes_FromString((const char *)PyUnicode_1BYTE_DATA( PyObject_Str(obj))); #else PyObject *numeric, *new_num; int tmp_size; char *tmp; numeric= PyObject_Str(obj); tmp= PyString_AsString(numeric); tmp_size= (int)PyString_Size(numeric); if (tmp[tmp_size - 1] == 'L') { new_num= PyString_FromStringAndSize(tmp, tmp_size); _PyString_Resize(&new_num, tmp_size - 1); return new_num; } else { return numeric; } #endif }
static PyObject * rf_read(rfobject *self, PyObject *args) { long n; PyObject *v; OSErr err; ByteCount n2; if (self->isclosed) { PyErr_SetString(PyExc_ValueError, "Operation on closed file"); return NULL; } if (!PyArg_ParseTuple(args, "l", &n)) return NULL; v = PyBytes_FromStringAndSize((char *)NULL, n); if (v == NULL) return NULL; err = FSReadFork(self->fRefNum, fsAtMark, 0, n, PyString_AsString(v), &n2); if (err && err != eofErr) { PyMac_Error(err); Py_DECREF(v); return NULL; } _PyString_Resize(&v, n2); return v; }
static PyObject * oss_read(oss_audio_t *self, PyObject *args) { int size, count; char *cp; PyObject *rv; if (!PyArg_ParseTuple(args, "i:read", &size)) return NULL; rv = PyString_FromStringAndSize(NULL, size); if (rv == NULL) return NULL; cp = PyString_AS_STRING(rv); Py_BEGIN_ALLOW_THREADS count = read(self->fd, cp, size); Py_END_ALLOW_THREADS if (count < 0) { PyErr_SetFromErrno(PyExc_IOError); Py_DECREF(rv); return NULL; } self->icount += count; _PyString_Resize(&rv, count); return rv; }
static PyObject* cfstring_to_pystring(CFStringRef ref) { const char* s; s = CFStringGetCStringPtr(ref, kCFStringEncodingUTF8); if (s) { return PyString_FromString(s); } else { CFIndex len = CFStringGetLength(ref); Boolean ok; PyObject* result; result = PyString_FromStringAndSize(NULL, len*4); ok = CFStringGetCString(ref, PyString_AS_STRING(result), PyString_GET_SIZE(result), kCFStringEncodingUTF8); if (!ok) { Py_DECREF(result); return NULL; } else { _PyString_Resize(&result, strlen(PyString_AS_STRING(result))); } return result; } }
/* * This function is an almost verbatim copy of PyString_Repr() from * Python's stringobject.c with the following differences: * * - it always quotes the output using double quotes. * - it also quotes \b and \f * - it replaces any non ASCII character hh with \u00hh instead of \xhh */ static PyObject* encode_string(PyObject *string) { register PyStringObject* op = (PyStringObject*) string; size_t newsize = 2 + 6 * op->ob_size; PyObject *v; if (op->ob_size > (PY_SSIZE_T_MAX-2)/6) { PyErr_SetString(PyExc_OverflowError, "string is too large to make repr"); return NULL; } v = PyString_FromStringAndSize((char *)NULL, newsize); if (v == NULL) { return NULL; } else { register Py_ssize_t i; register char c; register char *p; int quote; quote = '"'; p = PyString_AS_STRING(v); *p++ = quote; for (i = 0; i < op->ob_size; i++) { /* There's at least enough room for a hex escape and a closing quote. */ assert(newsize - (p - PyString_AS_STRING(v)) >= 7); 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 == '\f') *p++ = '\\', *p++ = 'f'; else if (c == '\b') *p++ = '\\', *p++ = 'b'; else if (c < ' ' || c >= 0x7f) { /* For performance, we don't want to call * PyOS_snprintf here (extra layers of * function call). */ sprintf(p, "\\u%04x", c & 0xff); p += 6; } else *p++ = c; } assert(newsize - (p - PyString_AS_STRING(v)) >= 1); *p++ = quote; *p = '\0'; _PyString_Resize(&v, (int) (p - PyString_AS_STRING(v))); return v; } }
static PyObject *iosource_read_random(iosource *self, PyObject *args) { uint32_t len; uint64_t offs; PyObject *result; int length; if(!PyArg_ParseTuple(args, "lL", &len, &offs)) return NULL; // Allocate some space for the request: result=PyString_FromStringAndSize(NULL, len); if(!result) return NULL; TRY { length=self->driver->read_random(self->driver, PyString_AsString(result), len, offs); } EXCEPT(E_ANY) { Py_DECREF(result); return PyErr_Format(PyExc_IOError, "%s",except_str); }; // If we returned less data than was requested - we need to resize // the string back if(length < len) if(_PyString_Resize(&result,length)<0) return NULL; return result; };
// @pymethod string|PyILockBytes|ReadAt|Reads a specified number of bytes starting at a specified offset from the beginning of the byte array object. PyObject *PyILockBytes::ReadAt(PyObject *self, PyObject *args) { ILockBytes *pILB = GetI(self); if ( pILB == NULL ) return NULL; // @pyparm <o ULARGE_INTEGER>|ulOffset||Offset to start reading // @pyparm int|cb||Number of bytes to read ULONG cb; ULARGE_INTEGER ulOffset; if ( !PyArg_ParseTuple(args, "Kk:ReadAt", &ulOffset.QuadPart, &cb) ) return NULL; PyObject *pyretval=PyString_FromStringAndSize(NULL, cb); if (pyretval==NULL) return NULL; ULONG cbRead; PY_INTERFACE_PRECALL; HRESULT hr = pILB->ReadAt( ulOffset, PyString_AS_STRING(pyretval), cb, &cbRead ); PY_INTERFACE_POSTCALL; if ( FAILED(hr) ){ Py_DECREF(pyretval); return PyCom_BuildPyException(hr, pILB, IID_ILockBytes); } // @comm The result is a binary buffer returned in a string. _PyString_Resize(&pyretval, cbRead); return pyretval; }
static PyObject* _encode(ImagingEncoderObject* encoder, PyObject* args) { PyObject* buf; PyObject* result; int status; /* Encode to a Python string (allocated by this method) */ int bufsize = 16384; if (!PyArg_ParseTuple(args, "|i", &bufsize)) return NULL; buf = PyString_FromStringAndSize(NULL, bufsize); if (!buf) return NULL; status = encoder->encode(encoder->im, &encoder->state, (UINT8*) PyString_AsString(buf), bufsize); /* adjust string length to avoid slicing in encoder */ if (_PyString_Resize(&buf, (status > 0) ? status : 0) < 0) return NULL; result = Py_BuildValue("iiO", status, encoder->state.errcode, buf); Py_DECREF(buf); /* must release buffer!!! */ return result; }
PyObject* DetachValue() { // At this point, Trim should have been called by PostRead. if (bytesUsed == SQL_NULL_DATA || buffer == 0) Py_RETURN_NONE; if (usingStack) { if (dataType == SQL_C_CHAR || dataType == SQL_C_BINARY) return PyString_FromStringAndSize(buffer, bytesUsed); if (sizeof(wchar_t) == Py_UNICODE_SIZE) return PyUnicode_FromUnicode((const Py_UNICODE*)buffer, bytesUsed / element_size); return PyUnicode_FromWideChar((const wchar_t*)buffer, bytesUsed / element_size); } if (PyString_CheckExact(bufferOwner)) { if (_PyString_Resize(&bufferOwner, bytesUsed) == -1) return 0; PyObject* tmp = bufferOwner; bufferOwner = 0; buffer = 0; return tmp; } if (PyUnicode_CheckExact(bufferOwner)) { if (PyUnicode_Resize(&bufferOwner, bytesUsed / element_size) == -1) return 0; PyObject* tmp = bufferOwner; bufferOwner = 0; buffer = 0; return tmp; } // We have allocated our own wchar_t buffer and must now copy it to a Unicode object. PyObject* result = PyUnicode_FromWideChar((const wchar_t*)buffer, bytesUsed / element_size); if (result == 0) return false; free(buffer); buffer = 0; return result; }
static void w_more(int c, WFILE *p) { int size, newsize; if (p->str == NULL) return; /* An error already occurred */ size = PyString_Size(p->str); newsize = size + 1024; if (_PyString_Resize(&p->str, newsize) != 0) { p->ptr = p->end = NULL; } else { p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size; p->end = PyString_AS_STRING((PyStringObject *)p->str) + newsize; *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char); } }
static PyObject *PyView_access(PyView *o, PyObject *_args) { try { PWOSequence args(_args); if (!PyProperty_Check((PyObject *)args[0])) Fail(PyExc_TypeError, "First arg must be a property"); c4_BytesProp& prop = *(c4_BytesProp*)(c4_Property*)(PyProperty*)(PyObject*)args[0]; int index = PyInt_AsLong(args[1]); if (index < 0 || index >= o->GetSize()) Fail(PyExc_IndexError, "Index out of range"); c4_RowRef row = o->GetAt(index); long offset = PyInt_AsLong(args[2]); int length = args.len() == 3 ? 0 : PyInt_AsLong(args[3]); if (length <= 0) { length = prop(row).GetSize() - offset; if (length < 0) length = 0; } PyObject* buffer = PyString_FromStringAndSize(0, length); int o = 0; while (o < length) { c4_Bytes buf = prop(row).Access(offset + o, length - o); int n = buf.Size(); if (n == 0) break; memcpy(PyString_AS_STRING(buffer) + o, buf.Contents(), n); o += n; } if (o < length) _PyString_Resize(&buffer, o); return buffer; } catch (...) { return 0; } }
static PyObject *py_read_random(PyObject *dummy, PyObject *args) { IO_INFO *self; PyObject *pyself; unsigned int length; unsigned long long int offs; char *buf; PyObject *string; int result; // retrieve args if(!PyArg_ParseTuple(args, "OIK", &pyself, &length, &offs)) { return NULL; }; self = (IO_INFO *)PyCObject_AsVoidPtr(pyself); TRY { /** Create a new string to return to the caller */ string = PyString_FromStringAndSize(NULL, length); if(string) { buf = PyString_AsString(string); result=self->read_random(self,buf, length, offs,"Python calling"); /** If this was a short read we truncate the string (This is allowed because we just created it) */ if(result < length) if(_PyString_Resize(&string, result) <0 ) return NULL; }; } EXCEPT(E_ANY) { return PyErr_Format(map_exceptions_for_python(__EXCEPT__), "%s", except_str); }; /** Return the string to our caller */ if(!string) return PyErr_Format(PyExc_MemoryError, "Unable to allocate a string of length %u\n", length); return string; };
static PyObject * lad_read(lad_t *self, PyObject *args) { int size, count; char *cp; PyObject *rv; if (!PyArg_ParseTuple(args, "i:read", &size)) return NULL; rv = PyString_FromStringAndSize(NULL, size); if (rv == NULL) return NULL; cp = PyString_AS_STRING(rv); if ((count = read(self->x_fd, cp, size)) < 0) { PyErr_SetFromErrno(LinuxAudioError); Py_DECREF(rv); return NULL; } self->x_icount += count; _PyString_Resize(&rv, count); return rv; }
static PyObject * s_get(void *ptr, Py_ssize_t size) { PyObject *result; size_t slen; result = PyString_FromString((char *)ptr); if (!result) return NULL; /* chop off at the first NUL character, if any. * On error, result will be deallocated and set to NULL. */ slen = strlen(PyString_AS_STRING(result)); size = min(size, (Py_ssize_t)slen); if (result->ob_refcnt == 1) { /* shorten the result */ _PyString_Resize(&result, size); return result; } else /* cannot shorten the result */ return PyString_FromStringAndSize(ptr, size); }
PyObject *_internal_encode(_YajlEncoder *self, PyObject *obj) { yajl_gen generator = NULL; yajl_gen_config genconfig = { 0, NULL}; yajl_gen_status status; struct StringAndUsedCount sauc; /* initialize context for our printer function which * performs low level string appending, using the python * string implementation as a chunked growth buffer */ sauc.used = 0; sauc.str = lowLevelStringAlloc(PY_YAJL_CHUNK_SZ); generator = yajl_gen_alloc2(py_yajl_printer, &genconfig, NULL, (void *) &sauc); self->_generator = generator; status = ProcessObject(self, obj); yajl_gen_free(generator); self->_generator = NULL; /* if resize failed inside our printer function we'll have a null sauc.str */ if (!sauc.str) { PyErr_SetObject(PyExc_ValueError, PyString_FromString("Allocation failure")); return NULL; } if (status != yajl_gen_status_ok) { PyErr_SetObject(PyExc_ValueError, PyString_FromString("Failed to process")); Py_XDECREF(sauc.str); return NULL; } /* truncate to used size, and resize will handle the null plugging */ _PyString_Resize(&sauc.str, sauc.used); return sauc.str; }
static void py_yajl_printer(void * ctx, const char * str, unsigned int len) { struct StringAndUsedCount * sauc = (struct StringAndUsedCount *) ctx; size_t newsize; if (!sauc || !sauc->str) return; /* resize our string if necc */ newsize = Py_SIZE(sauc->str); while (sauc->used + len > newsize) newsize *= 2; if (newsize != Py_SIZE(sauc->str)) { _PyString_Resize(&(sauc->str), newsize); if (!sauc->str) return; } /* and append data if available */ if (len && str) { memcpy((void *) (((PyStringObject *) sauc->str)->ob_sval + sauc->used), str, len); sauc->used += len; } }
static PyObject * DNA_checkbases(PyObject *bogus, PyStringObject *string) { register char *input, *output; register int i; register char c; register const char *table = " zz z z " " zzzzzzzzzz ABCD GH K MN RST VW Y z" " ABCD GH K MN RST VW Y " " " " " " "; PyObject *input_obj = (PyObject *)string, *result; int len; i = PyString_Size(input_obj); input = PyString_AsString(input_obj); result = PyString_FromStringAndSize((char *)NULL, i+1); if (result == NULL) return NULL; output = PyString_AsString(result); output[0] = ' '; len = 1; for (;--i >= 0;) { c = table[Py_CHARMASK(*input++)]; if (c == 'z') continue; else if (c == ' ') { PyErr_SetString(PyExc_TypeError, "All bases must IUPAC letters"); return NULL; } output[len] = c; len++; } _PyString_Resize(&result, len); return result; }
static PyObject* getenvironment(PyObject* environment) { int i, envsize; PyObject* out = NULL; PyObject* keys; PyObject* values; char* p; /* convert environment dictionary to windows enviroment string */ if (! PyMapping_Check(environment)) { PyErr_SetString( PyExc_TypeError, "environment must be dictionary or None"); return NULL; } envsize = PyMapping_Length(environment); keys = PyMapping_Keys(environment); values = PyMapping_Values(environment); if (!keys || !values) goto error; out = PyString_FromStringAndSize(NULL, 2048); if (! out) goto error; p = PyString_AS_STRING(out); for (i = 0; i < envsize; i++) { int ksize, vsize, totalsize; PyObject* key = PyList_GET_ITEM(keys, i); PyObject* value = PyList_GET_ITEM(values, i); if (! PyString_Check(key) || ! PyString_Check(value)) { PyErr_SetString(PyExc_TypeError, "environment can only contain strings"); goto error; } ksize = PyString_GET_SIZE(key); vsize = PyString_GET_SIZE(value); totalsize = (p - PyString_AS_STRING(out)) + ksize + 1 + vsize + 1 + 1; if (totalsize > PyString_GET_SIZE(out)) { int offset = p - PyString_AS_STRING(out); _PyString_Resize(&out, totalsize + 1024); p = PyString_AS_STRING(out) + offset; } memcpy(p, PyString_AS_STRING(key), ksize); p += ksize; *p++ = '='; memcpy(p, PyString_AS_STRING(value), vsize); p += vsize; *p++ = '\0'; } /* add trailing null byte */ *p++ = '\0'; _PyString_Resize(&out, p - PyString_AS_STRING(out)); /* PyObject_Print(out, stdout, 0); */ Py_XDECREF(keys); Py_XDECREF(values); return out; error: Py_XDECREF(out); Py_XDECREF(keys); Py_XDECREF(values); return NULL; }
/* * Internal function to read a line * XXX: does not check for a valid stream, * the caller is responsible for that! * * - if bytesrequested is 0, an empty string is returned * - if bytesrequested > 0, it is treated as the max * length of the line to return * - if bytesrequested < 0, an arbitrary length line * is returned * */ static PyObject * get_line(fcgi_Stream *self, long bytesrequested) { FCGX_Stream *s; size_t bytesread, buffersize; PyObject *v; int c, done; s = *(self->s); if (bytesrequested == 0) return PyString_FromString(""); if (bytesrequested < 0) buffersize = new_buffersize((size_t)0); else buffersize = bytesrequested; if (buffersize > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "requested number of bytes is more than a Python string can hold"); return NULL; } v = PyString_FromStringAndSize((char *)NULL, buffersize); if (v == NULL) return NULL; bytesread = 0; done = 0; for(;;) { Py_BEGIN_ALLOW_THREADS while (buffersize - bytesread > 0) { c = FCGX_GetChar(s); if (c == EOF) { if (bytesread == 0) { Py_BLOCK_THREADS Py_DECREF(v); return PyString_FromString(""); } else { done = 1; break; } } *(BUF(v) + bytesread) = (char) c; bytesread++; if (c == '\n') { done = 1; break; } } Py_END_ALLOW_THREADS if (done || (bytesread == bytesrequested)) break; if (bytesrequested < 0) { buffersize = new_buffersize(buffersize); if (_PyString_Resize(&v, buffersize) < 0) return NULL; } } if (bytesread != buffersize) _PyString_Resize(&v, bytesread); return v; }
static PyObject * fcgi_Stream_read(fcgi_Stream *self, PyObject *args) { FCGX_Stream *s; long bytesrequested = -1; size_t bytesread, buffersize, chunksize; PyObject *v; fcgi_Stream_Check(); s = *(self->s); if (!PyArg_ParseTuple(args, "|l:read", &bytesrequested)) return NULL; if (bytesrequested == 0) return PyString_FromString(""); if (bytesrequested < 0) buffersize = new_buffersize((size_t)0); else buffersize = bytesrequested; if (buffersize > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "requested number of bytes is more than a Python string can hold"); return NULL; } v = PyString_FromStringAndSize((char *)NULL, buffersize); if (v == NULL) return NULL; bytesread = 0; for (;;) { Py_BEGIN_ALLOW_THREADS chunksize = FCGX_GetStr(BUF(v) + bytesread, buffersize - bytesread, s); Py_END_ALLOW_THREADS if (chunksize == 0) { if (FCGX_HasSeenEOF(s)) break; PyErr_SetString(PyExc_IOError, "Read failed"); Py_DECREF(v); return NULL; } bytesread += chunksize; if (bytesread < buffersize) { break; } if (bytesrequested < 0) { buffersize = new_buffersize(buffersize); if (_PyString_Resize(&v, buffersize) < 0) return NULL; } else { /* Got what was requested. */ break; } } if (bytesread != buffersize) _PyString_Resize(&v, bytesread); return v; }
bool wsgi_call_application(Request* request) { StartResponse* start_response = PyObject_NEW(StartResponse, &StartResponse_Type); start_response->request = request; /* From now on, `headers` stores the _response_ headers * (passed by the WSGI app) rather than the _request_ headers */ PyObject* request_headers = request->headers; request->headers = NULL; /* application(environ, start_response) call */ PyObject* retval = PyObject_CallFunctionObjArgs( request->server_info->wsgi_app, request_headers, start_response, NULL /* sentinel */ ); Py_DECREF(request_headers); Py_DECREF(start_response); if(retval == NULL) return false; /* The following code is somewhat magic, so worth an explanation. * * If the application we called was a generator, we have to call .next() on * it before we do anything else because that may execute code that * invokes `start_response` (which might not have been invoked yet). * Think of the following scenario: * * def app(environ, start_response): * start_response('200 Ok', ...) * yield 'Hello World' * * That would make `app` return an iterator (more precisely, a generator). * Unfortunately, `start_response` wouldn't be called until the first item * of that iterator is requested; `start_response` however has to be called * _before_ the wsgi body is sent, because it passes the HTTP headers. * * If the application returned a list this would not be required of course, * but special-handling is painful - especially in C - so here's one generic * way to solve the problem: * * Look into the returned iterator in any case. This allows us to do other * optimizations, for example if the returned value is a list with exactly * one string in it, we can pick the string and throw away the list so bjoern * does not have to come back again and look into the iterator a second time. */ PyObject* first_chunk; if(PyList_Check(retval) && PyList_GET_SIZE(retval) == 1 && PyString_Check(PyList_GET_ITEM(retval, 0))) { /* Optimize the most common case, a single string in a list: */ PyObject* tmp = PyList_GET_ITEM(retval, 0); Py_INCREF(tmp); Py_DECREF(retval); retval = tmp; goto string; /* eeevil */ } else if(PyString_Check(retval)) { /* According to PEP 333 strings should be handled like any other iterable, * i.e. sending the response item for item. "item for item" means * "char for char" if you have a string. -- I'm not that stupid. */ string: if(PyString_GET_SIZE(retval)) { first_chunk = retval; } else { Py_DECREF(retval); first_chunk = NULL; } } else if(FileWrapper_CheckExact(retval)) { request->state.use_sendfile = true; request->iterable = ((FileWrapper*)retval)->file; Py_INCREF(request->iterable); Py_DECREF(retval); request->iterator = NULL; first_chunk = NULL; } else { /* Generic iterable (list of length != 1, generator, ...) */ request->iterable = retval; request->iterator = PyObject_GetIter(retval); if(request->iterator == NULL) return false; first_chunk = wsgi_iterable_get_next_chunk(request); if(first_chunk == NULL && PyErr_Occurred()) return false; } if(request->headers == NULL) { /* It is important that this check comes *after* the call to * wsgi_iterable_get_next_chunk(), because in case the WSGI application * was an iterator, there's no chance start_response could be called * before. See above if you don't understand what I say. */ PyErr_SetString( PyExc_RuntimeError, "wsgi application returned before start_response was called" ); Py_XDECREF(first_chunk); return false; } /* keep-alive cruft */ if(http_should_keep_alive(&request->parser.parser)) { if(request->state.response_length_unknown) { if(request->parser.parser.http_major > 0 && request->parser.parser.http_minor > 0) { /* On HTTP 1.1, we can use Transfer-Encoding: chunked. */ request->state.chunked_response = true; request->state.keep_alive = true; } else { /* On HTTP 1.0, we can only resort to closing the connection. */ request->state.keep_alive = false; } } else { /* We know the content-length. Can always keep-alive. */ request->state.keep_alive = true; } } else { /* Explicit "Connection: close" (HTTP 1.1) or missing "Connection: keep-alive" (HTTP 1.0) */ request->state.keep_alive = false; } /* Get the headers and concatenate the first body chunk. * In the first place this makes the code more simple because afterwards * we can throw away the first chunk PyObject; but it also is an optimization: * At least for small responses, the complete response could be sent with * one send() call (in server.c:ev_io_on_write) which is a (tiny) performance * booster because less kernel calls means less kernel call overhead. */ PyObject* buf = PyString_FromStringAndSize(NULL, 1024); Py_ssize_t length = wsgi_getheaders(request, buf); if(first_chunk == NULL) { _PyString_Resize(&buf, length); goto out; } if(request->state.chunked_response) { PyObject* new_chunk = wrap_http_chunk_cruft_around(first_chunk); Py_DECREF(first_chunk); assert(PyString_GET_SIZE(new_chunk) >= PyString_GET_SIZE(first_chunk) + 5); first_chunk = new_chunk; } assert(buf); _PyString_Resize(&buf, length + PyString_GET_SIZE(first_chunk)); memcpy(PyString_AS_STRING(buf)+length, PyString_AS_STRING(first_chunk), PyString_GET_SIZE(first_chunk)); Py_DECREF(first_chunk); out: request->state.wsgi_call_done = true; request->current_chunk = buf; request->current_chunk_p = 0; return true; }
static PyObject *pylzma_decomp_decompress(CDecompressionObject *self, PyObject *args) { PyObject *result=NULL; unsigned char *data, *next_in, *next_out; int length, start_total_out, res, max_length=BLOCK_SIZE; SizeT avail_in, avail_out; unsigned char properties[LZMA_PROPERTIES_SIZE]; SizeT inProcessed, outProcessed; if (!PyArg_ParseTuple(args, "s#|l", &data, &length, &max_length)) return NULL; if (max_length <= 0) { PyErr_SetString(PyExc_ValueError, "bufsize must be greater than zero"); return NULL; } start_total_out = self->total_out; if (self->unconsumed_length > 0) { self->unconsumed_tail = (unsigned char *)realloc(self->unconsumed_tail, self->unconsumed_length + length); next_in = (unsigned char *)self->unconsumed_tail; memcpy(next_in + self->unconsumed_length, data, length); } else next_in = data; avail_in = self->unconsumed_length + length; if (self->need_properties && avail_in < sizeof(properties)) { // we need enough bytes to read the properties if (!self->unconsumed_length) { self->unconsumed_tail = (unsigned char *)malloc(length); memcpy(self->unconsumed_tail, data, length); } self->unconsumed_length += length; return PyString_FromString(""); } if (self->need_properties) { self->need_properties = 0; memcpy(&properties, next_in, sizeof(properties)); avail_in -= sizeof(properties); next_in += sizeof(properties); if (self->unconsumed_length >= sizeof(properties)-length) { self->unconsumed_length -= sizeof(properties)-length; if (self->unconsumed_length > 0) { memcpy(self->unconsumed_tail, self->unconsumed_tail+sizeof(properties), self->unconsumed_length); self->unconsumed_tail = (unsigned char *)realloc(self->unconsumed_tail, self->unconsumed_length); } else FREE_AND_NULL(self->unconsumed_tail); } if (LzmaDecodeProperties(&self->state.Properties, properties, LZMA_PROPERTIES_SIZE) != LZMA_RESULT_OK) { PyErr_SetString(PyExc_TypeError, "Incorrect stream properties"); goto exit; } self->state.Probs = (CProb *)malloc(LzmaGetNumProbs(&self->state.Properties) * sizeof(CProb)); if (self->state.Probs == 0) { PyErr_NoMemory(); goto exit; } if (self->state.Properties.DictionarySize == 0) self->state.Dictionary = 0; else { self->state.Dictionary = (unsigned char *)malloc(self->state.Properties.DictionarySize); if (self->state.Dictionary == 0) { free(self->state.Probs); self->state.Probs = NULL; PyErr_NoMemory(); goto exit; } } LzmaDecoderInit(&self->state); } if (avail_in == 0) // no more bytes to decompress return PyString_FromString(""); if (!(result = PyString_FromStringAndSize(NULL, max_length))) return NULL; next_out = (unsigned char *)PyString_AS_STRING(result); avail_out = max_length; Py_BEGIN_ALLOW_THREADS // Decompress until EOS marker is reached res = LzmaDecode(&self->state, next_in, avail_in, &inProcessed, next_out, avail_out, &outProcessed, 0); Py_END_ALLOW_THREADS self->total_out += outProcessed; next_in += inProcessed; avail_in -= inProcessed; next_out += outProcessed; avail_out -= outProcessed; if (res != LZMA_RESULT_OK) { PyErr_SetString(PyExc_ValueError, "data error during decompression"); DEC_AND_NULL(result); goto exit; } /* Not all of the compressed data could be accomodated in the output buffer of specified size. Return the unconsumed tail in an attribute.*/ if (avail_in > 0) { if (avail_in != self->unconsumed_length) { if (avail_in > self->unconsumed_length) { self->unconsumed_tail = (unsigned char *)realloc(self->unconsumed_tail, avail_in); memcpy(self->unconsumed_tail, next_in, avail_in); } if (avail_in < self->unconsumed_length) { memcpy(self->unconsumed_tail, next_in, avail_in); self->unconsumed_tail = (unsigned char *)realloc(self->unconsumed_tail, avail_in); } } if (!self->unconsumed_tail) { PyErr_NoMemory(); DEC_AND_NULL(result); goto exit; } } else FREE_AND_NULL(self->unconsumed_tail); self->unconsumed_length = avail_in; _PyString_Resize(&result, self->total_out - start_total_out); exit: return result; }
static PyObject *pylzma_decomp_flush(CDecompressionObject *self, PyObject *args) { PyObject *result=NULL; int res; SizeT avail_out, outsize; unsigned char *tmp; SizeT inProcessed, outProcessed; if (!PyArg_ParseTuple(args, "")) return NULL; if (self->max_length != -1) avail_out = self->max_length - self->total_out; else avail_out = BLOCK_SIZE; if (avail_out == 0) // no more remaining data return PyString_FromString(""); result = PyString_FromStringAndSize(NULL, avail_out); if (result == NULL) return NULL; tmp = (unsigned char *)PyString_AS_STRING(result); outsize = 0; while (1) { Py_BEGIN_ALLOW_THREADS if (self->unconsumed_length == 0) // No remaining data res = LzmaDecode(&self->state, (unsigned char *)"", 0, &inProcessed, tmp, avail_out, &outProcessed, 1); else { // Decompress remaining data res = LzmaDecode(&self->state, self->unconsumed_tail, self->unconsumed_length, &inProcessed, tmp, avail_out, &outProcessed, 1); self->unconsumed_length -= inProcessed; if (self->unconsumed_length > 0) memcpy(self->unconsumed_tail, self->unconsumed_tail + inProcessed, self->unconsumed_length); else FREE_AND_NULL(self->unconsumed_tail); } Py_END_ALLOW_THREADS if (res != LZMA_RESULT_OK) { PyErr_SetString(PyExc_ValueError, "data error during decompression"); DEC_AND_NULL(result); goto exit; } self->total_out += outProcessed; outsize += outProcessed; if (outProcessed < avail_out || (outProcessed == avail_out && self->max_length != -1)) break; if (self->max_length != -1) { PyErr_SetString(PyExc_ValueError, "not enough input data for decompression"); DEC_AND_NULL(result); goto exit; } avail_out -= outProcessed; // Output buffer is full, might be more data for decompression if (_PyString_Resize(&result, outsize+BLOCK_SIZE) != 0) goto exit; avail_out += BLOCK_SIZE; tmp = (unsigned char *)PyString_AS_STRING(result) + outsize; } if (outsize != PyString_GET_SIZE(result)) _PyString_Resize(&result, outsize); exit: return result; }
static PyObject * _conn_read(conn_rec *c, ap_input_mode_t mode, long len) { apr_bucket *b; apr_bucket_brigade *bb; apr_status_t rc; long bytes_read; PyObject *result; char *buffer; long bufsize; bb = apr_brigade_create(c->pool, c->bucket_alloc); bufsize = len == 0 ? HUGE_STRING_LEN : len; while (APR_BRIGADE_EMPTY(bb)) { Py_BEGIN_ALLOW_THREADS; rc = ap_get_brigade(c->input_filters, bb, mode, APR_BLOCK_READ, bufsize); Py_END_ALLOW_THREADS; if (rc != APR_SUCCESS) { PyErr_SetObject(PyExc_IOError, PyString_FromString("Connection read error")); return NULL; } } /* * loop through the brigade reading buckets into the string */ b = APR_BRIGADE_FIRST(bb); if (APR_BUCKET_IS_EOS(b)) { apr_bucket_delete(b); Py_INCREF(Py_None); return Py_None; } /* PYTHON 2.5: 'PyString_FromStringAndSize' uses Py_ssize_t for input parameters */ result = PyString_FromStringAndSize(NULL, bufsize); /* possibly no more memory */ if (result == NULL) return PyErr_NoMemory(); buffer = PyString_AS_STRING((PyStringObject *) result); bytes_read = 0; while ((bytes_read < len || len == 0) && !(b == APR_BRIGADE_SENTINEL(bb) || APR_BUCKET_IS_EOS(b) || APR_BUCKET_IS_FLUSH(b))) { const char *data; apr_size_t size; apr_bucket *old; if (apr_bucket_read(b, &data, &size, APR_BLOCK_READ) != APR_SUCCESS) { PyErr_SetObject(PyExc_IOError, PyString_FromString("Connection read error")); return NULL; } if (bytes_read + size > bufsize) { apr_bucket_split(b, bufsize - bytes_read); size = bufsize - bytes_read; /* now the bucket is the exact size we need */ } memcpy(buffer, data, size); buffer += size; bytes_read += size; /* time to grow destination string? */ if (len == 0 && bytes_read == bufsize) { /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */ _PyString_Resize(&result, bufsize + HUGE_STRING_LEN); buffer = PyString_AS_STRING((PyStringObject *) result); buffer += bufsize; bufsize += HUGE_STRING_LEN; } if (mode == AP_MODE_GETLINE || len == 0) { apr_bucket_delete(b); break; } old = b; b = APR_BUCKET_NEXT(b); apr_bucket_delete(old); } /* resize if necessary */ if (bytes_read < len || len == 0) /* PYTHON 2.5: '_PyString_Resize' uses Py_ssize_t for input parameters */ if(_PyString_Resize(&result, bytes_read)) return NULL; return result; }
static PyObject * PyZlib_flush(compobject *self, PyObject *args) { int err, length = DEFAULTALLOC; PyObject *RetVal; int flushmode = Z_FINISH; unsigned long start_total_out; if (!PyArg_ParseTuple(args, "|i:flush", &flushmode)) return NULL; /* Flushing with Z_NO_FLUSH is a no-op, so there's no point in doing any work at all; just return an empty string. */ if (flushmode == Z_NO_FLUSH) { return PyString_FromStringAndSize(NULL, 0); } if (!(RetVal = PyString_FromStringAndSize(NULL, length))) return NULL; ENTER_ZLIB start_total_out = self->zst.total_out; self->zst.avail_in = 0; self->zst.avail_out = length; self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), flushmode); Py_END_ALLOW_THREADS /* while Z_OK and the output buffer is full, there might be more output, so extend the output buffer and try again */ while (err == Z_OK && self->zst.avail_out == 0) { if (_PyString_Resize(&RetVal, length << 1) < 0) goto error; self->zst.next_out = (unsigned char *)PyString_AS_STRING(RetVal) \ + length; self->zst.avail_out = length; length = length << 1; Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), flushmode); Py_END_ALLOW_THREADS } /* If flushmode is Z_FINISH, we also have to call deflateEnd() to free various data structures. Note we should only get Z_STREAM_END when flushmode is Z_FINISH, but checking both for safety*/ if (err == Z_STREAM_END && flushmode == Z_FINISH) { err = deflateEnd(&(self->zst)); if (err != Z_OK) { zlib_error(self->zst, err, "from deflateEnd()"); Py_DECREF(RetVal); RetVal = NULL; goto error; } else self->is_initialised = 0; /* We will only get Z_BUF_ERROR if the output buffer was full but there wasn't more output when we tried again, so it is not an error condition. */ } else if (err!=Z_OK && err!=Z_BUF_ERROR) { zlib_error(self->zst, err, "while flushing"); Py_DECREF(RetVal); RetVal = NULL; goto error; } _PyString_Resize(&RetVal, self->zst.total_out - start_total_out); error: LEAVE_ZLIB return RetVal; }