github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/common/byte.cpp (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #include "common/byte.h" 21 #include "common/base58.h" 22 #include "common/base64.h" 23 #include <iomanip> 24 #include <sstream> 25 26 namespace neb { 27 28 namespace internal { 29 std::string convert_byte_to_hex(const byte_t *buf, size_t len) { 30 if (!buf) 31 return ""; 32 std::stringstream s; 33 for (size_t i = 0; i < len; i++) { 34 s << std::hex << std::setw(2) << std::setfill('0') 35 << static_cast<int>(buf[i]); 36 } 37 return s.str(); 38 } 39 40 std::string convert_byte_to_base58(const byte_t *buf, size_t len) { 41 return ::neb::encode_base58(buf, buf + len); 42 } 43 44 std::string convert_byte_to_base64(const byte_t *buf, size_t len) { 45 return ::neb::encode_base64(buf, buf + len); 46 } 47 48 bool convert_hex_to_bytes(const std::string &s, byte_t *buf, size_t &len) { 49 auto char2int = [](char input) { 50 if (input >= '0' && input <= '9') 51 return input - '0'; 52 if (input >= 'A' && input <= 'F') 53 return input - 'A' + 10; 54 if (input >= 'a' && input <= 'f') 55 return input - 'a' + 10; 56 throw std::invalid_argument("Invalid input string"); 57 }; 58 59 try { 60 size_t i = 0; 61 while (i * 2 < s.size() && i * 2 + 1 < s.size()) { 62 if (buf) { 63 buf[i] = (char2int(s[i * 2]) << 4) + char2int(s[i * 2 + 1]); 64 } 65 i++; 66 } 67 len = i; 68 } catch (std::exception &e) { 69 return false; 70 } 71 return true; 72 } 73 74 template <typename CHAR> 75 void convert_string_to_byte(const CHAR *s, byte_t *buf, size_t size) { 76 if (buf) { 77 memcpy(buf, s, size); 78 } 79 } 80 81 bool convert_base58_to_bytes(const std::string &s, byte_t *buf, size_t &len) { 82 std::vector<unsigned char> ret; 83 bool rv = ::neb::decode_base58(s, ret); 84 if (rv) { 85 len = ret.size(); 86 convert_string_to_byte(&ret[0], buf, len); 87 } 88 89 return rv; 90 } 91 92 bool convert_base64_to_bytes(const std::string &s, byte_t *buf, size_t &len){ 93 std::string output_string; 94 bool rv = ::neb::decode_base64(s, output_string); 95 96 if (rv) { 97 len = output_string.size(); 98 if (nullptr != buf) { 99 convert_string_to_byte(output_string.c_str(), buf, len); 100 } 101 } else { 102 throw std::invalid_argument("Invalid decode_base64."); 103 } 104 105 return rv; 106 } 107 } 108 bytes::bytes() : m_value(nullptr), m_size(0) {} 109 110 bytes::bytes(size_t len) 111 : m_value(std::unique_ptr<byte_t[]>(new byte_t[len])), m_size(len) {} 112 113 bytes::bytes(const bytes &v) : bytes(v.size()) { 114 memcpy(m_value.get(), v.m_value.get(), v.size()); 115 m_size = v.size(); 116 } 117 118 bytes::bytes(bytes &&v) : m_value(std::move(v.m_value)), m_size(v.size()) {} 119 120 bytes::bytes(std::initializer_list<byte_t> l) { 121 if (l.size() > 0) { 122 m_value = std::unique_ptr<byte_t[]>(new byte_t[l.size()]); 123 std::copy(l.begin(), l.end(), m_value.get()); 124 } 125 m_size = l.size(); 126 } 127 bytes::bytes(const byte_t *buf, size_t buf_len) { 128 m_size = buf_len; 129 if (buf_len > 0) { 130 m_value = std::unique_ptr<byte_t[]>(new byte_t[buf_len]); 131 memcpy(m_value.get(), buf, buf_len); 132 } 133 } 134 bytes &bytes::operator=(const bytes &v) { 135 if (&v == this) 136 return *this; 137 if (v.value()) { 138 m_value = std::unique_ptr<byte_t[]>(new byte_t[v.size()]); 139 memcpy(m_value.get(), v.m_value.get(), v.size()); 140 } 141 m_size = v.size(); 142 return *this; 143 } 144 145 bytes &bytes::operator=(bytes &&v) { 146 m_value = std::move(v.m_value); 147 m_size = v.m_size; 148 return *this; 149 } 150 151 bool bytes::operator==(const bytes &v) const { 152 if (v.size() != size()) 153 return false; 154 return memcmp(v.value(), value(), size()) == 0; 155 } 156 bool bytes::operator!=(const bytes &v) const { return !operator==(v); } 157 158 bool bytes::operator<(const bytes &v) const { 159 return std::to_string(*this) < std::to_string(v); 160 } 161 162 byte_t bytes::operator[](size_t index) const { return m_value.get()[index]; } 163 byte_t &bytes::operator[](size_t index) { return m_value.get()[index]; } 164 165 std::string bytes::to_base58() const { 166 return internal::convert_byte_to_base58(value(), size()); 167 } 168 169 std::string bytes::to_base64() const { 170 return internal::convert_byte_to_base64(value(), size()); 171 } 172 173 std::string bytes::to_hex() const { 174 return internal::convert_byte_to_hex(value(), size()); 175 } 176 177 bytes bytes::from_base58(const std::string &t) { 178 size_t len = 0; 179 bool succ = internal::convert_base58_to_bytes(t, nullptr, len); 180 if (!succ) 181 throw std::invalid_argument("invalid base58 string for from_base58"); 182 bytes ret(len); 183 internal::convert_base58_to_bytes(t, ret.value(), len); 184 return ret; 185 } 186 187 bytes bytes::from_base64(const std::string &t) { 188 size_t len = 0; 189 bool succeed = internal::convert_base64_to_bytes(t, nullptr, len); 190 if (!succeed) { 191 throw std::invalid_argument("invalid base64 string for from_base64"); 192 } 193 194 bytes ret(len); 195 internal::convert_base64_to_bytes(t, ret.value(), len); 196 197 return ret; 198 } 199 200 bytes bytes::from_hex(const std::string &t) { 201 size_t len = 0; 202 bool succ = internal::convert_hex_to_bytes(t, nullptr, len); 203 if (!succ) { 204 throw std::invalid_argument("invalid hex string for from_hex"); 205 } 206 207 bytes ret(len); 208 bool succ_ret = internal::convert_hex_to_bytes(t, ret.value(), len); 209 if (!succ_ret) { 210 throw std::invalid_argument("invalid hex string for from_hex"); 211 } 212 213 return ret; 214 } 215 216 bytes &bytes::append_bytes(const byte_t *buf, size_t buf_len) { 217 if (buf_len <= 0) { 218 return *this; 219 } 220 221 auto new_value = std::unique_ptr<byte_t[]>(new byte_t[m_size + buf_len]); 222 memcpy(new_value.get(), m_value.get(), m_size); 223 memcpy(new_value.get() + m_size, buf, buf_len); 224 225 m_value = std::move(new_value); 226 m_size += buf_len; 227 return *this; 228 } 229 bytes &bytes::append_bytes(const bytes &v) { 230 return append_bytes(v.value(), v.size()); 231 } 232 } // namespace neb