8 #include "connection.h"
10 #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
17 struct wl_connection {
18 struct wl_buffer in, out;
21 wl_connection_update_func_t update;
24 struct wl_connection *
25 wl_connection_create(int fd,
26 wl_connection_update_func_t update,
29 struct wl_connection *connection;
31 connection = malloc(sizeof *connection);
32 memset(connection, 0, sizeof *connection);
34 connection->update = update;
35 connection->data = data;
37 connection->update(connection,
38 WL_CONNECTION_READABLE,
45 wl_connection_destroy(struct wl_connection *connection)
51 wl_connection_copy(struct wl_connection *connection, void *data, size_t size)
58 if (tail + size <= ARRAY_LENGTH(b->data)) {
59 memcpy(data, b->data + tail, size);
61 rest = ARRAY_LENGTH(b->data) - tail;
62 memcpy(data, b->data + tail, rest);
63 memcpy(data + rest, b->data, size - rest);
68 wl_connection_consume(struct wl_connection *connection, size_t size)
75 if (tail + size <= ARRAY_LENGTH(b->data)) {
78 rest = ARRAY_LENGTH(b->data) - tail;
79 b->tail = size - rest;
83 int wl_connection_data(struct wl_connection *connection, uint32_t mask)
87 int len, head, tail, count, size, available;
89 if (mask & WL_CONNECTION_READABLE) {
91 head = connection->in.head;
93 iov[0].iov_base = b->data + head;
94 iov[0].iov_len = b->tail - head;
97 size = ARRAY_LENGTH(b->data) - head;
98 iov[0].iov_base = b->data + head;
99 iov[0].iov_len = size;
100 iov[1].iov_base = b->data;
101 iov[1].iov_len = b->tail;
104 len = readv(connection->fd, iov, count);
107 "read error from connection %p: %m (%d)\n",
110 } else if (len == 0) {
111 /* FIXME: Handle this better? */
113 } else if (head + len <= ARRAY_LENGTH(b->data)) {
116 b->head = head + len - ARRAY_LENGTH(b->data);
119 /* We know we have data in the buffer at this point,
120 * so if head equals tail, it means the buffer is
123 available = b->head - b->tail;
125 available = sizeof b->data;
126 else if (available < 0)
127 available += ARRAY_LENGTH(b->data);
132 if (mask & WL_CONNECTION_WRITABLE) {
133 b = &connection->out;
135 if (tail < b->head) {
136 iov[0].iov_base = b->data + tail;
137 iov[0].iov_len = b->head - tail;
140 size = ARRAY_LENGTH(b->data) - tail;
141 iov[0].iov_base = b->data + tail;
142 iov[0].iov_len = size;
143 iov[1].iov_base = b->data;
144 iov[1].iov_len = b->head;
147 len = writev(connection->fd, iov, count);
149 fprintf(stderr, "write error for connection %p: %m\n", connection);
151 } else if (tail + len <= ARRAY_LENGTH(b->data)) {
154 b->tail = tail + len - ARRAY_LENGTH(b->data);
157 /* We just took data out of the buffer, so at this
158 * point if head equals tail, the buffer is empty. */
160 if (b->tail == b->head)
161 connection->update(connection,
162 WL_CONNECTION_READABLE,
170 wl_connection_write(struct wl_connection *connection, const void *data, size_t count)
176 b = &connection->out;
178 if (head + count <= ARRAY_LENGTH(b->data)) {
179 memcpy(b->data + head, data, count);
182 size = ARRAY_LENGTH(b->data) - head;
183 memcpy(b->data + head, data, size);
184 memcpy(b->data, data + size, count - size);
185 b->head = count - size;
189 connection->update(connection,
190 WL_CONNECTION_READABLE |
191 WL_CONNECTION_WRITABLE,