License Public Domain
Lines 107
Keywords
Buffer (2) C# (7) .Net (8) Socket (3) Thread (4) VB.Net (5)
Included in these Libraries
Permissions
Group Owner: .Net
Viewable by Everyone
Editable by Spencer Ruport

Thread safe byte buffer queue Atom Feed 0

In Brief Byte buffer queues are extremely useful in socket applications. I use this one in a few the projects I've worked on.
# 's
  1public class BufferQueue
2{
3 private byte[] buff;
4 private int head, tail, size;
5 private volatile int count;
6 private Mutex appendmut, readmut, countmut;
7
8 // Constructor
9 public BufferQueue(int size)
10 {
11 appendmut = new Mutex();
12 readmut = new Mutex();
13 countmut = new Mutex();
14 buff = new byte[size];
15 this.size = size;
16 head = 0;
17 tail = 0;
18 count = 0;
19 }
20
21 // Get the number of bytes in the buffer
22 public int Count { get { return count; } }
23 // The maximum size of the buffer
24 public int Size { get { return size; } }
25
26 // Append bytes to the buffer
27 public void append(byte[] data) { if (data != null) append(data, 0, data.Length); }
28 public void append(byte[] data, int offset, int length)
29 {
30 if (data == null) return;
31 if (data.Length < offset + length) { throw new Exception("array index out of bounds. offset + length extends beyond the length of the array."); }
32
33 appendmut.WaitOne();
34 // We need to acquire the mutex so that this.tail doesn't change.
35 for (int i = 0; i < length; i++)
36 buff[(i + this.tail) % this.size] = data[i + offset];
37 this.tail = (length + this.tail) % this.size;
38 countmut.WaitOne();
39 // We need to acquire the mutex so that this.count doesn't change.
40 this.count = this.count + length;
41 if (this.count > this.size)
42 throw new Exception("Buffer overflow error.");
43 countmut.ReleaseMutex();
44 appendmut.ReleaseMutex();
45 }
46
47 // Read bytes from the buffer
48 public string read()
49 {
50 byte[] data = new byte[size];
51 read(data);
52 return System.Text.ASCIIEncoding.ASCII.GetString(data);
53 }
54 public int read(byte[] data) { if (data != null) return read(data, 0, data.Length); else return 0; }
55 public int read(byte[] data, int offset, int length)
56 {
57 if (data == null) return 0;
58 if (data.Length < offset + length) throw new Exception("array index out of bounds. offset + length extends beyond the length of the array.");
59
60 int readlength = 0;
61
62 // We need to acquire the mutex so that this.head doesn't change.
63 readmut.WaitOne();
64
65 for (int i = 0; i < length; i++)
66 {
67 if (i == count) break;
68 data[i + offset] = buff[(i + head) % this.size];
69 readlength++;
70 }
71 this.head = (readlength + this.head) % this.size;
72
73 // We need to acquire the mutex so that this.count doesn't change.
74 countmut.WaitOne();
75 this.count = this.count - readlength;
76 countmut.ReleaseMutex();
77 readmut.ReleaseMutex();
78 return readlength;
79 }
80
81 // Peek at the buffer
82 public string peek()
83 {
84 byte[] data = new byte[size];
85 peek(data);
86 return System.Text.ASCIIEncoding.ASCII.GetString(data);
87 }
88 public int peek(byte[] data) { if (data != null) return peek(data, 0, data.Length); else return 0; }
89 public int peek(byte[] data, int offset, int length)
90 {
91 if (data == null) return 0;
92 if (data.Length < offset + length) throw new Exception("array index out of bounds. offset + length extends beyond the length of the array.");
93
94 int readlength = 0;
95
96 // We need to acquire the mutex so that this.head doesn't change.
97 readmut.WaitOne();
98
99 for (int i = 0; i < length; i++)
100 {
101 if (i == count) break;
102 data[i + offset] = buff[(i + head) % this.size];
103 readlength++;
104 }
105
106 readmut.ReleaseMutex();
107 return readlength;
108 }
109
110 public void clear()
111 {
112 readmut.WaitOne();
113 appendmut.WaitOne();
114 countmut.WaitOne();
115 this.head = 0;
116 this.tail = 0;
117 this.count = 0;
118 countmut.ReleaseMutex();
119 appendmut.ReleaseMutex();
120 readmut.ReleaseMutex();
121 }
122}

Byte buffer queues are extremely useful in socket applications. I use this one in a few the projects I've worked on.

Comments

over 4 years ago (16 Nov 2011 at 06:47 AM) by victor_olvera
Hello Spencer. Would you show me a main program in C# and Java the that invokes your circular buffer and uses it? Do you have such code in C++? Thanks.