-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbufferevent.pxi
147 lines (111 loc) · 4.42 KB
/
bufferevent.pxi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# bufferevent
cdef extern from "event.h":
struct evbuffer:
char *buf "buffer"
int off
struct event_watermark:
int low
int high
struct bufev_t "bufferevent":
evbuffer *input
event_watermark wm_read
event_watermark wm_write
int evbuffer_drain(evbuffer *b, int size)
bufev_t *bufferevent_new(int fd, void (*readcb)(bufev_t *b, void *arg),
void (*writecb)(bufev_t *b, void *arg),
void (*errorcb)(bufev_t *b, short e, void *arg),
void *cbarg)
void bufferevent_free(bufev_t *b)
int bufferevent_write(bufev_t *b, void *data, int size)
int bufferevent_read(bufev_t *b, void *data, int size)
int bufferevent_enable(bufev_t *b, short event)
int bufferevent_disable(bufev_t *b, short event)
void bufferevent_settimeout(bufev_t *b, int read_secs, int write_secs)
EVBUFFER_READ = 0x01
EVBUFFER_WRITE = 0x02
EVBUFFER_EOF = 0x10
EVBUFFER_ERROR = 0x20
EVBUFFER_TIMEOUT = 0x40
ctypedef void (*evbuffer_handler)(bufev_t *b, void *arg)
ctypedef void (*everror_handler)(bufev_t *b, short what, void *arg)
cdef void __bufev_readcb(bufev_t *b, void *arg) with gil:
o = (<object>arg)
o.readcb(*o.args)
cdef void __bufev_writecb(bufev_t *b, void *arg) with gil:
o = (<object>arg)
o.writecb(*o.args)
cdef void __bufev_errorcb(bufev_t *b, short what, void *arg) with gil:
o = (<object>arg)
o.errorcb(what, *o.args)
cdef class bufferevent:
"""bufferevent(handle, readcb, writecb, errorcb, *args) -> bufferevent object
Create a new buffered event
Arguments:
handle -- file handle, descriptor, or socket
readcb -- callback to invoke when there is data to be read, or None
writecb -- callback to invoke when ready for writing, or None
errorcb -- callback to invoke on error, or None
*args -- optional arguments to be passed to each of the callbacks
"""
cdef bufev_t *bufev
cdef public object handle, readcb, writecb, errorcb, args
def __init__(self, handle, readcb, writecb, errorcb, *args):
cdef evbuffer_handler rcb, wcb
cdef everror_handler ecb
self.handle = handle
self.readcb = readcb
self.writecb = writecb
self.errorcb = errorcb
self.args = args
rcb = wcb = ecb = NULL
if readcb is not None:
rcb = __bufev_readcb
if writecb is not None:
wcb = __bufev_writecb
if errorcb is not None:
ecb = __bufev_errorcb
if not isinstance(handle, int):
handle = handle.fileno()
self.bufev = bufferevent_new(handle, rcb, wcb, ecb, <void *>self)
def enable(self, short evtype):
"""Enable a bufferevent.
Arguments:
evtype -- any combination of EV_READ | EV_WRITE
"""
bufferevent_enable(self.bufev, evtype)
def disable(self, short evtype):
"""Disable a bufferevent.
Arguments:
evtype -- any combination of EV_READ | EV_WRITE
"""
bufferevent_disable(self.bufev, evtype)
def read(self, int size=-1):
"""Read data from a bufferevent.
Optional arguments:
size -- number of bytes to read
"""
if size < 0:
size = self.bufev.input.off
else:
size = min(self.bufev.input.off, size)
buf = PyString_FromStringAndSize(self.bufev.input.buf, size)
evbuffer_drain(self.bufev.input, size)
return buf
def write(self, buf):
"""Write data to a bufferevent. The data is appended to the output
buffer and written to the handle automatically as it becomes available
for writing. Returns 0 if successful, or -1 on error.
Arguments:
buf -- data to write
"""
cdef char *p
cdef int n
if PyObject_AsCharBuffer(buf, &p, &n) < 0:
raise TypeError
return bufferevent_write(self.bufev, p, n)
def set_timeout(self, int read_secs, int write_secs):
bufferevent_settimeout(self.bufev, read_secs, write_secs)
def __dealloc__(self):
bufferevent_free(self.bufev)
def __repr__(self):
return '<bufferevent handle=%s, readcb=%s, writecb=%s, errorcb=%s, args=%s>' % (self.handle, self.readcb, self.writecb, self.errorcb, self.args)