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:
52  using const_iterator = value_type const*;
53 
55  Slice() noexcept = default;
56 
57  Slice(Slice const&) noexcept = default;
58  Slice&
59  operator=(Slice const&) noexcept = default;
60 
62  Slice(void const* data, std::size_t size) noexcept
63  : data_(reinterpret_cast<std::uint8_t const*>(data)), size_(size)
64  {
65  }
66 
68  [[nodiscard]] bool
69  empty() const noexcept
70  {
71  return size_ == 0;
72  }
73 
79  [[nodiscard]] std::size_t
80  size() const noexcept
81  {
82  return size_;
83  }
84 
85  [[nodiscard]] std::size_t
86  length() const noexcept
87  {
88  return size_;
89  }
96  std::uint8_t const*
97  data() const noexcept
98  {
99  return data_;
100  }
101 
104  operator[](std::size_t i) const noexcept
105  {
106  assert(i < size_);
107  return data_[i];
108  }
109 
112  Slice&
114  {
115  if (n > size_)
116  Throw<std::domain_error>("too small");
117  data_ += n;
118  size_ -= n;
119  return *this;
120  }
121 
122  Slice
124  {
125  Slice temp = *this;
126  return temp += n;
127  }
131  void
133  {
134  data_ += n;
135  size_ -= n;
136  }
137 
139  void
141  {
142  size_ -= n;
143  }
144 
146  begin() const noexcept
147  {
148  return data_;
149  }
150 
152  cbegin() const noexcept
153  {
154  return data_;
155  }
156 
158  end() const noexcept
159  {
160  return data_ + size_;
161  }
162 
164  cend() const noexcept
165  {
166  return data_ + size_;
167  }
168 
180  Slice
182  std::size_t pos,
184  {
185  if (pos > size())
186  throw std::out_of_range("Requested sub-slice is out of bounds");
187 
188  return {data_ + pos, std::min(count, size() - pos)};
189  }
190 };
191 
192 //------------------------------------------------------------------------------
193 
194 template <class Hasher>
195 inline void
196 hash_append(Hasher& h, Slice const& v)
197 {
198  h(v.data(), v.size());
199 }
200 
201 inline bool
202 operator==(Slice const& lhs, Slice const& rhs) noexcept
203 {
204  if (lhs.size() != rhs.size())
205  return false;
206 
207  if (lhs.size() == 0)
208  return true;
209 
210  return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
211 }
212 
213 inline bool
214 operator!=(Slice const& lhs, Slice const& rhs) noexcept
215 {
216  return !(lhs == rhs);
217 }
218 
219 inline bool
220 operator<(Slice const& lhs, Slice const& rhs) noexcept
221 {
223  lhs.data(),
224  lhs.data() + lhs.size(),
225  rhs.data(),
226  rhs.data() + rhs.size());
227 }
228 
229 template <class Stream>
230 Stream&
231 operator<<(Stream& s, Slice const& v)
232 {
233  s << strHex(v);
234  return s;
235 }
236 
237 template <class T, std::size_t N>
240  Slice>
242 {
243  return Slice(a.data(), a.size());
244 }
245 
246 template <class T, class Alloc>
249  Slice>
251 {
252  return Slice(v.data(), v.size());
253 }
254 
255 template <class Traits, class Alloc>
256 Slice
258 {
259  return Slice(s.data(), s.size());
260 }
261 
262 } // namespace ripple
263 
264 #endif
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:80
ripple::Slice::operator+=
Slice & operator+=(std::size_t n)
Advance the buffer.
Definition: Slice.h:113
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:241
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:164
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:123
vector
std::array::size
T size(T... args)
ripple::Slice::end
const_iterator end() const noexcept
Definition: Slice.h:158
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:97
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:181
ripple::Slice::length
std::size_t length() const noexcept
Definition: Slice.h:86
ripple::Slice::operator[]
std::uint8_t operator[](std::size_t i) const noexcept
Access raw bytes.
Definition: Slice.h:104
ripple::Slice::empty
bool empty() const noexcept
Return true if the byte range is empty.
Definition: Slice.h:69
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:165
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:175
array
cstdint
std::uint8_t
ripple::Slice::cbegin
const_iterator cbegin() const noexcept
Definition: Slice.h:152
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:132
std::out_of_range
STL class.
std::size_t
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
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:140
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::const_iterator
value_type const * const_iterator
Definition: Slice.h:52
ripple::Slice::begin
const_iterator begin() const noexcept
Definition: Slice.h:146
string