VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/python/src/PyIInputStream.cpp@ 59795

Last change on this file since 59795 was 59795, checked in by vboxsync, 8 years ago

temporarily back out the recent Python 3 changes (r105649, r105645, r105644, r105643, r105641)

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is the Python XPCOM language bindings.
15 *
16 * The Initial Developer of the Original Code is
17 * ActiveState Tool Corp.
18 * Portions created by the Initial Developer are Copyright (C) 2000
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 * Mark Hammond <mhammond@skippinet.com.au> (original author)
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38//
39// This code is part of the XPCOM extensions for Python.
40//
41// Written September 2000 by Mark Hammond.
42//
43// Based heavily on the Python COM support, which is
44// (c) Mark Hammond and Greg Stein.
45//
46// (c) 2000, ActiveState corp.
47
48#include "PyXPCOM_std.h"
49#include "nsIInputStream.h"
50
51// Prevents us needing to use an nsIScriptableInputStream
52// (and even that can't read binary data!!!)
53
54static nsIInputStream *GetI(PyObject *self) {
55 nsIID iid = NS_GET_IID(nsIInputStream);
56
57 if (!Py_nsISupports::Check(self, iid)) {
58 PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
59 return NULL;
60 }
61 return (nsIInputStream *)Py_nsISupports::GetI(self);
62}
63
64static PyObject *DoPyRead_Buffer(nsIInputStream *pI, PyObject *obBuffer, PRUint32 n)
65{
66 PRUint32 nread;
67 void *buf;
68#ifndef VBOX /* unsafe cast on 64-bit hosts. */
69 PRUint32 buf_len;
70 if (PyObject_AsWriteBuffer(obBuffer, &buf, (Py_ssize_t *)&buf_len) != 0) {
71#else /* VBOX */
72# if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN)
73 Py_ssize_t buf_len;
74# else
75 int buf_len;
76# endif /* VBOX */
77 if (PyObject_AsWriteBuffer(obBuffer, &buf, &buf_len) != 0) {
78#endif
79 PyErr_Clear();
80 PyErr_SetString(PyExc_TypeError, "The buffer object does not have a write buffer!");
81 return NULL;
82 }
83 if (n==(PRUint32)-1) {
84 n = buf_len;
85 } else {
86 if (n > buf_len) {
87 NS_WARNING("Warning: PyIInputStream::read() was passed an integer size greater than the size of the passed buffer! Buffer size used.\n");
88 n = buf_len;
89 }
90 }
91 nsresult r;
92 Py_BEGIN_ALLOW_THREADS;
93 r = pI->Read((char *)buf, n, &nread);
94 Py_END_ALLOW_THREADS;
95 if ( NS_FAILED(r) )
96 return PyXPCOM_BuildPyException(r);
97 return PyInt_FromLong(nread);
98}
99
100static PyObject *DoPyRead_Size(nsIInputStream *pI, PRUint32 n)
101{
102 if (n==(PRUint32)-1) {
103 nsresult r;
104 Py_BEGIN_ALLOW_THREADS;
105 r = pI->Available(&n);
106 Py_END_ALLOW_THREADS;
107 if (NS_FAILED(r))
108 return PyXPCOM_BuildPyException(r);
109 }
110 if (n==0) { // mozilla will assert if we alloc zero bytes.
111 return PyBuffer_New(0);
112 }
113 char *buf = (char *)nsMemory::Alloc(n);
114 if (buf==NULL) {
115 PyErr_NoMemory();
116 return NULL;
117 }
118 nsresult r;
119 PRUint32 nread;
120 Py_BEGIN_ALLOW_THREADS;
121 r = pI->Read(buf, n, &nread);
122 Py_END_ALLOW_THREADS;
123 PyObject *rc = NULL;
124 if ( NS_SUCCEEDED(r) ) {
125 rc = PyBuffer_New(nread);
126 if (rc != NULL) {
127 void *ob_buf;
128#ifndef VBOX /* unsafe cast on 64-bit hosts. */
129 PRUint32 buf_len;
130 if (PyObject_AsWriteBuffer(rc, &ob_buf, (Py_ssize_t *)&buf_len) != 0) {
131#else /* VBOX */
132# if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN)
133 Py_ssize_t buf_len;
134# else
135 int buf_len;
136# endif /* VBOX */
137 if (PyObject_AsWriteBuffer(rc, &ob_buf, &buf_len) != 0) {
138#endif
139 // should never fail - we just created it!
140 return NULL;
141 }
142 if (buf_len != nread) {
143 PyErr_SetString(PyExc_RuntimeError, "New buffer isnt the size we create it!");
144 return NULL;
145 }
146 memcpy(ob_buf, buf, nread);
147 }
148 } else
149 PyXPCOM_BuildPyException(r);
150 nsMemory::Free(buf);
151 return rc;
152}
153
154static PyObject *PyRead(PyObject *self, PyObject *args)
155{
156 PyObject *obBuffer = NULL;
157 PRUint32 n = (PRUint32)-1;
158
159 nsIInputStream *pI = GetI(self);
160 if (pI==NULL)
161 return NULL;
162 if (PyArg_ParseTuple(args, "|i", (int *)&n))
163 // This worked - no args, or just an int.
164 return DoPyRead_Size(pI, n);
165 // try our other supported arg format.
166 PyErr_Clear();
167 if (!PyArg_ParseTuple(args, "O|i", &obBuffer, (int *)&n)) {
168 PyErr_Clear();
169 PyErr_SetString(PyExc_TypeError, "'read()' must be called as (buffer_ob, int_size=-1) or (int_size=-1)");
170 return NULL;
171 }
172 return DoPyRead_Buffer(pI, obBuffer, n);
173}
174
175
176struct PyMethodDef
177PyMethods_IInputStream[] =
178{
179 { "read", PyRead, 1},
180 // The rest are handled as normal
181 {NULL}
182};
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use