1 //
2 //  circularQueue.h
3 //
4 //  Author(s):
5 //	Robert Stiles, KK5VD, Copyright (C) 2013, 2015
6 //	Dave Freese, W1HKJ, Copyright (C) 2013
7 //
8 // This file is part of FLAMP.
9 //
10 // This is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // This software is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 //
23 
24 #ifndef flamp_circular_queue_h
25 #define flamp_circular_queue_h
26 
27 #include <pthread.h>
28 #include <string>
29 #include <exception>
30 #include <cstring>
31 #include <time.h>
32 
33 #include "util.h"
34 #include "crc16.h"
35 
36 #define CQUE_HOLD   1
37 #define CQUE_RESUME 0
38 #define CQUE_SLEEP_TIME 10
39 
40 #define TIME_SET 1
41 #define TIME_COUNT 2
42 
43 class CircQueException : public std::exception
44 {
45 public:
err(err_)46 	CircQueException(int err_ = 0)	 : err(err_), msg(err_to_str(err_)) { }
CircQueException(const char * msg_)47 	CircQueException(const char* msg_) : err(1),	msg(msg_)			 { }
CircQueException(int err_,const std::string & prefix)48 	CircQueException(int err_, const std::string& prefix)
49 	: err(err_), msg(std::string(prefix).append(": ").append(err_to_str(err_))) { }
~CircQueException()50 	virtual ~CircQueException() throw() { }
what(void)51 	const char*	 what(void) const throw() { return msg.c_str(); }
error(void)52 	int			 error(void) const { return err; }
53 
54 protected:
err_to_str(int e)55 	const char* err_to_str(int e) {
56 		return strerror(e);
57 	}
58 	int			 err;
59 	std::string	 msg;
60 };
61 
62 
63 class Circular_queue {
64 private:
65 
66 	pthread_t thread;
67 	pthread_mutex_t mutex;
68 	pthread_cond_t  condition;
69 
70 	char *buffer;
71 
72 	int buffer_size;
73 	int bufferCount;
74 	int exit_thread;
75 	int index_mask;
76 	int read_index;
77 	int stalled;
78 	int write_index;
79 
80 	Ccrc16 crcValidate;
81 
82 public:
83 
84 	int inhibitDataOut;
85 	int thread_running;
86 
87 	int  (* matchFound)(void *);
88 	int  (* readData)(void *);
89 	void * (* queueParser)(void *);
90 
91 public:
92 
93 	Circular_queue(void);
94 	Circular_queue(int po2, int (*_matchFound)(void *),	\
95 				   int (*_readDataFrom)(void *), void * (*_queueParser)(void *));
96 	~Circular_queue();
97 
98 public:
99 
100 	bool timeOut(time_t &timeValue, time_t seconds, int attribute);
101 
102 	int  adjustReadQueIndex(int count);
103 	int  lookAhead(char *_buffer, int _size);
104 	int  lookAheadCRC(char *_buffer, int _size, unsigned int *crcVal, int *reset);
105 	int  lookAheadForCharacter(char character, int *found);
106 	int  lookAheadToTerminator(char *_buffer, char terminator, int maxLen);
queueStalled()107 	int  queueStalled() { return stalled; }
108 	int  readQueData(int buffer_count);
thread_exit()109 	int  thread_exit() { return exit_thread; }
110 
111 	void addToQueue(char *_buffer, int _size);
112 	void addToQueueNullFiltered(char *_buffer, int _size);
113 	void resumeQueue();
114 	void signal(void);
115 	void sleep(int seconds, int milliseconds);
116 	void startDataOut();
117 	void stopDataOut();
118 	void stopQueue();
119 
milliSleep(int milliseconds)120 	void milliSleep(int milliseconds)
121 	{
122 		sleep(0, milliseconds);
123 	}
124 
125 	void setUp(int po2, int (*_matchFound)(void *),	\
126 			   int (*_readDataFrom)(void *), void * (*_queueParser)(void *));
127 };
128 
129 
130 #endif // flamp_circular_queue_h
131