1 // (c) 2019, David Freese, W1HKJ
2 
3 #ifndef __FIFO_H__
4 #define __FIFO_H__
5 
6 #include "pj_struc.h"
7 
8 // a simple FIFO buffer
9 template <class Type>
10 class FIFO {
11 public:
12 	size_t Len;
13 private:
14 	size_t ReadPtr;
15 	size_t WritePtr;
16 	Type *Data;
17 
18 public:
FIFO()19 	FIFO() { Init(); }
~FIFO()20 	~FIFO() { delete [] Data; }
21 
Init(void)22 	void Init(void) { Data = 0; Len = 0; }
23 
Free(void)24 	void Free(void) { delete [] Data; Data = 0; Len = 0; }
25 
Reset(void)26 	void Reset(void) {
27 		ReadPtr = WritePtr = 0;
28 	}
29 
Clear(void)30 	void Clear(void) {
31 		ReadPtr = WritePtr;
32 	}
33 
Preset(void)34 	int Preset(void) {
35 		if (ReallocArray(&Data, Len) < 0)
36 			return -1;
37 		Reset();
38 		return 0;
39 	}
40 
41 	// increment the pointer (with wrapping around)
42 	void IncrPtr(size_t &Ptr, size_t Step = 1) {
43 		Ptr += Step;
44 		if (Ptr >= Len)
45 			Ptr-=Len;
46 	}
47 
48 	// FIFO is full ?
Full(void)49 	int Full(void) {
50 		size_t Ptr = WritePtr;
51 		IncrPtr(Ptr);
52 		return (Ptr == ReadPtr);
53 	}
54 
55 	// FIFO is empty ?
Empty(void)56 	int Empty(void) {
57 		return (ReadPtr == WritePtr);
58 	}
59 
60 	// how many elements we can write = space left in the FIFO
WriteReady(void)61 	size_t WriteReady(void) {
62 		int Ready = ReadPtr - WritePtr;
63 		if (Ready <= 0) Ready += Len;
64 		return Ready - 1;
65 	}
66 
67 	// how many elements we can read = space taken in the FIFO
ReadReady(void)68 	size_t ReadReady(void) {
69 		int Ready = WritePtr - ReadPtr;
70 		if (Ready < 0)
71 			Ready += Len;
72 		return Ready;
73 	}
74 
75 	// write a new element
Write(Type & NewData)76 	int Write(Type &NewData) {
77 		size_t Ptr = WritePtr;
78 		IncrPtr(Ptr);
79 		if (Ptr == ReadPtr)
80 			return 0;
81 		Data[WritePtr] = NewData;
82 		WritePtr = Ptr;
83 		return 1;
84 	}
85 
86 	// read the oldest element
Read(Type & OldData)87 	int Read(Type &OldData) {
88 		if (ReadPtr == WritePtr)
89 			return 0;
90 		OldData = Data[ReadPtr];
91 		IncrPtr(ReadPtr);
92 		return 1;
93 	}
94 
95 	// lookup data in the FIFO but without taking them out
96 	int Lookup(Type &OldData, size_t Offset = 0) {
97 		size_t Ready = ReadReady();
98 		if (Offset >= Ready)
99 			return 0;
100 		size_t Ptr = ReadPtr;
101 		IncrPtr(Ptr,Offset);
102 		OldData = Data[Ptr];
103 		return 1;
104 	}
105 };
106 
107 #endif // of __FIFO_H__
108