00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include "ringbuffer.h"
00030 #include "pes.h"
00031
00032 #define DEBUG 1
00033 int ring_init (ringbuffer *rbuf, int size)
00034 {
00035 if (size > 0){
00036 rbuf->size = size;
00037 if( !(rbuf->buffer = (uint8_t *) malloc(sizeof(uint8_t)*size)) ){
00038 fprintf(stderr,"Not enough memory for ringbuffer\n");
00039 return -1;
00040 }
00041 } else {
00042 fprintf(stderr,"Wrong size for ringbuffer\n");
00043 return -1;
00044 }
00045 rbuf->read_pos = 0;
00046 rbuf->write_pos = 0;
00047 return 0;
00048 }
00049
00050 int ring_reinit (ringbuffer *rbuf, int size)
00051 {
00052 if (size > (int)(rbuf->size)) {
00053 uint8_t *tmpalloc = (uint8_t *) realloc(rbuf->buffer,
00054 sizeof(uint8_t)*size);
00055 if (! tmpalloc)
00056 return -1;
00057 rbuf->buffer = tmpalloc;
00058 if (rbuf->write_pos < rbuf->read_pos)
00059 {
00060 unsigned int delta = size - rbuf->size;
00061 memmove(rbuf->buffer + rbuf->read_pos + delta,
00062 rbuf->buffer + rbuf->read_pos,
00063 rbuf->size - rbuf->read_pos);
00064 rbuf->read_pos += delta;
00065 }
00066 rbuf->size = size;
00067 }
00068 return 0;
00069 }
00070 void ring_clear(ringbuffer *rbuf)
00071 {
00072 rbuf->read_pos = 0;
00073 rbuf->write_pos = 0;
00074 }
00075
00076
00077
00078 void ring_destroy(ringbuffer *rbuf)
00079 {
00080 free(rbuf->buffer);
00081 }
00082
00083
00084 int ring_write(ringbuffer *rbuf, uint8_t *data, int count)
00085 {
00086
00087 int free, pos, rest;
00088
00089 if (count <=0 ) return 0;
00090 pos = rbuf->write_pos;
00091 rest = rbuf->size - pos;
00092 free = ring_free(rbuf);
00093
00094 if ( free < count ){
00095 if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d\n",
00096 free, count, rbuf->size);
00097 return FULL_BUFFER;
00098 }
00099
00100 if (count >= rest){
00101 memcpy (rbuf->buffer+pos, data, rest);
00102 if (count - rest)
00103 memcpy (rbuf->buffer, data+rest, count - rest);
00104 rbuf->write_pos = count - rest;
00105 } else {
00106 memcpy (rbuf->buffer+pos, data, count);
00107 rbuf->write_pos += count;
00108 }
00109
00110 if (DEBUG>1) fprintf(stderr,"Buffer empty %.2f%%\n",
00111 ring_free(rbuf)*100.0/rbuf->size);
00112 return count;
00113 }
00114
00115 int ring_peek(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off)
00116 {
00117
00118 unsigned int avail, pos, rest;
00119
00120 if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return -1;
00121 pos = (rbuf->read_pos+off)%rbuf->size;
00122 rest = rbuf->size - pos ;
00123 avail = ring_avail(rbuf);
00124
00125
00126 if ( avail < count ){
00127
00128
00129 return EMPTY_BUFFER;
00130 }
00131
00132 if ( count < rest ){
00133 memcpy(data, rbuf->buffer+pos, count);
00134 } else {
00135 memcpy(data, rbuf->buffer+pos, rest);
00136 if ( count - rest)
00137 memcpy(data+rest, rbuf->buffer, count - rest);
00138 }
00139
00140 return count;
00141 }
00142
00143 int ring_poke(ringbuffer *rbuf, uint8_t *data, unsigned int count, uint32_t off)
00144 {
00145
00146 unsigned int avail, pos, rest;
00147
00148 if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return -1;
00149 pos = (rbuf->read_pos+off)%rbuf->size;
00150 rest = rbuf->size - pos ;
00151 avail = ring_avail(rbuf);
00152
00153
00154 if ( avail < count ){
00155
00156
00157 return EMPTY_BUFFER;
00158 }
00159
00160 if ( count < rest ){
00161 memcpy(rbuf->buffer+pos, data, count);
00162 } else {
00163 memcpy(rbuf->buffer+pos, data, rest);
00164 if ( count - rest)
00165 memcpy(rbuf->buffer, data+rest, count - rest);
00166 }
00167
00168 return count;
00169 }
00170
00171 int ring_read(ringbuffer *rbuf, uint8_t *data, int count)
00172 {
00173
00174 int avail, pos, rest;
00175
00176 if (count <=0 ) return 0;
00177 pos = rbuf->read_pos;
00178 rest = rbuf->size - pos;
00179 avail = ring_avail(rbuf);
00180
00181 if ( avail < count ){
00182
00183
00184 return EMPTY_BUFFER;
00185 }
00186
00187 if ( count < rest ){
00188 memcpy(data, rbuf->buffer+pos, count);
00189 rbuf->read_pos += count;
00190 } else {
00191 memcpy(data, rbuf->buffer+pos, rest);
00192 if ( count - rest)
00193 memcpy(data+rest, rbuf->buffer, count - rest);
00194 rbuf->read_pos = count - rest;
00195 }
00196
00197 if (DEBUG>1) fprintf(stderr,"Buffer empty %.2f%%\n",
00198 ring_free(rbuf)*100.0/rbuf->size);
00199 return count;
00200 }
00201
00202 int ring_skip(ringbuffer *rbuf, int count)
00203 {
00204
00205 int avail, pos, rest;
00206
00207 if (count <=0 ) return -1;
00208 pos = rbuf->read_pos;
00209 rest = rbuf->size - pos;
00210 avail = ring_avail(rbuf);
00211
00212 if ( avail < count ){
00213
00214
00215 return EMPTY_BUFFER;
00216 }
00217 if ( count < rest ){
00218 rbuf->read_pos += count;
00219 } else {
00220 rbuf->read_pos = count - rest;
00221 }
00222
00223 if (DEBUG>1) fprintf(stderr,"Buffer empty %.2f%%\n",
00224 ring_free(rbuf)*100.0/rbuf->size);
00225 return count;
00226 }
00227
00228
00229
00230 int ring_write_file(ringbuffer *rbuf, int fd, int count)
00231 {
00232
00233 int free, pos, rest, rr;
00234
00235 if (count <=0 ) return 0;
00236 pos = rbuf->write_pos;
00237 rest = rbuf->size - pos;
00238 free = ring_free(rbuf);
00239
00240 if ( free < count ){
00241 if (DEBUG) fprintf(stderr,"ringbuffer overflow %d<%d %d %d\n",
00242 free, count, pos, rbuf->read_pos);
00243 return FULL_BUFFER;
00244 }
00245
00246 if (count >= rest){
00247 rr = read (fd, rbuf->buffer+pos, rest);
00248 if (rr == rest && count - rest)
00249 rr += read (fd, rbuf->buffer, count - rest);
00250 if (rr >=0)
00251 rbuf->write_pos = (pos + rr) % rbuf->size;
00252 } else {
00253 rr = read (fd, rbuf->buffer+pos, count);
00254 if (rr >=0)
00255 rbuf->write_pos += rr;
00256 }
00257
00258 if (DEBUG>1) fprintf(stderr,"Buffer empty %.2f%%\n",
00259 ring_free(rbuf)*100.0/rbuf->size);
00260 return rr;
00261 }
00262
00263
00264
00265 int ring_read_file(ringbuffer *rbuf, int fd, int count)
00266 {
00267
00268 int avail, pos, rest, rr;
00269
00270 if (count <=0 ) return -1;
00271 pos = rbuf->read_pos;
00272 rest = rbuf->size - pos;
00273 avail = ring_avail(rbuf);
00274
00275 if ( avail < count ){
00276
00277
00278 return EMPTY_BUFFER;
00279 }
00280
00281 if (count >= rest){
00282 rr = write (fd, rbuf->buffer+pos, rest);
00283 if (rr == rest && count - rest)
00284 rr += write (fd, rbuf->buffer, count - rest);
00285 if (rr >=0)
00286 rbuf->read_pos = (pos + rr) % rbuf->size;
00287 } else {
00288 rr = write (fd, rbuf->buffer+pos, count);
00289 if (rr >=0)
00290 rbuf->read_pos += rr;
00291 }
00292
00293
00294 if (DEBUG>1) fprintf(stderr,"Buffer empty %.2f%%\n",
00295 ring_free(rbuf)*100.0/rbuf->size);
00296 return rr;
00297 }
00298
00299
00300 static void show(uint8_t *buf, int length)
00301 {
00302 int i,j,r;
00303
00304 fprintf(stderr,"\n");
00305 for (i=0; i<length; i+=16){
00306 for (j=0; j < 8 && j+i<length; j++)
00307 fprintf(stderr,"0x%02x ", (int)(buf[i+j]));
00308 for (r=j; r<8; r++)
00309 fprintf(stderr," ");
00310
00311 fprintf(stderr," ");
00312
00313 for (j=8; j < 16 && j+i<length; j++)
00314 fprintf(stderr,"0x%02x ", (int)(buf[i+j]));
00315 for (r=j; r<16; r++)
00316 fprintf(stderr," ");
00317
00318 for (j=0; j < 16 && j+i<length; j++){
00319 switch(buf[i+j]){
00320 case '0'...'Z':
00321 case 'a'...'z':
00322 fprintf(stderr,"%c", buf[i+j]);
00323 break;
00324 default:
00325 fprintf(stderr,".");
00326 }
00327 }
00328 fprintf(stderr,"\n");
00329 }
00330 }
00331
00332 void ring_show(ringbuffer *rbuf, unsigned int count, uint32_t off)
00333 {
00334
00335 unsigned int avail, pos, rest;
00336
00337 if (count <=0 || off+count > rbuf->size || off+count >ring_avail(rbuf)) return;
00338 pos = (rbuf->read_pos+off)%rbuf->size;
00339 rest = rbuf->size - pos ;
00340 avail = ring_avail(rbuf);
00341
00342
00343 if ( avail < count ){
00344
00345
00346 return;
00347 }
00348
00349 if ( count < rest ){
00350 show(rbuf->buffer+pos, count);
00351 } else {
00352 show(rbuf->buffer+pos, rest);
00353 if ( count - rest)
00354 show(rbuf->buffer, count - rest);
00355 }
00356 }
00357
00358
00359 int dummy_init(dummy_buffer *dbuf, int s)
00360 {
00361 dbuf->size = s;
00362 dbuf->fill = 0;
00363 if (ring_init(&dbuf->time_index, DBUF_INDEX*sizeof(uint64_t)) < 0)
00364 return -1;
00365 if (ring_init(&dbuf->data_index, DBUF_INDEX*sizeof(int32_t)) < 0)
00366 return -1;
00367
00368 return 0;
00369 }
00370
00371 void dummy_destroy(dummy_buffer *dbuf)
00372 {
00373 ring_destroy(&dbuf->time_index);
00374 ring_destroy(&dbuf->data_index);
00375 }
00376
00377 void dummy_clear(dummy_buffer *dbuf)
00378 {
00379 dbuf->fill = 0;
00380 ring_clear(&dbuf->time_index);
00381 ring_clear(&dbuf->data_index);
00382 }
00383
00384 int dummy_add(dummy_buffer *dbuf, uint64_t time, uint32_t size)
00385 {
00386 if (dummy_space(dbuf) < size) return -1;
00387
00388 dbuf->fill += size;
00389 if (ring_write(&dbuf->time_index, (uint8_t *)&time, sizeof(uint64_t)) < 0)
00390 return -2;
00391 if (ring_write(&dbuf->data_index, (uint8_t *)&size, sizeof(uint32_t)) < 0)
00392 return -3;
00393
00394
00395 return size;
00396 }
00397
00398 int dummy_delete(dummy_buffer *dbuf, uint64_t time)
00399 {
00400 uint64_t rtime;
00401 uint32_t size;
00402 int ex=0;
00403 uint32_t dsize=0;
00404
00405 do {
00406 if (ring_peek(&dbuf->time_index,(uint8_t *) &rtime,
00407 sizeof(uint64_t), 0)<0){
00408 if (dsize) break;
00409 else return -1;
00410 }
00411 if (ptscmp(rtime,time) < 0){
00412 ring_read(&dbuf->time_index,(uint8_t *) &rtime,
00413 sizeof(uint64_t));
00414 ring_read(&dbuf->data_index,(uint8_t *) &size,
00415 sizeof(uint32_t));
00416 dsize += size;
00417 } else ex = 1;
00418 } while (!ex);
00419
00420 dbuf->fill -= dsize;
00421
00422
00423
00424 return dsize;
00425 }
00426 void dummy_print(dummy_buffer *dbuf)
00427 {
00428 int i;
00429 uint64_t rtime;
00430 uint32_t size;
00431 int avail = ring_avail(&dbuf->time_index) / sizeof(uint64_t);
00432 for(i = 0; i < avail; i++) {
00433 ring_peek(&dbuf->time_index,(uint8_t *) &rtime,
00434 sizeof(uint64_t), i * sizeof(uint64_t));
00435 ring_peek(&dbuf->data_index,(uint8_t *) &size,
00436 sizeof(uint32_t), i * sizeof(uint32_t));
00437 printf("%d : %llu %u\n", i, rtime, size);
00438 }
00439 printf("Used: %d Free: %d data-free: %d\n", avail, 1000-avail, dbuf->size - dbuf->fill);
00440 }