~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/extensions/python/xpcom/src/PyIInputStream.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Mozilla Public License Version
 
3
 * 1.1 (the "License"); you may not use this file except in compliance with the
 
4
 * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
 
5
 *
 
6
 * Software distributed under the License is distributed on an "AS IS" basis,
 
7
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 
8
 * the specific language governing rights and limitations under the License.
 
9
 *
 
10
 * The Original Code is the Python XPCOM language bindings.
 
11
 *
 
12
 * The Initial Developer of the Original Code is ActiveState Tool Corp.
 
13
 * Portions created by ActiveState Tool Corp. are Copyright (C) 2000, 2001
 
14
 * ActiveState Tool Corp.  All Rights Reserved.
 
15
 *
 
16
 * Contributor(s): Mark Hammond <mhammond@skippinet.com.au> (original author)
 
17
 *
 
18
 */
 
19
 
 
20
//
 
21
// This code is part of the XPCOM extensions for Python.
 
22
//
 
23
// Written September 2000 by Mark Hammond.
 
24
//
 
25
// Based heavily on the Python COM support, which is
 
26
// (c) Mark Hammond and Greg Stein.
 
27
//
 
28
// (c) 2000, ActiveState corp.
 
29
 
 
30
#include "PyXPCOM_std.h"
 
31
#include "nsIInputStream.h"
 
32
 
 
33
// Prevents us needing to use an nsIScriptableInputStream
 
34
// (and even that can't read binary data!!!)
 
35
 
 
36
static nsIInputStream *GetI(PyObject *self) {
 
37
        nsIID iid = NS_GET_IID(nsIInputStream);
 
38
 
 
39
        if (!Py_nsISupports::Check(self, iid)) {
 
40
                PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
 
41
                return NULL;
 
42
        }
 
43
        return (nsIInputStream *)Py_nsISupports::GetI(self);
 
44
}
 
45
 
 
46
static PyObject *DoPyRead_Buffer(nsIInputStream *pI, PyObject *obBuffer, PRUint32 n)
 
47
{
 
48
        PRUint32 nread;
 
49
        void *buf;
 
50
        PRUint32 buf_len;
 
51
        if (PyObject_AsWriteBuffer(obBuffer, &buf, (int *)&buf_len) != 0) {
 
52
                PyErr_Clear();
 
53
                PyErr_SetString(PyExc_TypeError, "The buffer object does not have a write buffer!");
 
54
                return NULL;
 
55
        }
 
56
        if (n==(PRUint32)-1) {
 
57
                n = buf_len;
 
58
        } else {
 
59
                if (n > buf_len) {
 
60
                        NS_WARNING("Warning: PyIInputStream::read() was passed an integer size greater than the size of the passed buffer!  Buffer size used.\n");
 
61
                        n = buf_len;
 
62
                }
 
63
        }
 
64
        nsresult r;
 
65
        Py_BEGIN_ALLOW_THREADS;
 
66
        r = pI->Read((char *)buf, n, &nread);
 
67
        Py_END_ALLOW_THREADS;
 
68
        if ( NS_FAILED(r) )
 
69
                return PyXPCOM_BuildPyException(r);
 
70
        return PyInt_FromLong(nread);
 
71
}
 
72
 
 
73
static PyObject *DoPyRead_Size(nsIInputStream *pI, PRUint32 n)
 
74
{
 
75
        if (n==(PRUint32)-1) {
 
76
                nsresult r;
 
77
                Py_BEGIN_ALLOW_THREADS;
 
78
                r = pI->Available(&n);
 
79
                Py_END_ALLOW_THREADS;
 
80
                if (NS_FAILED(r))
 
81
                        return PyXPCOM_BuildPyException(r);
 
82
        }
 
83
        if (n==0) { // mozilla will assert if we alloc zero bytes.
 
84
                return PyBuffer_New(0);
 
85
        }
 
86
        char *buf = (char *)nsMemory::Alloc(n);
 
87
        if (buf==NULL) {
 
88
                PyErr_NoMemory();
 
89
                return NULL;
 
90
        }
 
91
        nsresult r;
 
92
        PRUint32 nread;
 
93
        Py_BEGIN_ALLOW_THREADS;
 
94
        r = pI->Read(buf, n, &nread);
 
95
        Py_END_ALLOW_THREADS;
 
96
        PyObject *rc = NULL;
 
97
        if ( NS_SUCCEEDED(r) ) {
 
98
                rc = PyBuffer_New(nread);
 
99
                if (rc != NULL) {
 
100
                        void *ob_buf;
 
101
                        PRUint32 buf_len;
 
102
                        if (PyObject_AsWriteBuffer(rc, &ob_buf, (int *)&buf_len) != 0) {
 
103
                                // should never fail - we just created it!
 
104
                                return NULL;
 
105
                        }
 
106
                        if (buf_len != nread) {
 
107
                                PyErr_SetString(PyExc_RuntimeError, "New buffer isnt the size we create it!");
 
108
                                return NULL;
 
109
                        }
 
110
                        memcpy(ob_buf, buf, nread);
 
111
                }
 
112
        } else
 
113
                PyXPCOM_BuildPyException(r);
 
114
        nsMemory::Free(buf);
 
115
        return rc;
 
116
}
 
117
 
 
118
static PyObject *PyRead(PyObject *self, PyObject *args)
 
119
{
 
120
        PyObject *obBuffer = NULL;
 
121
        PRUint32 n = (PRUint32)-1;
 
122
 
 
123
        nsIInputStream *pI = GetI(self);
 
124
        if (pI==NULL)
 
125
                return NULL;
 
126
        if (PyArg_ParseTuple(args, "|i", (int *)&n))
 
127
                // This worked - no args, or just an int.
 
128
                return DoPyRead_Size(pI, n);
 
129
        // try our other supported arg format.
 
130
        PyErr_Clear();
 
131
        if (!PyArg_ParseTuple(args, "O|i", &obBuffer, (int *)&n)) {
 
132
                PyErr_Clear();
 
133
                PyErr_SetString(PyExc_TypeError, "'read()' must be called as (buffer_ob, int_size=-1) or (int_size=-1)");
 
134
                return NULL;
 
135
        }
 
136
        return DoPyRead_Buffer(pI, obBuffer, n);
 
137
}
 
138
 
 
139
 
 
140
struct PyMethodDef 
 
141
PyMethods_IInputStream[] =
 
142
{
 
143
        { "read", PyRead, 1},
 
144
        // The rest are handled as normal
 
145
        {NULL}
 
146
};