framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
frame.hpp
Go to the documentation of this file.
1 // Copyright (C) 2013 iwg molw5
2 // For conditions of distribution and use, see copyright notice in COPYING
3 
13 #pragma once
14 
15 #include <string.h>
16 #include <functional>
17 
19 
20 namespace framework
21 {
22  namespace protocol_buffers
23  {
30  {
31  public:
35  using pos_type = std::size_t;
36 
40  using off_type = typename std::make_signed <pos_type>::type;
41 
42  public:
49  raw_input_frame (char const* begin, char const* end)
50  : p_pIt(begin),
51  p_pBegin(begin),
52  p_pEnd(end)
53  {
54  }
55 
60  bool read (char* s, std::size_t n)
61  {
62  if (FRAMEWORK_EXPECT_FALSE(p_pEnd - p_pIt < static_cast <long> (n)))
63  return false;
64 
65  memcpy(s, p_pIt, n);
66  p_pIt += n;
67  return true;
68  }
69 
73  template <std::size_t N>
75  bool read (char* s)
76  {
77  if (FRAMEWORK_EXPECT_FALSE(p_pEnd - p_pIt < static_cast <long> (N)))
78  return false;
79 
80  /*static*/ if (N > 1)
81  {
82  memcpy(s, p_pIt, N);
83  p_pIt += N;
84  }
85  else if (N == 1)
86  {
87  *s = (char)*(p_pIt++);
88  }
89 
90  return true;
91  }
92 
97  pos_type tellg () const
98  {
99  return p_pIt - p_pBegin;
100  }
101 
112  bool seekg (pos_type pos)
113  {
114  if (FRAMEWORK_EXPECT_FALSE(p_pEnd - p_pBegin <= static_cast <long> (pos)))
115  return false;
116 
117  p_pIt = p_pBegin + pos;
118  return true;
119  }
120 
133  bool seekg (off_type off, std::ios_base::seekdir dir)
134  {
135  switch (dir)
136  {
137  case std::ios::beg:
138  if (FRAMEWORK_EXPECT_FALSE(off < 0 || p_pEnd - p_pBegin < off))
139  return false;
140 
141  p_pIt = p_pBegin + off;
142  return true;
143 
144  case std::ios::end:
145  if (FRAMEWORK_EXPECT_FALSE(off > 0 || p_pEnd - p_pBegin < off))
146  return false;
147 
148  p_pIt = p_pEnd - off;
149  return true;
150 
151  case std::ios::cur:
152  if (off >= 0)
153  {
154  if (FRAMEWORK_EXPECT_FALSE(p_pEnd - p_pIt < off))
155  return false;
156 
157  p_pIt += off;
158  return true;
159  }
160  else
161  {
162  if (FRAMEWORK_EXPECT_FALSE(p_pIt - p_pBegin < -off))
163  return false;
164 
165  p_pIt += off;
166  return true;
167  }
168 
169  default:
170  assert(false);
171  return false;
172  }
173  }
174 
175  private:
176  char const* p_pIt;
177  char const* const p_pBegin;
178  char const* const p_pEnd;
179  };
180 
188  template <bool Safe = true>
190  {
191  public:
195  using pos_type = std::size_t;
196 
200  using off_type = typename std::make_signed <pos_type>::type;
201 
202  public:
212  raw_output_frame (char* begin, char* end)
213  : p_pIt(begin),
214  p_pBegin(begin),
215  p_pEnd(end)
216  {
217  assert(p_pBegin <= p_pEnd);
218  }
219 
223  bool write (char const* s, std::streamsize n)
224  {
225  /*static*/ if (Safe)
226  {
227  if (FRAMEWORK_EXPECT_FALSE(p_pEnd - p_pIt < n))
228  return false;
229  }
230  else
231  {
232  assert(p_pEnd - p_pIt >= n);
233  }
234 
235  memcpy(p_pIt, s, n);
236  p_pIt += n;
237  return true;
238  }
239 
243  template <std::size_t N>
244  bool write (char const* s)
245  {
246  /*static*/ if (Safe)
247  {
248  if (FRAMEWORK_EXPECT_FALSE(static_cast <std::size_t> (p_pEnd - p_pIt) < N))
249  return false;
250  }
251  else
252  {
253  assert(static_cast <std::size_t> (p_pEnd - p_pIt) >= N);
254  }
255 
256  /*static*/ if (N > 1)
257  {
258  memcpy(p_pIt, s, N);
259  p_pIt += N;
260  }
261  else if (N == 1)
262  {
263  *(p_pIt++) = static_cast <char> (*s);
264  }
265 
266  return true;
267  }
268 
278  bool seekp (pos_type pos)
279  {
280  /*static*/ if (Safe)
281  {
282  if (FRAMEWORK_EXPECT_FALSE(static_cast <std::size_t> (p_pEnd - p_pBegin) < pos))
283  return false;
284  }
285  else
286  {
287  assert(static_cast <std::size_t> (p_pEnd - p_pBegin) >= pos);
288  }
289 
290  p_pIt = p_pBegin + pos;
291  return true;
292  }
293 
297  std::size_t tellp () const
298  {
299  assert((p_pBegin <= p_pIt) && (p_pIt <= p_pEnd));
300  return p_pIt - p_pBegin;
301  }
302 
303  private:
304  char* p_pIt;
305  char* const p_pBegin;
306  char* const p_pEnd;
307  };
308 
314  template <typename Stream>
315  class length_delimited_input_frame : std::reference_wrapper <Stream>
316  {
317  public:
324  length_delimited_input_frame (Stream& stream, std::size_t size)
325  : std::reference_wrapper <Stream> (stream),
326  p_iSize(size)
327  {
328  }
329 
334  bool read (char* s, std::size_t n)
335  {
336  if (FRAMEWORK_EXPECT_FALSE(p_iSize < n))
337  return false;
338  if (FRAMEWORK_EXPECT_FALSE(!serializable::stream_read(this->get(), s, n)))
339  return false;
340 
341  p_iSize -= n;
342  return true;
343  }
344 
348  template <std::size_t N>
350  bool read (char* s)
351  {
352  if (FRAMEWORK_EXPECT_FALSE(p_iSize < N))
353  return false;
354  if (FRAMEWORK_EXPECT_FALSE(!serializable::stream_read <N> (this->get(), s)))
355  return false;
356 
357  p_iSize -= N;
358  return true;
359  }
360 
366  std::size_t size () const
367  {
368  return p_iSize;
369  }
370 
371  private:
372  std::size_t p_iSize;
373  };
374 
381  {
382  public:
386  using pos_type = std::size_t;
387 
388  public:
393  bool write (char const*, std::size_t n)
394  {
395  p_iSize += n;
396  return true;
397  }
398 
402  template <std::size_t N>
404  bool write (char const*)
405  {
406  p_iSize += N;
407  return true;
408  }
409 
420  bool seekp (pos_type pos)
421  {
422  p_iSize = pos;
423  return true;
424  }
425 
430  std::size_t tellp () const
431  {
432  return p_iSize;
433  }
434 
441  void skip (std::size_t n)
442  {
443  p_iSize += n;
444  }
445 
451  explicit operator std::size_t() const
452  {
453  return p_iSize;
454  }
455 
456  private:
457  std::size_t p_iSize {};
458  };
459 
469  class max_size_frame : private size_frame
470  {
471  public:
472  using size_frame::pos_type;
473  using size_frame::write;
474  using size_frame::seekp;
475  using size_frame::tellp;
476  using size_frame::skip;
477  using size_frame::operator std::size_t;
478  };
479  }
480 }