/simpletypesystem/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/simpletypesystem/trunk
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
1
#include "RingBuffer.h"
2
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
3
/* These are just to reduce code redundancy.
4
 */
5
#define err_on_full(S, E) {\
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
6
  if (self->len >= S->size) {\
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
7
    E = TRUE;\
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
8
    s_err_print ("Buffer full. Needs to be reallocated.\n"\
9
                 "    (This is not done automatically. Returning.)");\
10
    return;\
11
  }\
12
}
13
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
14
#define err_seems_full(E) {\
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
15
  s_err_print ("Array seems to be full... Returning.");\
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
16
  E = TRUE;\
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
17
  return;\
18
}
19
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
20
#define err_on_empty(S, E) {\
21
  if (s_ring_buffer_is_empty (S)) {\
22
    s_warn_print ("Ring buffer is empty, nothing to return");\
23
    E = TRUE;\
24
    return 0;\
25
  }\
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
26
}
27
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
28
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
29
struct SRingBuffer {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
30
  size_t size;   /* The number of elemets in the array */
31
  size_t len;    /* The "length" of the buffered data */
32
  
33
  size_t start;  /* The index of the "first" element in the buffer in the array
34
                  */
35
  size_t end;    /* The index of the "last" element in the buffer in the array
36
                  */
37
  
38
  sbyte * array; /* The array that is used to implement the buffer */
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
39
}
40
41
42
SRingBuffer *
43
s_ring_buffer_new (size_t len) {
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
44
  SRingBuffer * self = s_malloc (sizeof (SRingBuffer));
45
  self->array = s_calloc (len, size_t (sbyte));
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
46
  
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
47
  self->size = size;
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
48
  self->start = 0;
49
  self->end = 0;
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
50
  self->len = 0;
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
51
  
52
  return self;
53
}
54
55
56
void
57
s_ring_buffer_free (SRingBuffer * self) {
121.1.3 by Gustav Hartvigsson
* Made the GC switchable at rutime (once) when compiled with S_USE_GC set.
58
  s_free (self->array);
59
  s_free (self);
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
60
}
61
62
sboolean
63
s_ring_buffer_is_empty (SRingBuffer * self) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
64
  /* If the data data two pointers are the same and the the length is zero,
65
   * the array is most likely empty... */
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
66
  return ((self->start == self->end) && self->len == 0 );
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
67
}
68
69
void
70
s_ring_buffer_push (SRingBuffer * self,
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
71
                    sbyte data,
72
                    sboolean * err) {
73
  *err = FALSE;
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
74
  err_on_full (self, *err);
75
  /* The buffer should only have three different states so this should do.
76
   *    (exept there are five states... Idiot...)
77
   *
78
   * The first state here is the normal state where the end is after the start.
79
   *
80
   * The second state is when the end pointer is at the end of the array.
81
   *   This has two substates, one where the array is full (the start pointer
82
   *   is zero and the end pointer points to the last lement of the array), the
83
   *   second state is when the stat pointer does not point to zero and is thus
84
   *   free to use so we set the end pointer to zero.
85
   *
86
   * The third state is when the array loops back on itself (see headerfile).
87
   *   This has two substates, one where the next element that should be set is
88
   *   actially the start element, thus the array is full. The second substates
89
   *   is when that is not true and we can use that slot.
90
   */
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
91
  if (self->end <= self->size) {
92
    self->end = self->end + 1;
93
  } else if (self->end == self->size) {
94
    if (self->start == 0) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
95
      err_seems_full (*err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
96
    } else {
97
      self->end = 0;
98
    }
99
  } else if (self->end < self->start) {
100
    if ((self->end + 1) == self->start ) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
101
      err_seems_full (*err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
102
    } else {
103
      self->end = self->end + 1;
104
    }
105
  } else {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
106
    /* This is an unknown state... some bad shit has gone down if you end up
107
    * here */
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
108
    s_err_print ("Reaching a place that should not be reached. Returning");
109
    *err = TRUE;
110
    return;
111
  }
112
  self->len = self->len + 1;
113
  self->array[self->end] = data;
114
}
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
115
116
117
void
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
118
s_ring_buffer_push_front (SRingBuffer * self,
119
                          sbyte data,
120
                          sboolean * err) {
121
  *err = FALSE;
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
122
  err_on_full (self, *err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
123
  
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
124
  /* This is pretty much the same as s_ring_buffer_push (), save for the states
125
   * beeing in a different order order is different to make it actially work as
126
   * inteded, I think.
127
   *
128
   * LOL.
129
   */
130
  if (self->start == 0) {
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
131
    if (self->end == self->size) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
132
      err_seems_full (*err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
133
    } else {
134
      self->start = self->size;
135
    }
136
  } else if (self->start <= self-end) {
137
    self->start = self->start - 1;
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
138
  } else if (self->start > self->end) {
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
139
    if ((self->start - 1) == self->end ) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
140
      err_seems_full (*err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
141
    } else {
142
      self->start = self->start - 1;
143
    }
144
  } else {
145
    s_err_print ("Reaching a place that should not be reached. Returning");
146
    *err = TRUE;
147
    return;
148
  }
149
  self->len = self->len + 1;
150
  self->array[self->start] = data;
151
}
152
153
/*
154
 * When doing poping we do not override the data in the buffer.
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
155
 * This to alleviate some processing time form usage of the data structure.
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
156
 */
157
sbyte
158
s_ring_buffer_pop (SRingBuffer * self, sboolean * err) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
159
  err_on_empty (self, *err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
160
  sbyte ret_val = self->array[self->end];
161
  self->len = self->len - 1;
162
  self->end = self->end - 1;
163
  return ret_val;
164
}
165
166
167
sbyte
168
s_ring_buffer_pop_front (SRingBuffer * self, sboolean * err) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
169
  err_on_empty (self, *err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
170
  *err = FALSE;
171
  sbyte ret_val = self->array[self->start];
172
  self->start = self->start + 1;
173
  self->len = self->len - 1;
174
  return ret_val;
175
}
176
177
178
sbyte
179
s_ring_buffer_peek (SRingBuffer * self, sboolean * err) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
180
  err_on_empty (self, *err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
181
  *err = FALSE;
182
  return self->array[self->end];
183
}
184
185
sbyte
186
s_ring_buffer_peek_front (SRingBuffer * self, sboolean * err) {
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
187
  err_on_empty (self, *err);
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
188
  *err = FALSE;
189
  return self->array[self->start];
190
}
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
191
192
void
193
s_ring_buffer_realloc (SRingBuffer * self,
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
194
                       size_t len,
195
                       sboolean * err);
196
197
198
size_t
199
s_ring_buffer_len (SRingBuffer * self) {
200
  return self->len;
201
}
202
203
204
size_t
205
s_ring_buffer_size (SRingBuffer * self) {
206
  return self->size;
207
}
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
208
209
210
void
211
s_ring_buffer_for_each (SRingBuffer * self,
212
                        ForEachFunc func,
139 by Gustav Hartvigsson
* Started work on the ring buffer, still untested and may contain
213
                        spointer user_data,
140 by Gustav Hartvigsson
* Added Better comments to SRingBuffer
214
                        sboolean * err) {
215
  err_on_empty (self, *err);
216
  
217
}
99 by Gustav Hartvigsson
* Working on RingBuffer and Stream.
218