/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk

« back to all changes in this revision

Viewing changes to libssts/RingBuffer.c

  • Committer: Gustav Hartvigsson
  • Date: 2016-08-31 18:56:59 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20160831185659-vj3kpiv6sadtfjbw
* Started work on the ring buffer, still untested and may contain
logical errors.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include "RingBuffer.h"
2
2
 
3
3
 
 
4
#define err_on_full(S) {\
 
5
  if (self->len >= S->size) {\
 
6
    *err = TRUE;\
 
7
    s_err_print ("Buffer full. Needs to be reallocated.\n"\
 
8
                 "    (This is not done automatically. Returning.)");\
 
9
    return;\
 
10
  }\
 
11
}
 
12
 
 
13
#define err_seems_full() {\
 
14
  s_err_print ("Array seems to be full... Returning.");\
 
15
  *err = TRUE;\
 
16
  return;\
 
17
}
 
18
 
 
19
#define nothing_to_ret() {\
 
20
  s_warn_print ("Ring buffer is empty, nothing to return");\
 
21
  *err = TRUE;\
 
22
  return 0;\
 
23
}
 
24
 
4
25
struct SRingBuffer {
5
 
  size_t len;
 
26
  size_t size;
6
27
  size_t start;
7
28
  size_t end;
 
29
  size_t len;
8
30
  
9
31
  sbyte * array;
10
32
}
15
37
  SRingBuffer * self = s_malloc (sizeof (SRingBuffer));
16
38
  self->array = s_calloc (len, size_t (sbyte));
17
39
  
18
 
  self->len = len;
 
40
  self->size = size;
19
41
  self->start = 0;
20
42
  self->end = 0;
 
43
  self->len = 0;
21
44
  
22
45
  return self;
23
46
}
31
54
 
32
55
sboolean
33
56
s_ring_buffer_is_empty (SRingBuffer * self) {
34
 
  return (self->start == self->end);
 
57
  return ((self->start == self->end) && self->len == 0 );
35
58
}
36
59
 
37
60
void
38
61
s_ring_buffer_push (SRingBuffer * self,
39
 
                    sbyte data);
 
62
                    sbyte data,
 
63
                    sboolean * err) {
 
64
  *err = FALSE;
 
65
  err_on_full (self);
 
66
  
 
67
  if (self->end <= self->size) {
 
68
    self->end = self->end + 1;
 
69
  } else if (self->end == self->size) {
 
70
    if (self->start == 0) {
 
71
      err_seems_full ();
 
72
    } else {
 
73
      self->end = 0;
 
74
    }
 
75
  } else if (self->end < self->start) {
 
76
    if ((self->end + 1) == self->start ) {
 
77
      err_seems_full ();
 
78
    } else {
 
79
      self->end = self->end + 1;
 
80
    }
 
81
  } else {
 
82
    s_err_print ("Reaching a place that should not be reached. Returning");
 
83
    *err = TRUE;
 
84
    return;
 
85
  }
 
86
  self->len = self->len + 1;
 
87
  self->array[self->end] = data;
 
88
}
40
89
 
41
90
 
42
91
void
43
 
s_ring_buffer_push_back (SRingBuffer * self,
44
 
                         sbyte data);
45
 
 
46
 
 
47
 
sbyte
48
 
s_ring_buffer_pop (SRingBuffer * self);
49
 
 
50
 
 
51
 
sbyte
52
 
s_ring_buffer_pop_back (SRingBuffer * self);
53
 
 
 
92
s_ring_buffer_push_front (SRingBuffer * self,
 
93
                          sbyte data,
 
94
                          sboolean * err) {
 
95
  *err = FALSE;
 
96
  err_on_full (self);
 
97
  
 
98
  if ((self->start - 1) < 0) {
 
99
    if (self->end == self->size) {
 
100
      err_seems_full ();
 
101
    } else {
 
102
      self->start = self->size;
 
103
    }
 
104
  } else if (self->start <= self-end) {
 
105
    self->start = self->start - 1;
 
106
  } else  if (self->start > self->end) {
 
107
    if ((self->start - 1) == self->end ) {
 
108
      err_seems_full ();
 
109
    } else {
 
110
      self->start = self->start - 1;
 
111
    }
 
112
  } else {
 
113
    s_err_print ("Reaching a place that should not be reached. Returning");
 
114
    *err = TRUE;
 
115
    return;
 
116
  }
 
117
  self->len = self->len + 1;
 
118
  self->array[self->start] = data;
 
119
}
 
120
 
 
121
/*
 
122
 * When doing poping we do not override the data in the buffer.
 
123
 * This to alleviate some prosessing time form usage of the data structure.
 
124
 */
 
125
sbyte
 
126
s_ring_buffer_pop (SRingBuffer * self, sboolean * err) {
 
127
  if (s_ring_buffer_is_empty (self)) {
 
128
    nothing_to_ret ();
 
129
  }
 
130
  *err = FALSE;
 
131
  sbyte ret_val = self->array[self->end];
 
132
  self->len = self->len - 1;
 
133
  self->end = self->end - 1;
 
134
  return ret_val;
 
135
}
 
136
 
 
137
 
 
138
sbyte
 
139
s_ring_buffer_pop_front (SRingBuffer * self, sboolean * err) {
 
140
  if (s_ring_buffer_is_empty (self)) {
 
141
    nothing_to_ret ();
 
142
  }
 
143
  *err = FALSE;
 
144
  sbyte ret_val = self->array[self->start];
 
145
  self->start = self->start + 1;
 
146
  self->len = self->len - 1;
 
147
  return ret_val;
 
148
}
 
149
 
 
150
 
 
151
sbyte
 
152
s_ring_buffer_peek (SRingBuffer * self, sboolean * err) {
 
153
  if (s_ring_buffer_is_empty (self)) {
 
154
    nothing_to_ret ();
 
155
  }
 
156
  *err = FALSE;
 
157
  return self->array[self->end];
 
158
}
 
159
 
 
160
sbyte
 
161
s_ring_buffer_peek_front (SRingBuffer * self, sboolean * err) {
 
162
  if (s_ring_buffer_is_empty (self)) {
 
163
    nothing_to_ret ();
 
164
  }
 
165
  *err = FALSE;
 
166
  return self->array[self->start];
 
167
}
54
168
 
55
169
void
56
170
s_ring_buffer_realloc (SRingBuffer * self,
57
 
                       size_t len);
58
 
 
59
 
 
60
 
size_t
61
 
s_ring_buffer_len (SRingBuffer * self);
62
 
 
63
 
 
64
 
size_t
65
 
s_ring_buffer_size (SRingBuffer * self);
 
171
                       size_t len,
 
172
                       sboolean * err);
 
173
 
 
174
 
 
175
size_t
 
176
s_ring_buffer_len (SRingBuffer * self) {
 
177
  return self->len;
 
178
}
 
179
 
 
180
 
 
181
size_t
 
182
s_ring_buffer_size (SRingBuffer * self) {
 
183
  return self->size;
 
184
}
66
185
 
67
186
 
68
187
void
69
188
s_ring_buffer_for_each (SRingBuffer * self,
70
189
                        ForEachFunc func,
71
 
                        spointer user_data);
 
190
                        spointer user_data,
 
191
                        sboolean * err);
72
192