Release s3d 0.2.2
[s3d.git] / server / shm_ringbuf.c
blob8895f3e4729122496b0d64dd5254b17c5e7e70f4
1 /*
2 * shm_ringbuf.c
4 * Copyright (C) 2004-2011 Simon Wunderlich <dotslash@packetmixer.de>
6 * This file is part of s3d, a 3d network display server.
7 * See http://s3d.berlios.de/ for more updates.
9 * s3d is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * s3d is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with s3d; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "global.h"
25 #include <stdio.h> /* printf(), getchar() */
26 #include <stdint.h> /* uint32_t */
27 #include <string.h> /* memcpy() */
29 int shm_write(struct buf_t *rb, char *buf, int n)
31 int wrap = 0;
32 int rs;
33 int32_t e, s, size;
34 char *data;
36 e = rb->end;
37 s = rb->start;
38 size = rb->bufsize;
39 data = ((char *)rb) + sizeof(struct buf_t);
40 if (e < s) {
41 wrap = 1;
43 if ((((s + size * (1 - wrap)) - e) < (n + 1))) { /* checking free space */
44 printf("buffer reached maxsize, no resizing possible");
46 if ((e + n) > size) {
47 rs = size - e;
48 memcpy(data + e, buf, rs); /* copy the first part ... */
49 memcpy(data, buf + rs, n - rs); /* .. end the rest */
50 } else {
51 memcpy(data + e, buf, n); /* plain copy */
53 rb->end = e + n; /* update end of the buffer */
54 if (rb->end >= rb->bufsize)
55 rb->end -= rb->bufsize;
56 return 0;
59 int shm_read(struct buf_t *rb, char *buf, int n)
61 int wrap = 0;
62 int mn;
63 int rs;
64 int32_t e, s, size;
65 char *data;
67 e = rb->end;
68 s = rb->start;
69 size = rb->bufsize;
70 data = ((char *)rb) + sizeof(struct buf_t);
71 if (e < s)
72 wrap = 1;
73 rs = (e + wrap * size - s);
74 mn = (n > rs) ? rs : n;
75 if ((wrap) && (mn > (size - s))) {
76 rs = size - s; /* size of the first part */
77 memcpy(buf, data + s, rs);
78 memcpy(buf + rs, data, mn - rs);
79 } else { /* no wrap (needed) */
80 memcpy(buf, data + s, mn);
82 rb->start = s + mn;
83 if (rb->start >= rb->bufsize)
84 rb->start -= rb->bufsize;
85 return mn;
88 void ringbuf_init(char *data, uint32_t init_size)
90 struct buf_t *ringbuf = (struct buf_t *)data;
91 ringbuf->start = 0;
92 ringbuf->end = 0;
93 ringbuf->bufsize = init_size - RB_OVERHEAD;