rippled
Slice.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_BASICS_SLICE_H_INCLUDED
21 #define RIPPLE_BASICS_SLICE_H_INCLUDED
22 
23 #include <ripple/basics/contract.h>
24 #include <ripple/basics/strHex.h>
25 #include <algorithm>
26 #include <array>
27 #include <cassert>
28 #include <cstdint>
29 #include <cstring>
30 #include <limits>
31 #include <stdexcept>
32 #include <string>
33 #include <type_traits>
34 #include <vector>
35 
36 namespace ripple {
37 
44 class Slice
45 {
46 private:
47  std::uint8_t const* data_ = nullptr;
49 
50 public:
51  using const_iterator = std::uint8_t const*;
52 
54  Slice() noexcept = default;
55 
56  Slice(Slice const&) noexcept = default;
57  Slice&
58  operator=(Slice const&) noexcept = default;
59 
61  Slice(void const* data, std::size_t size) noexcept
62  : data_(reinterpret_cast<std::uint8_t const*>(data)), size_(size)
63  {
64  }
65 
67  [[nodiscard]] bool
68  empty() const noexcept
69  {
70  return size_ == 0;
71  }
72 
79  size() const noexcept
80  {
81  return size_;
82  }
83 
85  length() const noexcept
86  {
87  return size_;
88  }
95  std::uint8_t const*
96  data() const noexcept
97  {
98  return data_;
99  }
100 
103  operator[](std::size_t i) const noexcept
104  {
105  assert(i < size_);
106  return data_[i];
107  }
108 
111  Slice&
113  {
114  if (n > size_)
115  Throw<std::domain_error>("too small");
116  data_ += n;
117  size_ -= n;
118  return *this;
119  }
120 
121  Slice
123  {
124  Slice temp = *this;
125  return temp += n;
126  }
130  void
132  {
133  data_ += n;
134  size_ -= n;
135  }
136 
138  void
140  {
141  size_ -= n;
142  }
143 
145  begin() const noexcept
146  {
147  return data_;
148  }
149 
151  cbegin() const noexcept
152  {
153  return data_;
154  }
155 
157  end() const noexcept
158  {
159  return data_ + size_;
160  }
161 
163  cend() const noexcept
164  {
165  return data_ + size_;
166  }
167 
179  Slice
181  std::size_t pos,
183  {
184  if (pos > size())
185  throw std::out_of_range("Requested sub-slice is out of bounds");
186 
187  return {data_ + pos, std::min(count, size() - pos)};
188  }
189 };
190 
191 //------------------------------------------------------------------------------
192 
193 template <class Hasher>
194 inline void
195 hash_append(Hasher& h, Slice const& v)
196 {
197  h(v.data(), v.size());
198 }
199 
200 inline bool
201 operator==(Slice const& lhs, Slice const& rhs) noexcept
202 {
203  if (lhs.size() != rhs.size())
204  return false;
205 
206  if (lhs.size() == 0)
207  return true;
208 
209  return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
210 }
211 
212 inline bool
213 operator!=(Slice const& lhs, Slice const& rhs) noexcept
214 {
215  return !(lhs == rhs);
216 }
217 
218 inline bool
219 operator<(Slice const& lhs, Slice const& rhs) noexcept
220 {
222  lhs.data(),
223  lhs.data() + lhs.size(),
224  rhs.data(),
225  rhs.data() + rhs.size());
226 }
227 
228 template <class Stream>
229 Stream&
230 operator<<(Stream& s, Slice const& v)
231 {
232  s << strHex(v);
233  return s;
234 }
235 
236 template <class T, std::size_t N>
239  Slice>
241 {
242  return Slice(a.data(), a.size());
243 }
244 
245 template <class T, class Alloc>
248  Slice>
250 {
251  return Slice(v.data(), v.size());
252 }
253 
254 template <class Traits, class Alloc>
255 Slice
257 {
258  return Slice(s.data(), s.size());
259 }
260 
261 } // namespace ripple
262 
263 #endif
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:79
ripple::Slice::operator+=
Slice & operator+=(std::size_t n)
Advance the buffer.
Definition: Slice.h:112
std::is_same
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:240
ripple::Dir::const_iterator
Definition: Directory.h:49
std::basic_string
STL class.
cstring
ripple::Slice::Slice
Slice() noexcept=default
Default constructed Slice has length 0.
ripple::Slice::cend
const_iterator cend() const noexcept
Definition: Slice.h:163
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
ripple::Slice::operator+
Slice operator+(std::size_t n) const
Definition: Slice.h:122
vector
std::array::size
T size(T... args)
ripple::Slice::end
const_iterator end() const noexcept
Definition: Slice.h:157
ripple::Slice::data_
std::uint8_t const * data_
Definition: Slice.h:47
ripple::Slice::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:96
ripple::Slice::substr
Slice substr(std::size_t pos, std::size_t count=std::numeric_limits< std::size_t >::max()) const
Return a "sub slice" of given length starting at the given position.
Definition: Slice.h:180
ripple::Slice::length
std::size_t length() const noexcept
Definition: Slice.h:85
ripple::Slice::operator[]
std::uint8_t operator[](std::size_t i) const noexcept
Access raw bytes.
Definition: Slice.h:103
ripple::Slice::empty
bool empty() const noexcept
Return true if the byte range is empty.
Definition: Slice.h:68
ripple::operator<<
std::ostream & operator<<(std::ostream &os, TOffer< TIn, TOut > const &offer)
Definition: Offer.h:242
algorithm
ripple::operator==
bool operator==(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:161
stdexcept
ripple::Slice::size_
std::size_t size_
Definition: Slice.h:48
std::enable_if_t
ripple::operator<
bool operator<(CanonicalTXSet::Key const &lhs, CanonicalTXSet::Key const &rhs)
Definition: CanonicalTXSet.cpp:25
std::lexicographical_compare
T lexicographical_compare(T... args)
ripple::operator!=
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:171
array
cstdint
std::uint8_t
ripple::Slice::const_iterator
std::uint8_t const * const_iterator
Definition: Slice.h:51
ripple::Slice::cbegin
const_iterator cbegin() const noexcept
Definition: Slice.h:151
std::min
T min(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
limits
std
STL namespace.
cassert
ripple::Slice::remove_prefix
void remove_prefix(std::size_t n)
Shrinks the slice by moving its start forward by n characters.
Definition: Slice.h:131
std::out_of_range
STL class.
std::size_t
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:45
std::memcmp
T memcmp(T... args)
ripple::Slice::remove_suffix
void remove_suffix(std::size_t n)
Shrinks the slice by moving its end backward by n characters.
Definition: Slice.h:139
ripple::hash_append
void hash_append(Hasher &h, ValidatorBlobInfo const &blobInfo)
Definition: ValidatorList.h:897
std::numeric_limits
std::array::data
T data(T... args)
type_traits
ripple::Slice::begin
const_iterator begin() const noexcept
Definition: Slice.h:145
string