Statistics
| Branch: | Tag: | Revision:

dvbd / ringbuffy.c @ bfdb7446

History | View | Annotate | Download (4.37 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 "config.h"
22
#include "ringbuffy.h"
23
#include <string.h>
24

    
25
int ring_init (ringbuffy *rbuf, int size)
26
{
27
        if (size > 0){
28
                rbuf->size = size;
29
                if( !(rbuf->buffy = (char *) malloc(sizeof(char)*size)) ){
30
                        fprintf(stderr,"Not enough memory for ringbuffy\n");
31
                        return -1;
32
                }
33
        } else {
34
                fprintf(stderr,"Wrong size for ringbuffy\n");
35
                return -1;
36
        }
37
        rbuf->read_pos = 0;        
38
        rbuf->write_pos = 0;
39
        return 0;
40
}
41

    
42

    
43
void ring_destroy(ringbuffy *rbuf)
44
{
45
        free(rbuf->buffy);
46
}
47

    
48

    
49
int ring_write(ringbuffy *rbuf, char *data, int count)
50
{
51

    
52
        int diff, free, pos, rest;
53

    
54
        if (count <=0 ) return 0;
55
               pos  = rbuf->write_pos;
56
        rest = rbuf->size - pos;
57
        diff = rbuf->read_pos - pos;
58
        free = (diff > 0) ? diff-1 : rbuf->size+diff-1;
59

    
60
        if ( free <= 0 ) return FULL_BUFFER;
61
        if ( free < count ) count = free;
62
        
63
        if (count >= rest){
64
                memcpy (rbuf->buffy+pos, data, rest);
65
                if (count - rest)
66
                        memcpy (rbuf->buffy, data+rest, count - rest);
67
                rbuf->write_pos = count - rest;
68
        } else {
69
                memcpy (rbuf->buffy+pos, data, count);
70
                rbuf->write_pos += count;
71
        }
72

    
73
        return count;
74
}
75

    
76

    
77

    
78

    
79
int ring_peek(ringbuffy *rbuf, char *data, int count, long off)
80
{
81

    
82
        int diff, free, pos, rest;
83

    
84
        if (count <=0 ) return 0;
85
        pos  = rbuf->read_pos+off;
86
        rest = rbuf->size - pos ;
87
        diff = rbuf->write_pos - pos;
88
        free = (diff >= 0) ? diff : rbuf->size+diff;
89

    
90
        if ( free <= 0 ) return FULL_BUFFER;
91
        if ( free < count ) count = free;
92
        
93
        if ( count < rest ){
94
                memcpy(data, rbuf->buffy+pos, count);
95
        } else {
96
                memcpy(data, rbuf->buffy+pos, rest);
97
                if ( count - rest)
98
                        memcpy(data+rest, rbuf->buffy, count - rest);
99
        }
100

    
101
        return count;
102
}
103

    
104
int ring_read(ringbuffy *rbuf, char *data, int count)
105
{
106

    
107
        int diff, free, pos, rest;
108

    
109
        if (count <=0 ) return 0;
110
        pos  = rbuf->read_pos;
111
        rest = rbuf->size - pos;
112
        diff = rbuf->write_pos - pos;
113
        free = (diff >= 0) ? diff : rbuf->size+diff;
114

    
115
        if ( rest <= 0 ) return 0;
116
        if ( free < count ) count = free;
117
        
118
        if ( count < rest ){
119
                memcpy(data, rbuf->buffy+pos, count);
120
                rbuf->read_pos += count;
121
        } else {
122
                memcpy(data, rbuf->buffy+pos, rest);
123
                if ( count - rest)
124
                        memcpy(data+rest, rbuf->buffy, count - rest);
125
                rbuf->read_pos = count - rest;
126
        }
127

    
128
        return count;
129
}
130

    
131

    
132

    
133
int ring_write_file(ringbuffy *rbuf, int fd, int count)
134
{
135

    
136
        int diff, free, pos, rest, rr;
137

    
138
        if (count <=0 ) return 0;
139
               pos  = rbuf->write_pos;
140
        rest = rbuf->size - pos;
141
        diff = rbuf->read_pos - pos;
142
        free = (diff > 0) ? diff-1 : rbuf->size+diff-1;
143

    
144
        if ( rest <= 0 ) return 0;
145
        if ( free < count ) count = free;
146
        
147
        if (count >= rest){
148
                rr = read (fd, rbuf->buffy+pos, rest);
149
                if (rr == rest && count - rest)
150
                        rr += read (fd, rbuf->buffy, count - rest);
151
                if (rr >=0)
152
                        rbuf->write_pos = (pos + rr) % rbuf->size;
153
        } else {
154
                rr = read (fd, rbuf->buffy+pos, count);
155
                if (rr >=0)
156
                        rbuf->write_pos += rr;
157
        }
158

    
159
        return rr;
160
}
161

    
162

    
163

    
164
int ring_read_file(ringbuffy *rbuf, int fd, int count)
165
{
166

    
167
        int diff, free, pos, rest, rr;
168

    
169
        if (count <=0 ) return 0;
170
        pos  = rbuf->read_pos;
171
        rest = rbuf->size - pos;
172
        diff = rbuf->write_pos - pos;
173
        free = (diff >= 0) ? diff : rbuf->size+diff;
174

    
175
        if ( free <= 0 ) return FULL_BUFFER;
176
        if ( free < count ) count = free;
177

    
178
        if (count >= rest){
179
                rr = write (fd, rbuf->buffy+pos, rest);
180
                if (rr == rest && count - rest)
181
                        rr += write (fd, rbuf->buffy, count - rest);
182
                if (rr >=0)
183
                        rbuf->read_pos = (pos + rr) % rbuf->size;
184
        } else {
185
                rr = write (fd, rbuf->buffy+pos, count);
186
                if (rr >=0)
187
                        rbuf->read_pos += rr;
188
        }
189

    
190

    
191
        return rr;
192
}
193

    
194
int ring_rest(ringbuffy *rbuf){
195
               int diff, free, pos, rest;
196
        pos  = rbuf->read_pos;
197
        rest = rbuf->size - pos;
198
        diff = rbuf->write_pos - pos;
199
        free = (diff >= 0) ? diff : rbuf->size+diff;
200
        
201
        return free;
202
}