VSM C++ SDK
Vehicle Specific Modules SDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
io_stream.h
Go to the documentation of this file.
1 // Copyright (c) 2018, Smart Projects Holdings Ltd
2 // All rights reserved.
3 // See LICENSE file for license details.
4 
11 #ifndef _UGCS_VSM_IO_STREAM_H_
12 #define _UGCS_VSM_IO_STREAM_H_
13 
14 #include <ugcs/vsm/io_buffer.h>
18 
19 #include <chrono>
20 
21 namespace ugcs {
22 namespace vsm {
23 
24 // Supported UDP packet size. Used as default with UDP sockets for reading.
25 // Read on UDP socket must reserve space for maximum payload it can possibly receive.
26 // Theoretical max is 64K which will always be fragmented.
27 // We use what is typically the largest unfragmented packet.
28 // This number is ether_v2 MTU - IP header - UDP header.
29 static constexpr int MIN_UDP_PAYLOAD_SIZE_TO_READ = 1500 - 60 - 8;
30 
31 // TCP socket readers can use this as default max buffer size.
32 // Typically reads data worth one MTU.
33 // This number is ether_v2 MTU - IP header - TCP header (incl 20 byte options).
34 static constexpr int MAX_TCP_PAYLOAD_SIZE_TO_READ = 1500 - 60 - 40;
35 
37 enum class Io_result {
39  OK,
41  TIMED_OUT,
43  CANCELED,
50  CLOSED,
56  LOCK_ERROR,
60 };
61 
66 class Io_stream: public std::enable_shared_from_this<Io_stream> {
68 
69 public:
72 
75  typedef int64_t Offset;
79  static const Offset OFFSET_NONE;
83  static const Offset OFFSET_END;
84 
87 
90 
93 
95  enum class State {
97  CLOSED,
100  OPENING,
103  OPENING_PASSIVE,
105  OPENED
106  };
107 
109  enum class Type {
110  FILE,
111  SERIAL,
112  ANDROID_SERIAL,
113  TCP,
114  UDP,
115  UDP_MULTICAST,
116  CAN,
117  UNDEFINED
118  };
119 
120  virtual
121  ~Io_stream()
122  {}
123 
125  void
126  Add_ref();
127 
131  void
132  Release_ref();
133 
146  Operation_waiter
148  Offset offset,
149  Write_handler completion_handler = Make_dummy_callback<void, Io_result>(),
151  {
152  if (!!completion_handler != !!comp_ctx) {
153  VSM_EXCEPTION(Invalid_param_exception, "Completion handler can not "
154  "exist without completion context and vice versa.");
155  }
156  return Write_impl(buffer, offset, completion_handler, comp_ctx);
157  }
158 
170  Write_handler completion_handler = Make_dummy_callback<void, Io_result>(),
172  {
173  if (!!completion_handler != !!comp_ctx) {
174  VSM_EXCEPTION(Invalid_param_exception, "Completion handler can not "
175  "exist without completion context and vice versa.");
176  }
177  return Write_impl(buffer, OFFSET_NONE, completion_handler, comp_ctx);
178  }
179 
198  Read(size_t max_to_read, size_t min_to_read, Offset offset,
199  Read_handler completion_handler = Make_dummy_callback<void, Io_buffer::Ptr, Io_result>(),
201  {
202  if (!!completion_handler != !!comp_ctx) {
203  VSM_EXCEPTION(Invalid_param_exception, "Completion handler can not "
204  "exist without completion context and vice versa.");
205  }
206  if (max_to_read < min_to_read) {
207  VSM_EXCEPTION(Invalid_param_exception, "max_to_read cannot be less than min_to_read");
208  }
209  return Read_impl(max_to_read, min_to_read, offset, completion_handler,
210  comp_ctx);
211  }
212 
232  Read(size_t max_to_read, size_t min_to_read = 1,
233  Read_handler completion_handler = Make_dummy_callback<void, Io_buffer::Ptr, Io_result>(),
235  {
236  if (!!completion_handler != !!comp_ctx) {
237  VSM_EXCEPTION(Invalid_param_exception, "Completion handler can not "
238  "exist without completion context and vice versa.");
239  }
240  if (min_to_read && max_to_read == 0) {
241  // For UDP and TCP Let's try to read more than required as it can save us some syscalls later.
242  // In UDP case we need to try read the maximum expected size. Otherwise we can get truncated data.
243  switch (stream_type) {
244  case Type::UDP:
245  case Type::UDP_MULTICAST:
246  max_to_read = MIN_UDP_PAYLOAD_SIZE_TO_READ;
247  break;
248  case Type::TCP:
249  max_to_read = MAX_TCP_PAYLOAD_SIZE_TO_READ;
250  break;
251  default:
252  max_to_read = min_to_read;
253  break;
254  }
255  } else if (max_to_read < min_to_read) {
256  VSM_EXCEPTION(Invalid_param_exception, "max_to_read cannot be less than min_to_read");
257  }
258  return Read_impl(max_to_read, min_to_read, OFFSET_NONE, completion_handler, comp_ctx);
259  }
260 
269  Close(Close_handler completion_handler = Make_dummy_callback<void>(),
271  {
272  if (!!completion_handler != !!comp_ctx) {
273  VSM_EXCEPTION(Invalid_param_exception, "Completion handler can not "
274  "exist without completion context and vice versa.");
275  }
276  return Close_impl(completion_handler, comp_ctx);
277  }
278 
282  Io_stream(const Io_stream&) = delete;
283 
287  Io_stream(Type type) :
288  stream_type(type)
289  {}
290 
292  State
293  Get_state() const
294  {
295  return state;
296  }
297 
299  bool
300  Is_closed() const
301  {
302  return (state == State::CLOSED);
303  }
304 
306  std::string
307  Get_name() const;
308 
309  Type
310  Get_type() const
311  {
312  return stream_type;
313  }
314 
316  static const char*
317  Io_result_as_char(const Io_result res);
318 
319 protected:
320  Type stream_type;
321 
325  std::atomic_int ref_count = { 0 };
326 
337  virtual Operation_waiter
338  Write_impl(Io_buffer::Ptr buffer, Offset offset,
339  Write_handler completion_handler,
340  Request_completion_context::Ptr comp_ctx) = 0;
341 
352  virtual Operation_waiter
353  Read_impl(size_t max_to_read, size_t min_to_read, Offset offset,
354  Read_handler completion_handler,
355  Request_completion_context::Ptr comp_ctx) = 0;
356 
364  virtual Operation_waiter
365  Close_impl(Close_handler completion_handler,
366  Request_completion_context::Ptr comp_ctx) = 0;
367 
369  void
370  Set_name(const std::string&);
371 
372 private:
376  static std::mutex name_mutex;
377 
379  std::string name = "[undefined]";
380 };
381 
384 
385 
386 DEFINE_CALLBACK_BUILDER(Make_read_callback, (Io_buffer::Ptr, Io_result),
387  (nullptr, Io_result::OTHER_FAILURE))
388 
389 } /* namespace vsm */
390 } /* namespace ugcs */
391 
392 #endif /* _UGCS_VSM_IO_STREAM_H_ */
State state
Current state of the stream.
Definition: io_stream.h:323
Operation waiter class.
static const Offset OFFSET_NONE
Offset special value which indicates that the offset value is not specified.
Definition: io_stream.h:79
Io_stream(Type type)
Constructor.
Definition: io_stream.h:287
#define DEFINE_CALLBACK_BUILDER(__name, __types, __values)
Define callback builder function.
Definition: callback.h:42
int64_t Offset
Offset for read/write operations.
Definition: io_stream.h:75
Operation_waiter Read(size_t max_to_read, size_t min_to_read=1, Read_handler completion_handler=Make_dummy_callback< void, Io_buffer::Ptr, Io_result >(), Request_completion_context::Ptr comp_ctx=Request_temp_completion_context::Create())
Initiate read operation.
Definition: io_stream.h:232
static Ptr Create(Args &&...args)
Create an instance.
Definition: request_temp_completion_context.h:19
Callback_proxy< void, Io_result > Write_handler
Default prototype for write operation completion handler.
Definition: io_stream.h:86
Io_result
Result of I/O operation.
Definition: io_stream.h:37
Reference guard class definition.
Abstract I/O stream interface.
Definition: io_stream.h:66
Operation completed successfully.
Bad address specific.
virtual Operation_waiter Close_impl(Close_handler completion_handler, Request_completion_context::Ptr comp_ctx)=0
Close call implementation.
bool Is_closed() const
Checks if stream is closed or not.
Definition: io_stream.h:300
Operation_waiter Read(size_t max_to_read, size_t min_to_read, Offset offset, Read_handler completion_handler=Make_dummy_callback< void, Io_buffer::Ptr, Io_result >(), Request_completion_context::Ptr comp_ctx=Request_temp_completion_context::Create())
Initiate read operation.
Definition: io_stream.h:198
Some other system failure.
Callback_proxy< void, Io_buffer::Ptr, Io_result > Read_handler
Default prototype for read operation completion handler.
Definition: io_stream.h:89
Remote side has explicitly refused the connection.
Helper class for proxying callback invocation.
Definition: callback.h:699
Operation_waiter Write(Io_buffer::Ptr buffer, Offset offset, Write_handler completion_handler=Make_dummy_callback< void, Io_result >(), Request_completion_context::Ptr comp_ctx=Request_temp_completion_context::Create())
Initiate write operation.
Definition: io_stream.h:147
void Set_name(const std::string &)
Set the stream name.
virtual Operation_waiter Read_impl(size_t max_to_read, size_t min_to_read, Offset offset, Read_handler completion_handler, Request_completion_context::Ptr comp_ctx)=0
Read call implementation.
std::atomic_int ref_count
Reference counter.
Definition: io_stream.h:325
End of file encountered.
Operation_waiter Write(Io_buffer::Ptr buffer, Write_handler completion_handler=Make_dummy_callback< void, Io_result >(), Request_completion_context::Ptr comp_ctx=Request_temp_completion_context::Create())
Initiate write operation.
Definition: io_stream.h:169
Generic I/O buffer.
Definition: io_buffer.h:33
virtual Operation_waiter Write_impl(Io_buffer::Ptr buffer, Offset offset, Write_handler completion_handler, Request_completion_context::Ptr comp_ctx)=0
Write call implementation.
Operation canceled.
void Release_ref()
Release reference for the stream.
Type
Stream types.
Definition: io_stream.h:109
void Add_ref()
Add reference to the stream.
std::shared_ptr< Request_context > Ptr
Pointer type.
Definition: request_context.h:25
std::shared_ptr< Io_buffer > Ptr
Pointer type.
Definition: io_buffer.h:34
Operation_waiter Close(Close_handler completion_handler=Make_dummy_callback< void >(), Request_completion_context::Ptr comp_ctx=Request_temp_completion_context::Create())
Initiate stream close operation.
Definition: io_stream.h:269
static const Offset OFFSET_END
Offset special value which indicates that the offset value corresponds to the stream end (e...
Definition: io_stream.h:83
std::string Get_name() const
Get human readable stream name.
Io_stream(const Io_stream &)=delete
There is no sense in copying the stream.
#define DEFINE_COMMON_CLASS(__class_name,...)
Use this macro to define some common attributes for a class.
Definition: utils.h:25
std::shared_ptr< Io_stream > Ptr
Pointer type.
Definition: io_stream.h:67
Callback_proxy< void > Close_handler
Default prototype for close operation completion handler.
Definition: io_stream.h:92
Insufficient permissions for the requested operation.
Reference guard objects keep references for managed objects.
Definition: reference_guard.h:31
Stream has been or is closed.
static const char * Io_result_as_char(const Io_result res)
Convert Io_result value to character string.
State
Stream states.
Definition: io_stream.h:95
#define VSM_EXCEPTION(__exc_class, __msg,...)
Throw VSM exception instance.
Definition: exception.h:168
State Get_state() const
Get current state of the stream.
Definition: io_stream.h:293
Operation timed out.
Io_buffer class implementation.
Class for synchronizing with request execution.
Definition: operation_waiter.h:24