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
Hide
Easily highlight source code for your blog with our Syntax Highlighter. Join Siafoo Now or Learn More

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 8 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.