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