Files
monero_c/monero_libwallet2_api_c/src/main/cpp/helpers.cpp
T
Czarek Nakamoto b72d2dff62 feat: split MONERO and WOWNERO prefixed functions
So basically: when we open the .so file, we define some
symbols, and it appears that if we load something else,
with the same symbols, under the same thread we cause
some funky behaviour - like calling function a wownero
function MONERO_Wallet_address() resulting in a monero
address being generated.
Needless to say, this is undesired, and a blocker for
https://github.com/cypherstack/stack_wallet/pull/818

I'm afraid that this may not solve all of our issues (but
will solve some significant roadblocks), because of the
"genesis block" issue, as output of
nm -gDC release/wownero/x86_64-linux-gnu_libwallet2_api_c.so | grep genesis
indicate that these functions may share *something* in
common across both WOW and XMR libraries.
In a case in which this fix won't be sufficient, I think that
the way forward would be to close the dynamic libraries,
but before we do that I want to check if maybe there is
a change to run multiple wallets at once.
2024-03-31 09:19:47 +02:00

160 lines
5.0 KiB
C++

#include <inttypes.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <vector>
#include <string>
#include "helpers.hpp"
#include <set>
#include <sstream>
#include <cstring>
const char* vectorToString(const std::vector<std::string>& vec, const std::string separator) {
// Concatenate all strings in the vector
std::string result;
for (const auto& str : vec) {
result += str;
result += separator;
}
const char* cstr = result.c_str();
return cstr;
}
const char* vectorToString(const std::vector<uint32_t>& vec, const std::string separator) {
// Calculate the size needed for the result string
size_t size = 0;
for (size_t i = 0; i < vec.size(); ++i) {
// Calculate the number of digits in each element
size += snprintf(nullptr, 0, "%u", vec[i]);
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
size += separator.size(); // comma and space
}
}
// Allocate memory for the result string
char* result = static_cast<char*>(malloc(size + 1));
if (result == nullptr) {
// Handle memory allocation failure
return nullptr;
}
// Fill in the result string
char* current = result;
for (size_t i = 0; i < vec.size(); ++i) {
// Convert each element to string and copy to the result string
int written = snprintf(current, size + 1, "%u", vec[i]);
current += written;
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
strcpy(current, separator.c_str());
current += separator.size();
}
}
return result;
}
const char* vectorToString(const std::vector<uint64_t>& vec, const std::string separator) {
// Calculate the size needed for the result string
size_t size = 0;
for (size_t i = 0; i < vec.size(); ++i) {
// Calculate the number of digits in each element
size += snprintf(nullptr, 0, "%lu", vec[i]);
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
size += separator.size(); // comma and space
}
}
// Allocate memory for the result string
char* result = static_cast<char*>(malloc(size + 1));
if (result == nullptr) {
// Handle memory allocation failure
return nullptr;
}
// Fill in the result string
char* current = result;
for (size_t i = 0; i < vec.size(); ++i) {
// Convert each element to string and copy to the result string
int written = snprintf(current, size + 1, "%lu", vec[i]);
current += written;
// Add comma and space for all elements except the last one
if (i < vec.size() - 1) {
strcpy(current, separator.c_str());
current += separator.size();
}
}
return result;
}
const char* vectorToString(const std::vector<std::set<uint32_t>>& vec, const std::string separator) {
// Check if the vector is empty
if (vec.empty()) {
return "";
}
// Use a stringstream to concatenate sets with commas and individual elements with spaces
std::ostringstream oss;
oss << "{";
for (auto it = vec.begin(); it != vec.end(); ++it) {
if (it != vec.begin()) {
oss << separator;
}
oss << "{";
for (auto setIt = it->begin(); setIt != it->end(); ++setIt) {
if (setIt != it->begin()) {
oss << separator;
}
oss << *setIt;
}
oss << "}";
}
oss << "}";
std::string str = oss.str();
const std::string::size_type size = str.size();
char *buffer = new char[size + 1]; //we need extra char for NUL
memcpy(buffer, str.c_str(), size + 1);
return buffer;
}
// Function to convert std::set<uint32_t> to a string
const char* vectorToString(const std::set<uint32_t>& intSet, const std::string separator) {
// Check if the set is empty
if (intSet.empty()) {
return "";
}
// Use a stringstream to concatenate elements with commas
std::ostringstream oss;
auto it = intSet.begin();
oss << *it;
for (++it; it != intSet.end(); ++it) {
oss << ", " << *it;
}
std::string str = oss.str();
const std::string::size_type size = str.size();
char *buffer = new char[size + 1]; //we need extra char for NUL
memcpy(buffer, str.c_str(), size + 1);
return buffer;
}
std::set<std::string> splitString(const std::string& str, const std::string& delim) {
std::set<std::string> tokens;
if (str.empty()) return tokens;
size_t pos = 0;
std::string token;
std::string content = str; // Copy of str so we can safely erase content
while ((pos = content.find(delim)) != std::string::npos) {
token = content.substr(0, pos);
tokens.insert(token);
content.erase(0, pos + delim.length());
}
tokens.insert(content); // Inserting the last token
return tokens;
}