dodo  0.0.1
A C++ library to create containerized Linux services
socketreadbuffer.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the dodo library (https://github.com/jmspit/dodo).
3  * Copyright (c) 2019 Jan-Marten Spit.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 3.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /**
19  * @file socketreadbuffer.hpp
20  * Defines the dodo::network::SocketReadBuffer class.
21  */
22 
23 #ifndef dodo_network_socketreadbuffer_hpp
24 #define dodo_network_socketreadbuffer_hpp
25 
26 #include <network/basesocket.hpp>
27 
28 namespace dodo {
29 
30  namespace network {
31 
32  /**
33  * Interface to read individual bytes whilst the implementation
34  * can read from an actual source (such as a network buffer)
35  * in larger chunks, reducing the number of required system calls. This is covenient
36  * when implementing protocols that need be char (byte) scanned to parse.
37  *
38  * Note that this interface requires a source that blocks on read. A call to next()
39  * will advance the current byte, but this in turn will call underflow, which in turn might do
40  * a read if it reached the end of available bytes.
41  *
42  * @see SocketReadBuffer and FileReadBuffer - both concrete implementations.
43  */
45  public:
46 
47  VirtualReadBuffer() : buffer_(NULL), bufsize_(0), underflows_(0) {};
48 
49  /**
50  * Get the current char from VirtualReadBuffer.
51  * @return The current character read.
52  * @see next()
53  */
54  virtual char get() const = 0;
55 
56  /**
57  * Move to the next char from the VirtualReadBuffer. Note that call will return a SystemError::ecEAGAIN
58  * if there is no more data (received within the prevailing timeout).
59  * @return SystemError::ecOK and c is valid, or an SystemError.
60  */
61  virtual common::SystemError next() = 0 ;
62 
63  /**
64  * If the buffer_ underflows, the buffer_ must be reset refilledwith new data from the source.
65  * @return Systemerror::ecOK on succes.
66  */
67  virtual common::SystemError underflow() = 0;
68 
69  /**
70  * Return the number of times underflow() was invoked.
71  * @return The number of times underflow() was invoked.
72  */
73  size_t getUnderflowCount() const { return underflows_; }
74 
75  protected:
76 
77  /**
78  * The buffer.
79  * @see bufsize_
80  */
81  char* buffer_;
82 
83  /**
84  * The size of buffer_.
85  */
86  ssize_t bufsize_;
87 
88  /**
89  * The number underflow() invocations.
90  */
91  size_t underflows_;
92 
93  };
94 
95  /**
96  * SocketReadBuffer is a VirtualReadBuffer that reads from the BaseSocket
97  * in chunks internally. Note that the BaseSocket should be in blocking mode.
98  */
100  public:
101 
102  /**
103  * Construct a SocketReadBuffer. If BaseSocket::getBlocking() is false, an exception is thrown.
104  * @param socket The blocking BaseSocket to read from.
105  * @param bufsize The buffer size to use
106  */
107  explicit SocketReadBuffer( BaseSocket* socket, size_t bufsize = 8192 );
108 
109  /**
110  * Destruct the SocketReadBuffer, de-allocate the internal buffer.
111  * Any bytes buffered will be lost.
112  */
113  virtual ~SocketReadBuffer();
114 
115  virtual char get() const;
116 
117  virtual common::SystemError next();
118 
119  /**
120  * If the buffer_ is fully read. eset and read new data from the socket.
121  * @return Systemerror::ecOK on succes.
122  */
123  virtual common::SystemError underflow();
124 
125  protected:
126 
127  /**
128  * The associated network::BaseSocket*.
129  */
131 
132  /**
133  * The current index of get(char &c) in buffer_.
134  */
135  ssize_t idx_;
136 
137  /**
138  * The number of chars received in the last underflow().
139  */
140  ssize_t received_;
141 
142  };
143 
144  /**
145  * File-based VirtualReadBuffer, conventient for testing purposes as
146  * parsers can be tested against file instead of network sources.
147  */
149  public:
150 
151  /**
152  * Construct a FileReadBuffer.
153  * @param filename The file to read.
154  * @param bufsize The buffer size to use
155  */
156  explicit FileReadBuffer( std::string filename, size_t bufsize = 8192 );
157 
158  virtual ~FileReadBuffer();
159 
160  virtual char get() const;
161 
162  virtual common::SystemError next();
163 
164  virtual common::SystemError underflow();
165 
166  protected:
167 
168  /** The file handle. */
169  FILE *file_;
170 
171  /** The index into the buffer. */
172  size_t idx_;
173 
174  /**
175  * The number of chars read in buffer_
176  */
177  size_t read_;
178 
179  };
180 
181  /**
182  * String based VirtualReadBuffer, conventient for testing purposes as
183  * parsers can be tested against strings instead of network sources.
184  */
186  public:
187 
188  /**
189  * Construct a FileReadBuffer.
190  * @param data The string data
191  */
192  explicit StringReadBuffer( const std::string &data ) { data_ = data; idx_ = 0; }
193 
194  virtual ~StringReadBuffer() {};
195 
196  virtual char get() const { return data_.at(idx_); }
197 
198  virtual common::SystemError next() { if ( idx_ >= data_.length() -1 ) return common::SystemError::ecEAGAIN; else { idx_++; return common::SystemError::ecOK; } };
199 
200  protected:
201 
203 
204  /**
205  * The string data backing the buffer.
206  */
207  std::string data_;
208 
209  /**
210  * The current index into the string buffer.
211  */
212  size_t idx_;
213 
214  };
215 
216  }
217 
218 }
219 
220 #endif
dodo::network::SocketReadBuffer::underflow
virtual common::SystemError underflow()
If the buffer_ is fully read.
Definition: socketreadbuffer.cpp:44
dodo::network::SocketReadBuffer
SocketReadBuffer is a VirtualReadBuffer that reads from the BaseSocket in chunks internally.
Definition: socketreadbuffer.hpp:99
dodo::network::SocketReadBuffer::idx_
ssize_t idx_
The current index of get(char &c) in buffer_.
Definition: socketreadbuffer.hpp:135
dodo::network::FileReadBuffer::underflow
virtual common::SystemError underflow()
If the buffer_ underflows, the buffer_ must be reset refilledwith new data from the source.
Definition: socketreadbuffer.cpp:79
dodo::network::StringReadBuffer::underflow
virtual common::SystemError underflow()
If the buffer_ underflows, the buffer_ must be reset refilledwith new data from the source.
Definition: socketreadbuffer.hpp:202
dodo::network::FileReadBuffer::get
virtual char get() const
Get the current char from VirtualReadBuffer.
Definition: socketreadbuffer.cpp:91
dodo::network::VirtualReadBuffer
Interface to read individual bytes whilst the implementation can read from an actual source (such as ...
Definition: socketreadbuffer.hpp:44
dodo::network::VirtualReadBuffer::buffer_
char * buffer_
The buffer.
Definition: socketreadbuffer.hpp:81
dodo::network::FileReadBuffer::FileReadBuffer
FileReadBuffer(std::string filename, size_t bufsize=8192)
Construct a FileReadBuffer.
Definition: socketreadbuffer.cpp:63
dodo::network::VirtualReadBuffer::next
virtual common::SystemError next()=0
Move to the next char from the VirtualReadBuffer.
dodo::network::FileReadBuffer
File-based VirtualReadBuffer, conventient for testing purposes as parsers can be tested against file ...
Definition: socketreadbuffer.hpp:148
dodo::network::VirtualReadBuffer::get
virtual char get() const =0
Get the current char from VirtualReadBuffer.
dodo::common::SystemError::ecEAGAIN
@ ecEAGAIN
11 Try again
Definition: systemerror.hpp:71
dodo::network::SocketReadBuffer::~SocketReadBuffer
virtual ~SocketReadBuffer()
Destruct the SocketReadBuffer, de-allocate the internal buffer.
Definition: socketreadbuffer.cpp:40
dodo::network::StringReadBuffer::next
virtual common::SystemError next()
Move to the next char from the VirtualReadBuffer.
Definition: socketreadbuffer.hpp:198
dodo::network::StringReadBuffer::StringReadBuffer
StringReadBuffer(const std::string &data)
Construct a FileReadBuffer.
Definition: socketreadbuffer.hpp:192
dodo::network::VirtualReadBuffer::underflows_
size_t underflows_
The number underflow() invocations.
Definition: socketreadbuffer.hpp:91
dodo
A C++ platform interface to lean Linux services tailored for containerized deployment.
Definition: application.hpp:29
dodo::network::FileReadBuffer::read_
size_t read_
The number of chars read in buffer_.
Definition: socketreadbuffer.hpp:177
dodo::network::StringReadBuffer::get
virtual char get() const
Get the current char from VirtualReadBuffer.
Definition: socketreadbuffer.hpp:196
dodo::network::SocketReadBuffer::get
virtual char get() const
Get the current char from VirtualReadBuffer.
Definition: socketreadbuffer.cpp:54
dodo::network::SocketReadBuffer::socket_
BaseSocket * socket_
The associated network::BaseSocket*.
Definition: socketreadbuffer.hpp:130
dodo::network::StringReadBuffer::idx_
size_t idx_
The current index into the string buffer.
Definition: socketreadbuffer.hpp:212
dodo::network::FileReadBuffer::next
virtual common::SystemError next()
Move to the next char from the VirtualReadBuffer.
Definition: socketreadbuffer.cpp:95
dodo::common::SystemError::ecOK
@ ecOK
0 Not an error, success
Definition: systemerror.hpp:60
dodo::network::StringReadBuffer
String based VirtualReadBuffer, conventient for testing purposes as parsers can be tested against str...
Definition: socketreadbuffer.hpp:185
dodo::network::SocketReadBuffer::received_
ssize_t received_
The number of chars received in the last underflow().
Definition: socketreadbuffer.hpp:140
dodo::network::FileReadBuffer::idx_
size_t idx_
The index into the buffer.
Definition: socketreadbuffer.hpp:172
dodo::network::SocketReadBuffer::SocketReadBuffer
SocketReadBuffer(BaseSocket *socket, size_t bufsize=8192)
Construct a SocketReadBuffer.
Definition: socketreadbuffer.cpp:31
dodo::common::SystemError
Linux system error primitive to provide a consistent interface to Linux error codes.
Definition: systemerror.hpp:53
dodo::network::VirtualReadBuffer::bufsize_
ssize_t bufsize_
The size of buffer_.
Definition: socketreadbuffer.hpp:86
dodo::network::VirtualReadBuffer::getUnderflowCount
size_t getUnderflowCount() const
Return the number of times underflow() was invoked.
Definition: socketreadbuffer.hpp:73
dodo::network::StringReadBuffer::data_
std::string data_
The string data backing the buffer.
Definition: socketreadbuffer.hpp:202
dodo::network::FileReadBuffer::file_
FILE * file_
The file handle.
Definition: socketreadbuffer.hpp:169
dodo::network::SocketReadBuffer::next
virtual common::SystemError next()
Move to the next char from the VirtualReadBuffer.
Definition: socketreadbuffer.cpp:58
basesocket.hpp
dodo::network::BaseSocket
Interface to and common implementation of concrete sockets (Socket, TLSSocket).
Definition: basesocket.hpp:36
dodo::network::VirtualReadBuffer::underflow
virtual common::SystemError underflow()=0
If the buffer_ underflows, the buffer_ must be reset refilledwith new data from the source.