]> git.vomp.tv Git - vompserver.git/blob - libdvbmpeg/ringbuffy.c
Initial import
[vompserver.git] / libdvbmpeg / ringbuffy.c
1 /* 
2     Ringbuffer Implementation for gtvscreen
3
4     Copyright (C) 2000 Marcus Metzler (mocm@metzlerbros.de)
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "ringbuffy.h"
22
23 int ring_init (ringbuffy *rbuf, int size)
24 {
25         if (size > 0){
26                 rbuf->size = size;
27                 if( !(rbuf->buffy = (char *) malloc(sizeof(char)*size)) ){
28                         fprintf(stderr,"Not enough memory for ringbuffy\n");
29                         return -1;
30                 }
31         } else {
32                 fprintf(stderr,"Wrong size for ringbuffy\n");
33                 return -1;
34         }
35         rbuf->read_pos = 0;     
36         rbuf->write_pos = 0;
37         return 0;
38 }
39
40
41 void ring_destroy(ringbuffy *rbuf)
42 {
43         free(rbuf->buffy);
44 }
45
46
47 int ring_write(ringbuffy *rbuf, char *data, int count)
48 {
49
50         int diff, free, pos, rest;
51
52         if (count <=0 ) return 0;
53         pos  = rbuf->write_pos;
54         rest = rbuf->size - pos;
55         diff = rbuf->read_pos - pos;
56         free = (diff > 0) ? diff-1 : rbuf->size+diff-1;
57
58         if ( free <= 0 ) return FULL_BUFFER;
59         if ( free < count ) count = free;
60         
61         if (count >= rest){
62                 memcpy (rbuf->buffy+pos, data, rest);
63                 if (count - rest)
64                         memcpy (rbuf->buffy, data+rest, count - rest);
65                 rbuf->write_pos = count - rest;
66         } else {
67                 memcpy (rbuf->buffy+pos, data, count);
68                 rbuf->write_pos += count;
69         }
70
71         return count;
72 }
73
74
75
76
77 int ring_peek(ringbuffy *rbuf, char *data, int count, long off)
78 {
79
80         int diff, free, pos, rest;
81
82         if (count <=0 ) return 0;
83         pos  = rbuf->read_pos+off;
84         rest = rbuf->size - pos ;
85         diff = rbuf->write_pos - pos;
86         free = (diff >= 0) ? diff : rbuf->size+diff;
87
88         if ( free <= 0 ) return FULL_BUFFER;
89         if ( free < count ) count = free;
90         
91         if ( count < rest ){
92                 memcpy(data, rbuf->buffy+pos, count);
93         } else {
94                 memcpy(data, rbuf->buffy+pos, rest);
95                 if ( count - rest)
96                         memcpy(data+rest, rbuf->buffy, count - rest);
97         }
98
99         return count;
100 }
101
102 int ring_read(ringbuffy *rbuf, char *data, int count)
103 {
104
105         int diff, free, pos, rest;
106
107         if (count <=0 ) return 0;
108         pos  = rbuf->read_pos;
109         rest = rbuf->size - pos;
110         diff = rbuf->write_pos - pos;
111         free = (diff >= 0) ? diff : rbuf->size+diff;
112
113         if ( rest <= 0 ) return 0;
114         if ( free < count ) count = free;
115         
116         if ( count < rest ){
117                 memcpy(data, rbuf->buffy+pos, count);
118                 rbuf->read_pos += count;
119         } else {
120                 memcpy(data, rbuf->buffy+pos, rest);
121                 if ( count - rest)
122                         memcpy(data+rest, rbuf->buffy, count - rest);
123                 rbuf->read_pos = count - rest;
124         }
125
126         return count;
127 }
128
129
130
131 int ring_write_file(ringbuffy *rbuf, int fd, int count)
132 {
133
134         int diff, free, pos, rest, rr;
135
136         if (count <=0 ) return 0;
137         pos  = rbuf->write_pos;
138         rest = rbuf->size - pos;
139         diff = rbuf->read_pos - pos;
140         free = (diff > 0) ? diff-1 : rbuf->size+diff-1;
141
142         if ( rest <= 0 ) return 0;
143         if ( free < count ) count = free;
144         
145         if (count >= rest){
146                 rr = read (fd, rbuf->buffy+pos, rest);
147                 if (rr == rest && count - rest)
148                         rr += read (fd, rbuf->buffy, count - rest);
149                 if (rr >=0)
150                         rbuf->write_pos = (pos + rr) % rbuf->size;
151         } else {
152                 rr = read (fd, rbuf->buffy+pos, count);
153                 if (rr >=0)
154                         rbuf->write_pos += rr;
155         }
156
157         return rr;
158 }
159
160
161
162 int ring_read_file(ringbuffy *rbuf, int fd, int count)
163 {
164
165         int diff, free, pos, rest, rr;
166
167         if (count <=0 ) return 0;
168         pos  = rbuf->read_pos;
169         rest = rbuf->size - pos;
170         diff = rbuf->write_pos - pos;
171         free = (diff >= 0) ? diff : rbuf->size+diff;
172
173         if ( free <= 0 ) return FULL_BUFFER;
174         if ( free < count ) count = free;
175
176         if (count >= rest){
177                 rr = write (fd, rbuf->buffy+pos, rest);
178                 if (rr == rest && count - rest)
179                         rr += write (fd, rbuf->buffy, count - rest);
180                 if (rr >=0)
181                         rbuf->read_pos = (pos + rr) % rbuf->size;
182         } else {
183                 rr = write (fd, rbuf->buffy+pos, count);
184                 if (rr >=0)
185                         rbuf->read_pos += rr;
186         }
187
188
189         return rr;
190 }
191
192 int ring_rest(ringbuffy *rbuf){
193         int diff, free, pos, rest;
194         pos  = rbuf->read_pos;
195         rest = rbuf->size - pos;
196         diff = rbuf->write_pos - pos;
197         free = (diff >= 0) ? diff : rbuf->size+diff;
198         
199         return free;
200 }