urg_ring_buffer.c
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         // last から buffer_size 終端までに配置
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             // 0 から first の前までを配置
00071             byte_move(ring->buffer, &data[move_size], left_size);
00072             ring->last = left_size;
00073         }
00074     } else {
00075         // last から first の前まで配置
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         // first から buffer_size 終端までを配置
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             // 0 から last の前までを配置
00106             byte_move(&buffer[move_size], ring->buffer, left_size);
00107 
00108             ring->first = left_size;
00109         }
00110     }
00111     return pop_size;
00112 }


urg_c
Author(s): Satofumi Kamimura , Katsumi Kimoto, Adrian Boeing
autogenerated on Wed Aug 26 2015 16:38:27