danicoin/src/Common/StringTools.cpp
2016-01-18 15:33:29 +00:00

341 lines
9.6 KiB
C++
Executable file

// Copyright (c) 2011-2016 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "StringTools.h"
#include <fstream>
namespace Common {
namespace {
const uint8_t characterValues[256] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};
}
std::string asString(const void* data, size_t size) {
return std::string(static_cast<const char*>(data), size);
}
std::string asString(const std::vector<uint8_t>& data) {
return std::string(reinterpret_cast<const char*>(data.data()), data.size());
}
std::vector<uint8_t> asBinaryArray(const std::string& data) {
auto dataPtr = reinterpret_cast<const uint8_t*>(data.data());
return std::vector<uint8_t>(dataPtr, dataPtr + data.size());
}
uint8_t fromHex(char character) {
uint8_t value = characterValues[static_cast<unsigned char>(character)];
if (value > 0x0f) {
throw std::runtime_error("fromHex: invalid character");
}
return value;
}
bool fromHex(char character, uint8_t& value) {
if (characterValues[static_cast<unsigned char>(character)] > 0x0f) {
return false;
}
value = characterValues[static_cast<unsigned char>(character)];
return true;
}
size_t fromHex(const std::string& text, void* data, size_t bufferSize) {
if ((text.size() & 1) != 0) {
throw std::runtime_error("fromHex: invalid string size");
}
if (text.size() >> 1 > bufferSize) {
throw std::runtime_error("fromHex: invalid buffer size");
}
for (size_t i = 0; i < text.size() >> 1; ++i) {
static_cast<uint8_t*>(data)[i] = fromHex(text[i << 1]) << 4 | fromHex(text[(i << 1) + 1]);
}
return text.size() >> 1;
}
bool fromHex(const std::string& text, void* data, size_t bufferSize, size_t& size) {
if ((text.size() & 1) != 0) {
return false;
}
if (text.size() >> 1 > bufferSize) {
return false;
}
for (size_t i = 0; i < text.size() >> 1; ++i) {
uint8_t value1;
if (!fromHex(text[i << 1], value1)) {
return false;
}
uint8_t value2;
if (!fromHex(text[(i << 1) + 1], value2)) {
return false;
}
static_cast<uint8_t*>(data)[i] = value1 << 4 | value2;
}
size = text.size() >> 1;
return true;
}
std::vector<uint8_t> fromHex(const std::string& text) {
if ((text.size() & 1) != 0) {
throw std::runtime_error("fromHex: invalid string size");
}
std::vector<uint8_t> data(text.size() >> 1);
for (size_t i = 0; i < data.size(); ++i) {
data[i] = fromHex(text[i << 1]) << 4 | fromHex(text[(i << 1) + 1]);
}
return data;
}
bool fromHex(const std::string& text, std::vector<uint8_t>& data) {
if ((text.size() & 1) != 0) {
return false;
}
for (size_t i = 0; i < text.size() >> 1; ++i) {
uint8_t value1;
if (!fromHex(text[i << 1], value1)) {
return false;
}
uint8_t value2;
if (!fromHex(text[(i << 1) + 1], value2)) {
return false;
}
data.push_back(value1 << 4 | value2);
}
return true;
}
std::string toHex(const void* data, size_t size) {
std::string text;
for (size_t i = 0; i < size; ++i) {
text += "0123456789abcdef"[static_cast<const uint8_t*>(data)[i] >> 4];
text += "0123456789abcdef"[static_cast<const uint8_t*>(data)[i] & 15];
}
return text;
}
void toHex(const void* data, size_t size, std::string& text) {
for (size_t i = 0; i < size; ++i) {
text += "0123456789abcdef"[static_cast<const uint8_t*>(data)[i] >> 4];
text += "0123456789abcdef"[static_cast<const uint8_t*>(data)[i] & 15];
}
}
std::string toHex(const std::vector<uint8_t>& data) {
std::string text;
for (size_t i = 0; i < data.size(); ++i) {
text += "0123456789abcdef"[data[i] >> 4];
text += "0123456789abcdef"[data[i] & 15];
}
return text;
}
void toHex(const std::vector<uint8_t>& data, std::string& text) {
for (size_t i = 0; i < data.size(); ++i) {
text += "0123456789abcdef"[data[i] >> 4];
text += "0123456789abcdef"[data[i] & 15];
}
}
std::string extract(std::string& text, char delimiter) {
size_t delimiterPosition = text.find(delimiter);
std::string subText;
if (delimiterPosition != std::string::npos) {
subText = text.substr(0, delimiterPosition);
text = text.substr(delimiterPosition + 1);
} else {
subText.swap(text);
}
return subText;
}
std::string extract(const std::string& text, char delimiter, size_t& offset) {
size_t delimiterPosition = text.find(delimiter, offset);
if (delimiterPosition != std::string::npos) {
offset = delimiterPosition + 1;
return text.substr(offset, delimiterPosition);
} else {
offset = text.size();
return text.substr(offset);
}
}
namespace {
static const std::string base64chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
}
std::string base64Decode(std::string const& encoded_string) {
size_t in_len = encoded_string.size();
size_t i = 0;
size_t j = 0;
size_t in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i == 4) {
for (i = 0; i <4; i++)
char_array_4[i] = (unsigned char)base64chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = (unsigned char)base64chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
bool loadFileToString(const std::string& filepath, std::string& buf) {
try {
std::ifstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(filepath, std::ios_base::binary | std::ios_base::in | std::ios::ate);
size_t fileSize = static_cast<size_t>(fstream.tellg());
buf.resize(fileSize);
if (fileSize > 0) {
fstream.seekg(0, std::ios::beg);
fstream.read(&buf[0], buf.size());
}
} catch (const std::exception&) {
return false;
}
return true;
}
bool saveStringToFile(const std::string& filepath, const std::string& buf) {
try {
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(filepath, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
fstream << buf;
} catch (const std::exception&) {
return false;
}
return true;
}
std::string ipAddressToString(uint32_t ip) {
uint8_t bytes[4];
bytes[0] = ip & 0xFF;
bytes[1] = (ip >> 8) & 0xFF;
bytes[2] = (ip >> 16) & 0xFF;
bytes[3] = (ip >> 24) & 0xFF;
char buf[16];
sprintf(buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
return std::string(buf);
}
bool parseIpAddressAndPort(uint32_t& ip, uint32_t& port, const std::string& addr) {
uint32_t v[4];
uint32_t localPort;
if (sscanf(addr.c_str(), "%d.%d.%d.%d:%d", &v[0], &v[1], &v[2], &v[3], &localPort) != 5) {
return false;
}
for (int i = 0; i < 4; ++i) {
if (v[i] > 0xff) {
return false;
}
}
ip = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0];
port = localPort;
return true;
}
std::string timeIntervalToString(uint64_t intervalInSeconds) {
auto tail = intervalInSeconds;
auto days = tail / (60 * 60 * 24);
tail = tail % (60 * 60 * 24);
auto hours = tail / (60 * 60);
tail = tail % (60 * 60);
auto minutes = tail / (60);
tail = tail % (60);
auto seconds = tail;
return
"d" + std::to_string(days) +
".h" + std::to_string(hours) +
".m" + std::to_string(minutes) +
".s" + std::to_string(seconds);
}
}