urg_ring_buffer.c
Go to the documentation of this file.
1 
10 #include "urg_c/urg_ring_buffer.h"
11 
12 
13 void ring_initialize(ring_buffer_t *ring, char *buffer, const int shift_length)
14 {
15  ring->buffer = buffer;
16  ring->buffer_size = 1 << shift_length;
17  ring_clear(ring);
18 }
19 
20 
22 {
23  ring->first = 0;
24  ring->last = 0;
25 }
26 
27 
28 int ring_size(const ring_buffer_t *ring)
29 {
30  int first = ring->first;
31  int last = ring->last;
32 
33  return (last >= first) ? last - first : ring->buffer_size - (first - last);
34 }
35 
36 
37 int ring_capacity(const ring_buffer_t *ring)
38 {
39  return ring->buffer_size - 1;
40 }
41 
42 
43 static void byte_move(char *dest, const char *src, int n)
44 {
45  const char *last_p = dest + n;
46  while (dest < last_p) {
47  *dest++ = *src++;
48  }
49 }
50 
51 
52 int ring_write(ring_buffer_t *ring, const char *data, int size)
53 {
54  int free_size = ring_capacity(ring) - ring_size(ring);
55  int push_size = (size > free_size) ? free_size : size;
56 
57  // データ配置
58  if (ring->first <= ring->last) {
59  // last から buffer_size 終端までに配置
60  int left_size = 0;
61  int to_end = ring->buffer_size - ring->last;
62  int move_size = (to_end > push_size) ? push_size : to_end;
63 
64  byte_move(&ring->buffer[ring->last], data, move_size);
65  ring->last += move_size;
66  ring->last &= (ring->buffer_size -1);
67 
68  left_size = push_size - move_size;
69  if (left_size > 0) {
70  // 0 から first の前までを配置
71  byte_move(ring->buffer, &data[move_size], left_size);
72  ring->last = left_size;
73  }
74  } else {
75  // last から first の前まで配置
76  byte_move(&ring->buffer[ring->last], data, size);
77  ring->last += push_size;
78  }
79  return push_size;
80 }
81 
82 
83 int ring_read(ring_buffer_t *ring, char *buffer, int size)
84 {
85  // データ取得
86  int now_size = ring_size(ring);
87  int pop_size = (size > now_size) ? now_size : size;
88 
89  if (ring->first <= ring->last) {
90  byte_move(buffer, &ring->buffer[ring->first], pop_size);
91  ring->first += pop_size;
92 
93  } else {
94  // first から buffer_size 終端までを配置
95  int left_size = 0;
96  int to_end = ring->buffer_size - ring->first;
97  int move_size = (to_end > pop_size) ? pop_size : to_end;
98  byte_move(buffer, &ring->buffer[ring->first], move_size);
99 
100  ring->first += move_size;
101  ring->first &= (ring->buffer_size -1);
102 
103  left_size = pop_size - move_size;
104  if (left_size > 0) {
105  // 0 から last の前までを配置
106  byte_move(&buffer[move_size], ring->buffer, left_size);
107 
108  ring->first = left_size;
109  }
110  }
111  return pop_size;
112 }
int last
バッファの最終位置
int first
バッファの先頭位置
int ring_size(const ring_buffer_t *ring)
格納データ数を返す
リングバッファ
int ring_capacity(const ring_buffer_t *ring)
最大の格納データ数を返す
int buffer_size
バッファサイズ
int ring_write(ring_buffer_t *ring, const char *data, int size)
データの格納
int ring_read(ring_buffer_t *ring, char *buffer, int size)
データの取り出し
char * buffer
バッファへのポインタ
リングバッファの管理情報
void ring_initialize(ring_buffer_t *ring, char *buffer, const int shift_length)
初期化
void ring_clear(ring_buffer_t *ring)
リングバッファのクリア
static void byte_move(char *dest, const char *src, int n)


urg_c
Author(s): Satofumi Kamimura , Katsumi Kimoto, Adrian Boeing
autogenerated on Wed Jun 10 2020 03:48:10