Home | History | Annotate | Download | only in src
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2015 Google Inc.
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 #include <base/logging.h>
     20 #include <stdlib.h>
     21 
     22 #include "osi/include/allocator.h"
     23 #include "osi/include/ringbuffer.h"
     24 
     25 struct ringbuffer_t {
     26   size_t total;
     27   size_t available;
     28   uint8_t* base;
     29   uint8_t* head;
     30   uint8_t* tail;
     31 };
     32 
     33 ringbuffer_t* ringbuffer_init(const size_t size) {
     34   ringbuffer_t* p =
     35       static_cast<ringbuffer_t*>(osi_calloc(sizeof(ringbuffer_t)));
     36 
     37   p->base = static_cast<uint8_t*>(osi_calloc(size));
     38   p->head = p->tail = p->base;
     39   p->total = p->available = size;
     40 
     41   return p;
     42 }
     43 
     44 void ringbuffer_free(ringbuffer_t* rb) {
     45   if (rb != NULL) osi_free(rb->base);
     46   osi_free(rb);
     47 }
     48 
     49 size_t ringbuffer_available(const ringbuffer_t* rb) {
     50   CHECK(rb);
     51   return rb->available;
     52 }
     53 
     54 size_t ringbuffer_size(const ringbuffer_t* rb) {
     55   CHECK(rb);
     56   return rb->total - rb->available;
     57 }
     58 
     59 size_t ringbuffer_insert(ringbuffer_t* rb, const uint8_t* p, size_t length) {
     60   CHECK(rb);
     61   CHECK(p);
     62 
     63   if (length > ringbuffer_available(rb)) length = ringbuffer_available(rb);
     64 
     65   for (size_t i = 0; i != length; ++i) {
     66     *rb->tail++ = *p++;
     67     if (rb->tail >= (rb->base + rb->total)) rb->tail = rb->base;
     68   }
     69 
     70   rb->available -= length;
     71   return length;
     72 }
     73 
     74 size_t ringbuffer_delete(ringbuffer_t* rb, size_t length) {
     75   CHECK(rb);
     76 
     77   if (length > ringbuffer_size(rb)) length = ringbuffer_size(rb);
     78 
     79   rb->head += length;
     80   if (rb->head >= (rb->base + rb->total)) rb->head -= rb->total;
     81 
     82   rb->available += length;
     83   return length;
     84 }
     85 
     86 size_t ringbuffer_peek(const ringbuffer_t* rb, off_t offset, uint8_t* p,
     87                        size_t length) {
     88   CHECK(rb);
     89   CHECK(p);
     90   CHECK(offset >= 0);
     91   CHECK((size_t)offset <= ringbuffer_size(rb));
     92 
     93   uint8_t* b = ((rb->head - rb->base + offset) % rb->total) + rb->base;
     94   const size_t bytes_to_copy = (offset + length > ringbuffer_size(rb))
     95                                    ? ringbuffer_size(rb) - offset
     96                                    : length;
     97 
     98   for (size_t copied = 0; copied < bytes_to_copy; ++copied) {
     99     *p++ = *b++;
    100     if (b >= (rb->base + rb->total)) b = rb->base;
    101   }
    102 
    103   return bytes_to_copy;
    104 }
    105 
    106 size_t ringbuffer_pop(ringbuffer_t* rb, uint8_t* p, size_t length) {
    107   CHECK(rb);
    108   CHECK(p);
    109 
    110   const size_t copied = ringbuffer_peek(rb, 0, p, length);
    111   rb->head += copied;
    112   if (rb->head >= (rb->base + rb->total)) rb->head -= rb->total;
    113 
    114   rb->available += copied;
    115   return copied;
    116 }
    117