Add support for virNetworkPort object & APIs
[libvirt-python/ericb.git] / libvirt-override-virStream.py
blob901c2e6af94e205b172c82b2769882cab8f5c613
1 def __del__(self):
2 try:
3 if self.cb:
4 libvirtmod.virStreamEventRemoveCallback(self._o)
5 except AttributeError:
6 pass
8 if self._o is not None:
9 libvirtmod.virStreamFree(self._o)
10 self._o = None
12 def _dispatchStreamEventCallback(self, events, cbData):
13 """
14 Dispatches events to python user's stream event callbacks
15 """
16 cb = cbData["cb"]
17 opaque = cbData["opaque"]
19 cb(self, events, opaque)
20 return 0
22 def eventAddCallback(self, events, cb, opaque):
23 self.cb = cb
24 cbData = {"stream": self, "cb" : cb, "opaque" : opaque}
25 ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData)
26 if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed')
28 def recvAll(self, handler, opaque):
29 """Receive the entire data stream, sending the data to the
30 requested data sink. This is simply a convenient alternative
31 to virStreamRecv, for apps that do blocking-I/O.
33 A hypothetical handler function looks like:
35 def handler(stream, # virStream instance
36 buf, # string containing received data
37 opaque): # extra data passed to recvAll as opaque
38 fd = opaque
39 return os.write(fd, buf)
40 """
41 while True:
42 got = self.recv(1024*64)
43 if got == -2:
44 raise libvirtError("cannot use recvAll with "
45 "nonblocking stream")
46 if len(got) == 0:
47 break
49 try:
50 ret = handler(self, got, opaque)
51 if type(ret) is int and ret < 0:
52 raise RuntimeError("recvAll handler returned %d" % ret)
53 except Exception:
54 e = sys.exc_info()[1]
55 try:
56 self.abort()
57 except:
58 pass
59 raise e
61 def sendAll(self, handler, opaque):
62 """
63 Send the entire data stream, reading the data from the
64 requested data source. This is simply a convenient alternative
65 to virStreamSend, for apps that do blocking-I/O.
67 A hypothetical handler function looks like:
69 def handler(stream, # virStream instance
70 nbytes, # int amt of data to read
71 opaque): # extra data passed to recvAll as opaque
72 fd = opaque
73 return os.read(fd, nbytes)
74 """
75 while True:
76 try:
77 got = handler(self, 1024*64, opaque)
78 except:
79 e = sys.exc_info()[1]
80 try:
81 self.abort()
82 except:
83 pass
84 raise e
86 if not got:
87 break
89 ret = self.send(got)
90 if ret == -2:
91 raise libvirtError("cannot use sendAll with "
92 "nonblocking stream")
94 def recv(self, nbytes):
95 """Reads a series of bytes from the stream. This method may
96 block the calling application for an arbitrary amount
97 of time.
99 Errors are not guaranteed to be reported synchronously
100 with the call, but may instead be delayed until a
101 subsequent call.
103 On success, the received data is returned. On failure, an
104 exception is raised. If the stream is a NONBLOCK stream and
105 the request would block, integer -2 is returned.
107 ret = libvirtmod.virStreamRecv(self._o, nbytes)
108 if ret is None: raise libvirtError ('virStreamRecv() failed')
109 return ret
111 def send(self, data):
112 """Write a series of bytes to the stream. This method may
113 block the calling application for an arbitrary amount
114 of time. Once an application has finished sending data
115 it should call virStreamFinish to wait for successful
116 confirmation from the driver, or detect any error
118 This method may not be used if a stream source has been
119 registered
121 Errors are not guaranteed to be reported synchronously
122 with the call, but may instead be delayed until a
123 subsequent call.
125 ret = libvirtmod.virStreamSend(self._o, data)
126 if ret == -1: raise libvirtError ('virStreamSend() failed')
127 return ret
129 def recvHole(self, flags = 0):
130 """This method is used to determine the length in bytes
131 of the empty space to be created in a stream's target
132 file when uploading or downloading sparsely populated
133 files. This is the counterpart to sendHole.
135 ret = libvirtmod.virStreamRecvHole(self._o, flags)
136 if ret is None: raise libvirtError ('virStreamRecvHole() failed')
137 return ret
139 def sendHole(self, length, flags = 0):
140 """Rather than transmitting empty file space, this method
141 directs the stream target to create length bytes of empty
142 space. This method would be used when uploading or
143 downloading sparsely populated files to avoid the
144 needless copy of empty file space.
146 ret = libvirtmod.virStreamSendHole(self._o, length, flags)
147 if ret == -1: raise libvirtError('virStreamSendHole() failed')
148 return ret
150 def recvFlags(self, nbytes, flags = 0):
151 """Reads a series of bytes from the stream. This method may
152 block the calling application for an arbitrary amount
153 of time. This is just like recv except it has flags
154 argument.
156 Errors are not guaranteed to be reported synchronously
157 with the call, but may instead be delayed until a
158 subsequent call.
160 On success, the received data is returned. On failure, an
161 exception is raised. If the stream is a NONBLOCK stream and
162 the request would block, integer -2 is returned.
164 ret = libvirtmod.virStreamRecvFlags(self._o, nbytes, flags)
165 if ret is None: raise libvirtError ('virStreamRecvFlags() failed')
166 return ret
168 def sparseRecvAll(self, handler, holeHandler, opaque):
169 """Receive the entire data stream, sending the data to
170 the requested data sink handler and calling the skip
171 holeHandler to generate holes for sparse stream targets.
172 This is simply a convenient alternative to recvFlags, for
173 apps that do blocking-I/O and want to preserve sparseness.
175 Hypothetical callbacks can look like this:
177 def handler(stream, # virStream instance
178 buf, # string containing received data
179 opaque): # extra data passed to sparseRecvAll as opaque
180 fd = opaque
181 return os.write(fd, buf)
183 def holeHandler(stream, # virStream instance
184 length, # number of bytes to skip
185 opaque): # extra data passed to sparseRecvAll as opaque
186 fd = opaque
187 cur = os.lseek(fd, length, os.SEEK_CUR)
188 return os.ftruncate(fd, cur) # take this extra step to
189 # actually allocate the hole
191 while True:
192 want = 64 * 1024
193 got = self.recvFlags(want, VIR_STREAM_RECV_STOP_AT_HOLE)
194 if got == -2:
195 raise libvirtError("cannot use sparseRecvAll with "
196 "nonblocking stream")
197 if got == -3:
198 length = self.recvHole()
199 if length is None:
200 self.abort()
201 raise RuntimeError("recvHole handler failed")
202 ret = holeHandler(self, length, opaque)
203 if type(ret) is int and ret < 0:
204 self.abort()
205 raise RuntimeError("holeHandler handler returned %d" % ret)
206 continue
208 if len(got) == 0:
209 break
211 ret = handler(self, got, opaque)
212 if type(ret) is int and ret < 0:
213 self.abort()
214 raise RuntimeError("sparseRecvAll handler returned %d" % ret)
216 def sparseSendAll(self, handler, holeHandler, skipHandler, opaque):
217 """Send the entire data stream, reading the data from the
218 requested data source. This is simply a convenient
219 alternative to virStreamSend, for apps that do
220 blocking-I/O and want to preserve sparseness.
222 Hypothetical callbacks can look like this:
224 def handler(stream, # virStream instance
225 nbytes, # int amt of data to read
226 opaque): # extra data passed to sparseSendAll as opaque
227 fd = opaque
228 return os.read(fd, nbytes)
230 def holeHandler(stream, # virStream instance
231 opaque): # extra data passed to sparseSendAll as opaque
232 fd = opaque
233 cur = os.lseek(fd, 0, os.SEEK_CUR)
234 # ... find out current section and its boundaries
235 # and set inData = True/False and sectionLen correspondingly
236 os.lseek(fd, cur, os.SEEK_SET)
237 return [inData, sectionLen]
239 def skipHandler(stream, # virStream instance
240 length, # number of bytes to skip
241 opaque): # extra data passed to sparseSendAll as opaque
242 fd = opaque
243 return os.lseek(fd, length, os.SEEK_CUR)
246 while True:
247 [inData, sectionLen] = holeHandler(self, opaque)
248 if (inData == False and sectionLen > 0):
249 if (self.sendHole(sectionLen) < 0 or
250 skipHandler(self, sectionLen, opaque) < 0):
251 self.abort()
252 continue
254 want = 64 * 1024
255 if (want > sectionLen):
256 want = sectionLen
258 got = handler(self, want, opaque)
259 if type(got) is int and got < 0:
260 self.abort()
261 raise RuntimeError("sparseSendAll handler returned %d" % got)
263 if not got:
264 break
266 ret = self.send(got)
267 if ret == -2:
268 raise libvirtError("cannot use sparseSendAll with "
269 "nonblocking stream")