Go to the documentation of this file.00001
00010 #include "urg_c/urg_ring_buffer.h"
00011
00012
00013 void ring_initialize(ring_buffer_t *ring, char *buffer, const int shift_length)
00014 {
00015 ring->buffer = buffer;
00016 ring->buffer_size = 1 << shift_length;
00017 ring_clear(ring);
00018 }
00019
00020
00021 void ring_clear(ring_buffer_t *ring)
00022 {
00023 ring->first = 0;
00024 ring->last = 0;
00025 }
00026
00027
00028 int ring_size(const ring_buffer_t *ring)
00029 {
00030 int first = ring->first;
00031 int last = ring->last;
00032
00033 return (last >= first) ? last - first : ring->buffer_size - (first - last);
00034 }
00035
00036
00037 int ring_capacity(const ring_buffer_t *ring)
00038 {
00039 return ring->buffer_size - 1;
00040 }
00041
00042
00043 static void byte_move(char *dest, const char *src, int n)
00044 {
00045 const char *last_p = dest + n;
00046 while (dest < last_p) {
00047 *dest++ = *src++;
00048 }
00049 }
00050
00051
00052 int ring_write(ring_buffer_t *ring, const char *data, int size)
00053 {
00054 int free_size = ring_capacity(ring) - ring_size(ring);
00055 int push_size = (size > free_size) ? free_size : size;
00056
00057
00058 if (ring->first <= ring->last) {
00059
00060 int left_size = 0;
00061 int to_end = ring->buffer_size - ring->last;
00062 int move_size = (to_end > push_size) ? push_size : to_end;
00063
00064 byte_move(&ring->buffer[ring->last], data, move_size);
00065 ring->last += move_size;
00066 ring->last &= (ring->buffer_size -1);
00067
00068 left_size = push_size - move_size;
00069 if (left_size > 0) {
00070
00071 byte_move(ring->buffer, &data[move_size], left_size);
00072 ring->last = left_size;
00073 }
00074 } else {
00075
00076 byte_move(&ring->buffer[ring->last], data, size);
00077 ring->last += push_size;
00078 }
00079 return push_size;
00080 }
00081
00082
00083 int ring_read(ring_buffer_t *ring, char *buffer, int size)
00084 {
00085
00086 int now_size = ring_size(ring);
00087 int pop_size = (size > now_size) ? now_size : size;
00088
00089 if (ring->first <= ring->last) {
00090 byte_move(buffer, &ring->buffer[ring->first], pop_size);
00091 ring->first += pop_size;
00092
00093 } else {
00094
00095 int left_size = 0;
00096 int to_end = ring->buffer_size - ring->first;
00097 int move_size = (to_end > pop_size) ? pop_size : to_end;
00098 byte_move(buffer, &ring->buffer[ring->first], move_size);
00099
00100 ring->first += move_size;
00101 ring->first &= (ring->buffer_size -1);
00102
00103 left_size = pop_size - move_size;
00104 if (left_size > 0) {
00105
00106 byte_move(&buffer[move_size], ring->buffer, left_size);
00107
00108 ring->first = left_size;
00109 }
00110 }
00111 return pop_size;
00112 }