コード例 #1
0
ファイル: zlibmodule.c プロジェクト: adintr/minipython
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;
}
コード例 #2
0
ファイル: zlibmodule.c プロジェクト: Oize/pspstacklesspython
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;
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: fsimage.c プロジェクト: 0day-ci/xen
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);
}
コード例 #5
0
ファイル: cdmodule.c プロジェクト: Charlian/python-cobra
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;
}
コード例 #6
0
/**
  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
}
コード例 #7
0
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;
}
コード例 #8
0
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;
}
コード例 #9
0
ファイル: _scproxy.c プロジェクト: 0xcc/python-read
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;
    }
}
コード例 #10
0
ファイル: cjsonx.c プロジェクト: petronius/cjsonx
/*
 * 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;
    }
}
コード例 #11
0
ファイル: iosubsys.c プロジェクト: anarchivist/pyflag
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;
};
コード例 #12
0
// @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;
}
コード例 #13
0
ファイル: encode.c プロジェクト: znanja/pil-py3k
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;
}
コード例 #14
0
ファイル: getdata.cpp プロジェクト: ramiro/pyodbc
    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;
    }
コード例 #15
0
ファイル: marshal.c プロジェクト: JupiterSmalltalk/openqwaq
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);
	}
}
コード例 #16
0
ファイル: PyView.cpp プロジェクト: SASfit/SASfit
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; }
}
コード例 #17
0
ファイル: io.c プロジェクト: anarchivist/pyflag
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;
};
コード例 #18
0
ファイル: linuxaudiodev.c プロジェクト: grobe0ba/plan9front
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;
}
コード例 #19
0
ファイル: cfield.c プロジェクト: 1310701102/sl4a
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);
}
コード例 #20
0
ファイル: encoder.c プロジェクト: alphabetum/py-yajl
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;
}
コード例 #21
0
ファイル: encoder.c プロジェクト: alphabetum/py-yajl
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;
    }
}
コード例 #22
0
ファイル: DNAUtils.c プロジェクト: andyoberlin/biopython
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;
}
コード例 #23
0
ファイル: _subprocess.c プロジェクト: Oize/pspstacklesspython
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;
}
コード例 #24
0
ファイル: pyfcgi.c プロジェクト: msolo-dropbox/msolo
/*
 * 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;
}
コード例 #25
0
ファイル: pyfcgi.c プロジェクト: msolo-dropbox/msolo
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;
}
コード例 #26
0
ファイル: wsgi.c プロジェクト: Logout22/bjoern
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;
}
コード例 #27
0
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;    
}
コード例 #28
0
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;
}
コード例 #29
0
ファイル: connobject.c プロジェクト: newyue588cc/CheungSSH
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;
}
コード例 #30
0
ファイル: zlibmodule.c プロジェクト: Oize/pspstacklesspython
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;
}