1/*
2 * Copyright 2008-2013, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef CIRCULAR_BUFFER_H
6#define CIRCULAR_BUFFER_H
7
8
9#include <stdlib.h>
10
11#include <OS.h>
12
13
14template<typename Type>
15class CircularBuffer {
16public:
17	CircularBuffer(size_t size)
18		:
19		fSize(0),
20		fBuffer(NULL)
21	{
22		SetSize(size);
23	}
24
25	~CircularBuffer()
26	{
27		free(fBuffer);
28	}
29
30	status_t InitCheck() const
31	{
32		return fBuffer != NULL ? B_OK : B_NO_MEMORY;
33	}
34
35	status_t SetSize(size_t size)
36	{
37		MakeEmpty();
38
39		if (fSize == size)
40			return B_OK;
41
42		fSize = size;
43		fBuffer = (Type*)malloc(fSize * sizeof(Type));
44		if (fBuffer == NULL) {
45			fSize = 0;
46			return B_NO_MEMORY;
47		}
48
49		return B_OK;
50	}
51
52	void MakeEmpty()
53	{
54		fIn = 0;
55		fFirst = 0;
56	}
57
58	bool IsEmpty() const
59	{
60		return fIn == 0;
61	}
62
63	int32 CountItems() const
64	{
65		return fIn;
66	}
67
68	Type* ItemAt(int32 index) const
69	{
70		if (index >= (int32)fIn || index < 0 || fBuffer == NULL)
71			return NULL;
72
73		return &fBuffer[(fFirst + index) % fSize];
74	}
75
76	void AddItem(const Type& item)
77	{
78		uint32 index;
79		if (fIn < fSize)
80			index = fFirst + fIn++;
81		else
82			index = fFirst++;
83
84		if (fBuffer != NULL)
85			fBuffer[index % fSize] = item;
86	}
87
88	size_t Size() const
89	{
90		return fSize;
91	}
92
93private:
94	uint32		fFirst;
95	uint32		fIn;
96	uint32		fSize;
97	Type*		fBuffer;
98};
99
100
101#endif	// CIRCULAR_BUFFER_H
102