Statistics
| Branch: | Tag: | Revision:

dvbd / src / ringbuffy.c @ a24dbbce

History | View | Annotate | Download (4.33 KB)

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
}