SSP21-CPP
WSeq.h
1 /*
2  * Copyright (c) 2018, Automatak LLC
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6  * following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
9  * disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
15  * products derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #ifndef SER4CPP_WSEQ_H
26 #define SER4CPP_WSEQ_H
27 
28 #include "ser4cpp/container/RSeq.h"
29 #include "ser4cpp/util/Comparisons.h"
30 
31 #include <cstdint>
32 #include <cstring>
33 
34 namespace ser4cpp
35 {
36 
37 /**
38 * Represents a write-able slice of a buffer located elsewhere. Mediates writing to the buffer
39 * to prevent overruns and other errors. Parameterized by the length type
40 */
41 template <class L>
42 class WSeq : public HasLength<L>
43 {
44  typedef void* (memfunc_t)(void*, const void*, size_t);
45 
46 public:
47  static WSeq empty()
48  {
49  return WSeq();
50  }
51 
52  WSeq()
53  {}
54 
55  WSeq(uint8_t* buffer, uint32_t length) : HasLength<L>(length), buffer_(buffer)
56  {}
57 
58  void set_all_to(uint8_t value)
59  {
60  memset(this->buffer_, value, this->length());
61  }
62 
63  void make_empty()
64  {
65  this->buffer_ = nullptr;
66  this->m_length = 0;
67  }
68 
69  L advance(L count)
70  {
71  const auto num = ser4cpp::min(count, this->length());
72  this->buffer_ += num;
73  this->m_length -= num;
74  return num;
75  }
76 
77  bool put(uint8_t byte)
78  {
79  if (this->length() == 0) return false;
80  else
81  {
82  this->buffer_[0] = byte;
83  ++this->buffer_;
84  --this->m_length;
85  return true;
86  }
87  }
88 
89  WSeq skip(uint32_t count) const
90  {
91  const auto num = ser4cpp::min(count, this->m_length);
92  return WSeq(this->buffer_ + num, this->m_length - num);
93  }
94 
95  WSeq take(uint32_t count) const
96  {
97  return WSeq(this->buffer_, ser4cpp::min(this->m_length, count));
98  }
99 
100  RSeq<L> readonly() const
101  {
102  return RSeq<L>(this->buffer_, this->length());
103  }
104 
105  operator uint8_t* () const
106  {
107  return buffer_;
108  };
109 
110  RSeq<L> copy_from(const RSeq<L>& src)
111  {
112  return this->transfer_from<memcpy>(src);
113  }
114 
115  RSeq<L> move_from(const RSeq<L>& src)
116  {
117  return this->transfer_from<memmove>(src);
118  }
119 
120 private:
121  template <memfunc_t mem_func>
122  RSeq<L> transfer_from(const RSeq<L>& src)
123  {
124  if (src.length() > this->length())
125  {
126  return RSeq<L>::empty();
127  }
128  else
129  {
130  const auto ret = this->readonly().take(src.length());
131  mem_func(buffer_, src, src.length());
132  this->advance(src.length());
133  return ret;
134  }
135  }
136 
137  uint8_t* buffer_ = nullptr;
138 };
139 
140 }
141 
142 #endif
ser4cpp header-only library namespace
Definition: Buffer.h:33