Monero
Loading...
Searching...
No Matches
varint.h
Go to the documentation of this file.
1// Copyright (c) 2014-2022, The Monero Project
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification, are
6// permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this list of
9// conditions and the following disclaimer.
10//
11// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12// of conditions and the following disclaimer in the documentation and/or other
13// materials provided with the distribution.
14//
15// 3. Neither the name of the copyright holder nor the names of its contributors may be
16// used to endorse or promote products derived from this software without specific
17// prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30
31#pragma once
32
33#include <limits>
34#include <type_traits>
35#include <utility>
36#include <sstream>
37#include <string>
52
53namespace tools {
54
57 enum {
58 /* \brief Represents the overflow error */
60 /* \brief Represents a non conical represnetation */
62 };
63
66 template<typename OutputIt, typename T>
67 /* Requires T to be both an integral type and unsigned, should be a compile error if it is not */
68 typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, void>::type
69 write_varint(OutputIt &&dest, T i) {
70 /* Make sure that there is one after this */
71 while (i >= 0x80) {
72 *dest = (static_cast<char>(i) & 0x7f) | 0x80;
73 ++dest;
74 i >>= 7; /* I should be in multiples of 7, this should just get the next part */
75 }
76 /* writes the last one to dest */
77 *dest = static_cast<char>(i);
78 dest++; /* Seems kinda pointless... */
79 }
80
83 template<typename T>
84 std::string get_varint_data(const T& v)
85 {
86 std::stringstream ss;
87 write_varint(std::ostreambuf_iterator<char>(ss), v);
88 return ss.str();
89 }
90
92 template<int bits, typename InputIt, typename T>
93 typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value && 0 <= bits && bits <= std::numeric_limits<T>::digits, int>::type
94 read_varint(InputIt &&first, InputIt &&last, T &write) {
95 int read = 0;
96 write = 0;
97 for (int shift = 0;; shift += 7) {
98 if (first == last) {
99 return read;
100 }
101 unsigned char byte = *first;
102 ++first;
103 ++read;
104 if (shift + 7 >= bits && byte >= 1 << (bits - shift)) {
105 return EVARINT_OVERFLOW;
106 }
107 if (byte == 0 && shift != 0) {
108 return EVARINT_REPRESENT;
109 }
110
111 write |= static_cast<T>(byte & 0x7f) << shift; /* Does the actually placing into write, stripping the first bit */
112
113 /* If there is no next */
114 if ((byte & 0x80) == 0) {
115 break;
116 }
117 }
118 return read;
119 }
120
124 template<typename InputIt, typename T>
125 int read_varint(InputIt &&first, InputIt &&last, T &i) {
126 return read_varint<std::numeric_limits<T>::digits>(std::forward<InputIt>(first), std::forward<InputIt>(last), i);
127 }
128}
Various Tools.
Definition apply_permutation.h:40
std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&0<=bits &&bits<=std::numeric_limits< T >::digits, int >::type read_varint(InputIt &&first, InputIt &&last, T &write)
reads in the varint that is pointed to by InputIt into write
Definition varint.h:94
std::string get_varint_data(const T &v)
Returns the string that represents the varint.
Definition varint.h:84
std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value, void >::type write_varint(OutputIt &&dest, T i)
writes a varint to a stream.
Definition varint.h:69
@ EVARINT_REPRESENT
Definition varint.h:61
@ EVARINT_OVERFLOW
Definition varint.h:59
CXA_THROW_INFO_T void(* dest)(void *))
Definition stack_trace.cpp:91
#define T(x)