mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-03-29 10:08:15 -04:00
Merge pull request #1981 from G10h4ck/RsMemoryWrapper_JSON_fixup
Change raw memory JSON representation
This commit is contained in:
commit
97a60865b4
libretroshare/src
@ -503,8 +503,16 @@ bool RsTypeSerializer::from_JSON( const std::string& /*memberName*/,
|
|||||||
// Binary blocks //
|
// Binary blocks //
|
||||||
//============================================================================//
|
//============================================================================//
|
||||||
|
|
||||||
|
#if __cplusplus < 201703L
|
||||||
|
/* Solve weird undefined reference error with C++ < 17 see:
|
||||||
|
* https://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char
|
||||||
|
*/
|
||||||
|
/*static*/ decltype(RsTypeSerializer::RawMemoryWrapper::base64_key) constexpr
|
||||||
|
RsTypeSerializer::RawMemoryWrapper::base64_key;
|
||||||
|
|
||||||
/*static*/ /* without this Android compilation breaks */
|
/*static*/ /* without this Android compilation breaks */
|
||||||
constexpr uint32_t RsTypeSerializer::RawMemoryWrapper::MAX_SERIALIZED_CHUNK_SIZE;
|
constexpr uint32_t RsTypeSerializer::RawMemoryWrapper::MAX_SERIALIZED_CHUNK_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
||||||
@ -542,18 +550,7 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
ctx.mOffset += second;
|
ctx.mOffset += second;
|
||||||
break;
|
break;
|
||||||
case RsGenericSerializer::DESERIALIZE:
|
case RsGenericSerializer::DESERIALIZE:
|
||||||
if(first || second)
|
freshMemCheck();
|
||||||
{
|
|
||||||
/* Items are created anew before deserialization so buffer pointer
|
|
||||||
* must be null and size 0 at this point */
|
|
||||||
|
|
||||||
RsWarn() << __PRETTY_FUNCTION__ << " DESERIALIZE got uninitialized "
|
|
||||||
<< " or pre-allocated buffer! Buffer pointer: " << first
|
|
||||||
<< " must be null and size: " << second << " must be 0 at "
|
|
||||||
<< "this point. Does your item costructor initialize them "
|
|
||||||
<< "properly?" << std::endl;
|
|
||||||
print_stacktrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
RS_SERIAL_PROCESS(second);
|
RS_SERIAL_PROCESS(second);
|
||||||
if(!ctx.mOk) break;
|
if(!ctx.mOk) break;
|
||||||
@ -597,44 +594,33 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
if(!ctx.mOk) break;
|
if(!ctx.mOk) break;
|
||||||
std::string encodedValue;
|
std::string encodedValue;
|
||||||
RsBase64::encode(first, second, encodedValue, true, false);
|
RsBase64::encode(first, second, encodedValue, true, false);
|
||||||
ctx.mJson.SetString(
|
ctx.mOk = ctx.mOk &&
|
||||||
encodedValue.data(),
|
RsTypeSerializer::to_JSON(base64_key, encodedValue, ctx.mJson);
|
||||||
static_cast<rapidjson::SizeType>(encodedValue.length()),
|
|
||||||
ctx.mJson.GetAllocator());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RsGenericSerializer::FROM_JSON:
|
case RsGenericSerializer::FROM_JSON:
|
||||||
{
|
{
|
||||||
const bool yelding = !!(
|
freshMemCheck();
|
||||||
RsSerializationFlags::YIELDING & ctx.mFlags );
|
|
||||||
if(!(ctx.mOk || yelding))
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!ctx.mJson.IsString())
|
|
||||||
{
|
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " "
|
|
||||||
<< std::errc::invalid_argument << std::endl;
|
|
||||||
print_stacktrace();
|
|
||||||
|
|
||||||
ctx.mOk = false;
|
const auto failure = [&]() -> void { ctx.mOk = false; clear(); };
|
||||||
clear();
|
const bool yielding = !!(
|
||||||
break;
|
RsSerializationFlags::YIELDING & ctx.mFlags );
|
||||||
}
|
if(!(ctx.mOk || yielding)) return failure();
|
||||||
if( ctx.mJson.GetStringLength() >
|
|
||||||
|
std::string encodedValue;
|
||||||
|
if(!RsTypeSerializer::from_JSON(
|
||||||
|
base64_key, encodedValue, ctx.mJson )) return failure();
|
||||||
|
|
||||||
|
if( encodedValue.length() >
|
||||||
RsBase64::encodedSize(MAX_SERIALIZED_CHUNK_SIZE, true) )
|
RsBase64::encodedSize(MAX_SERIALIZED_CHUNK_SIZE, true) )
|
||||||
{
|
{
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " "
|
RsErr() << __PRETTY_FUNCTION__ << " "
|
||||||
<< std::errc::message_size << std::endl;
|
<< std::errc::message_size << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
|
|
||||||
ctx.mOk = false;
|
return failure();
|
||||||
clear();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encodedValue = ctx.mJson.GetString();
|
|
||||||
std::vector<uint8_t> decoded;
|
std::vector<uint8_t> decoded;
|
||||||
auto ec = RsBase64::decode(encodedValue, decoded);
|
auto ec = RsBase64::decode(encodedValue, decoded);
|
||||||
if(ec)
|
if(ec)
|
||||||
@ -642,9 +628,7 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
RsErr() << __PRETTY_FUNCTION__ << " " << ec << std::endl;
|
RsErr() << __PRETTY_FUNCTION__ << " " << ec << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
|
|
||||||
ctx.mOk = false;
|
return failure();
|
||||||
clear();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto decodedSize = decoded.size();
|
const auto decodedSize = decoded.size();
|
||||||
@ -655,11 +639,8 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(decodedSize != second)
|
first = reinterpret_cast<uint8_t*>(malloc(decodedSize));
|
||||||
{
|
second = static_cast<uint32_t>(decodedSize);
|
||||||
first = reinterpret_cast<uint8_t*>(realloc(first, decodedSize));
|
|
||||||
second = static_cast<uint32_t>(decodedSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(first, decoded.data(), second);
|
memcpy(first, decoded.data(), second);
|
||||||
break;
|
break;
|
||||||
@ -675,6 +656,24 @@ void RsTypeSerializer::RawMemoryWrapper::clear()
|
|||||||
second = 0;
|
second = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RsTypeSerializer::RawMemoryWrapper::freshMemCheck()
|
||||||
|
{
|
||||||
|
if(first || second)
|
||||||
|
{
|
||||||
|
/* Items are created anew before deserialization so buffer pointer
|
||||||
|
* must be null and size 0 at this point */
|
||||||
|
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " got uninitialized "
|
||||||
|
<< " or pre-allocated buffer! Buffer pointer: " << first
|
||||||
|
<< " must be null and size: " << second << " must be 0 at "
|
||||||
|
<< "this point. Does your item costructor initialize them "
|
||||||
|
<< "properly?" << std::endl;
|
||||||
|
print_stacktrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================//
|
//============================================================================//
|
||||||
// std::error_condition //
|
// std::error_condition //
|
||||||
//============================================================================//
|
//============================================================================//
|
||||||
|
@ -59,12 +59,17 @@ struct RsTypeSerializer
|
|||||||
/// Maximum supported size 10MB
|
/// Maximum supported size 10MB
|
||||||
static constexpr uint32_t MAX_SERIALIZED_CHUNK_SIZE = 10*1024*1024;
|
static constexpr uint32_t MAX_SERIALIZED_CHUNK_SIZE = 10*1024*1024;
|
||||||
|
|
||||||
|
/** Key used for JSON serialization.
|
||||||
|
* @note Changing this value breaks JSON API retro-compatibility */
|
||||||
|
static constexpr char base64_key[] = "base64";
|
||||||
|
|
||||||
/// @see RsSerializable
|
/// @see RsSerializable
|
||||||
void serial_process(
|
void serial_process(
|
||||||
RsGenericSerializer::SerializeJob j,
|
RsGenericSerializer::SerializeJob j,
|
||||||
RsGenericSerializer::SerializeContext& ctx ) override;
|
RsGenericSerializer::SerializeContext& ctx ) override;
|
||||||
private:
|
private:
|
||||||
void clear();
|
void clear();
|
||||||
|
bool freshMemCheck();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Most types are not valid sequence containers
|
/// Most types are not valid sequence containers
|
||||||
@ -777,9 +782,9 @@ struct RsTypeSerializer
|
|||||||
{
|
{
|
||||||
if(!yielding)
|
if(!yielding)
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName
|
RsErr() << __PRETTY_FUNCTION__ << " \"" << memberName
|
||||||
<< "\" not found in JSON:" << std::endl
|
<< "\" not found in JSON:" << std::endl
|
||||||
<< jDoc << std::endl << std::endl;
|
<< jDoc << std::endl << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
}
|
}
|
||||||
ctx.mOk = false;
|
ctx.mOk = false;
|
||||||
@ -790,9 +795,9 @@ struct RsTypeSerializer
|
|||||||
|
|
||||||
if(!v.IsObject())
|
if(!v.IsObject())
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName
|
RsErr() << __PRETTY_FUNCTION__ << " \"" << memberName
|
||||||
<< "\" has wrong type in JSON, object expected, got:"
|
<< "\" has wrong type in JSON, object expected, got:"
|
||||||
<< std::endl << jDoc << std::endl << std::endl;
|
<< std::endl << jDoc << std::endl << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
ctx.mOk = false;
|
ctx.mOk = false;
|
||||||
break;
|
break;
|
||||||
|
@ -32,6 +32,8 @@ std::ostream &operator<<(std::ostream& out, const std::error_condition& err);
|
|||||||
# include <sstream>
|
# include <sstream>
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
|
# include "util/rsjson.h"
|
||||||
|
|
||||||
enum class RsLoggerCategories
|
enum class RsLoggerCategories
|
||||||
{
|
{
|
||||||
DEBUG = ANDROID_LOG_DEBUG,
|
DEBUG = ANDROID_LOG_DEBUG,
|
||||||
@ -55,6 +57,10 @@ struct t_RsLogger
|
|||||||
inline stream_type& operator<<(const T& val)
|
inline stream_type& operator<<(const T& val)
|
||||||
{ ostr << val; return *this; }
|
{ ostr << val; return *this; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline stream_type& operator<<(const RsJson& val)
|
||||||
|
{ ostr << val; return *this; }
|
||||||
|
|
||||||
/// needed for manipulators and things like std::endl
|
/// needed for manipulators and things like std::endl
|
||||||
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
||||||
{
|
{
|
||||||
@ -111,7 +117,7 @@ struct t_RsLogger
|
|||||||
const auto now = system_clock::now();
|
const auto now = system_clock::now();
|
||||||
const auto sec = time_point_cast<seconds>(now);
|
const auto sec = time_point_cast<seconds>(now);
|
||||||
const auto msec = duration_cast<milliseconds>(now - sec);
|
const auto msec = duration_cast<milliseconds>(now - sec);
|
||||||
std::stringstream tstream;
|
std::ostringstream tstream;
|
||||||
tstream << static_cast<char>(CATEGORY) << " "
|
tstream << static_cast<char>(CATEGORY) << " "
|
||||||
<< sec.time_since_epoch().count() << "."
|
<< sec.time_since_epoch().count() << "."
|
||||||
<< std::setfill('0') << std::setw(3) << msec.count()
|
<< std::setfill('0') << std::setw(3) << msec.count()
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
typedef rapidjson::Document RsJson;
|
typedef rapidjson::Document RsJson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print out RsJson to a stream, use std::stringstream to get the string
|
* Print out RsJson to a stream, use std::ostringstream to get the string
|
||||||
* @param[out] out output stream
|
* @param[out] out output stream
|
||||||
* @param[in] jDoc JSON document to print
|
* @param[in] jDoc JSON document to print
|
||||||
* @return same output stream passed as out parameter
|
* @return same output stream passed as out parameter
|
||||||
|
Loading…
x
Reference in New Issue
Block a user