Safer rsids API

Deprecate unsafe costructor, substituted by fromBufferUnsafe which explicitely
  marked suggest the caller to pay attention.
Use enum class for id types instead of constants
Make size constants more private
Use internal Id_t alias to avoid huge template lines
Remove and deprecate oguly names in favor of consistent names
This commit is contained in:
Gioacchino Mazzurco 2019-04-28 18:10:17 +02:00
parent ccf7dc24b8
commit 7642216912
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
12 changed files with 337 additions and 267 deletions

View file

@ -67,13 +67,10 @@ uint32_t msecs_of_day()
static const uint32_t DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID = 0xa0001 ; static const uint32_t DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID = 0xa0001 ;
typedef RsGxsTunnelService::RsGxsTunnelId RsGxsTunnelId; DistantChatService::DistantChatService() :
// default: accept everyone
DistantChatService::DistantChatService() : mDistantChatMtx("distant chat") mDistantChatPermissions(RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE),
{ mGxsTunnels(nullptr), mDistantChatMtx("distant chat") {}
mGxsTunnels = NULL ;
mDistantChatPermissions = RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE ; // default: accept everyone
}
void DistantChatService::connectToGxsTunnelService(RsGxsTunnelService *tr) void DistantChatService::connectToGxsTunnelService(RsGxsTunnelService *tr)
{ {
@ -181,7 +178,8 @@ bool DistantChatService::acceptDataFromPeer(const RsGxsId& gxs_id,const RsGxsTun
return res ; return res ;
} }
void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, uint32_t tunnel_status) void DistantChatService::notifyTunnelStatus(
const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status )
{ {
#ifdef DEBUG_DISTANT_CHAT #ifdef DEBUG_DISTANT_CHAT
DISTANT_CHAT_DEBUG() << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl; DISTANT_CHAT_DEBUG() << "DistantChatService::notifyTunnelStatus(): got notification " << std::hex << tunnel_status << std::dec << " for tunnel " << tunnel_id << std::endl;
@ -207,7 +205,8 @@ void DistantChatService::notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunne
} }
} }
void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tunnel_id, unsigned char *data, uint32_t data_size) void DistantChatService::receiveData(
const RsGxsTunnelId& tunnel_id, unsigned char* data, uint32_t data_size)
{ {
#ifdef DEBUG_DISTANT_CHAT #ifdef DEBUG_DISTANT_CHAT
DISTANT_CHAT_DEBUG() << "DistantChatService::receiveData(): got data of size " << std::dec << data_size << " for tunnel " << tunnel_id << std::endl; DISTANT_CHAT_DEBUG() << "DistantChatService::receiveData(): got data of size " << std::dec << data_size << " for tunnel " << tunnel_id << std::endl;
@ -249,7 +248,8 @@ void DistantChatService::receiveData(const RsGxsTunnelService::RsGxsTunnelId &tu
void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid) void DistantChatService::markDistantChatAsClosed(const DistantChatPeerId& dcpid)
{ {
mGxsTunnels->closeExistingTunnel(RsGxsTunnelService::RsGxsTunnelId(dcpid),DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID) ; mGxsTunnels->closeExistingTunnel(
RsGxsTunnelId(dcpid), DISTANT_CHAT_GXS_TUNNEL_SERVICE_ID );
RS_STACK_MUTEX(mDistantChatMtx) ; RS_STACK_MUTEX(mDistantChatMtx) ;

View file

@ -30,12 +30,13 @@ class RsGixs ;
static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ; static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ;
/**
* Public interface only uses DistandChatPeerId, but internally, this is
* converted into a RsGxsTunnelId
*/
class DistantChatService: public RsGxsTunnelService::RsGxsTunnelClientService class DistantChatService: public RsGxsTunnelService::RsGxsTunnelClientService
{ {
public: public:
// So, public interface only uses DistandChatPeerId, but internally, this is converted into a RsGxsTunnelService::RsGxsTunnelId
DistantChatService() ; DistantChatService() ;
virtual void triggerConfigSave()=0 ; virtual void triggerConfigSave()=0 ;
@ -91,9 +92,13 @@ public:
virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ; virtual void connectToGxsTunnelService(RsGxsTunnelService *tunnel_service) ;
private: private:
virtual bool acceptDataFromPeer(const RsGxsId& gxs_id, const RsGxsTunnelService::RsGxsTunnelId& tunnel_id, bool am_I_client_side) ; virtual bool acceptDataFromPeer(
virtual void notifyTunnelStatus(const RsGxsTunnelService::RsGxsTunnelId& tunnel_id,uint32_t tunnel_status) ; const RsGxsId& gxs_id, const RsGxsTunnelId& tunnel_id,
virtual void receiveData(const RsGxsTunnelService::RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) ; bool am_I_client_side);
virtual void notifyTunnelStatus(
const RsGxsTunnelId& tunnel_id, uint32_t tunnel_status);
virtual void receiveData(
const RsGxsTunnelId& id, unsigned char* data, uint32_t data_size );
// Utility functions. // Utility functions.

View file

@ -47,7 +47,7 @@ namespace librs
template<class T> friend HashStream& operator<<(HashStream& u, const T&) ; template<class T> friend HashStream& operator<<(HashStream& u, const T&) ;
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
friend HashStream& operator<<(HashStream& u, const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& r) friend HashStream& operator<<(HashStream& u, const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& r)
{ {
EVP_DigestUpdate(u.mdctx, r.toByteArray(), ID_SIZE_IN_BYTES); EVP_DigestUpdate(u.mdctx, r.toByteArray(), ID_SIZE_IN_BYTES);

View file

@ -92,8 +92,6 @@
* as these will be used very frequently. * as these will be used very frequently.
*****/ *****/
typedef PGPIdType RsPgpId;
/* Identity Interface for GXS Message Verification. /* Identity Interface for GXS Message Verification.
*/ */
class RsGixs class RsGixs

View file

@ -217,7 +217,9 @@ bool GrpCircleVetting::expired()
{ {
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET); return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET);
} }
bool GrpCircleVetting::canSend(const SSLIdType& peerId, const RsGxsCircleId& circleId,bool& should_encrypt) bool GrpCircleVetting::canSend(
const RsPeerId& peerId, const RsGxsCircleId& circleId,
bool& should_encrypt )
{ {
if(mCircles->isLoaded(circleId)) if(mCircles->isLoaded(circleId))
{ {

View file

@ -1062,7 +1062,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item)
// Note: for some obscure reason, the typedef does not work here. Looks like a compiler error. So I use the primary type. // Note: for some obscure reason, the typedef does not work here. Looks like a compiler error. So I use the primary type.
/*static*/ GXSTunnelId p3GxsTunnelService::makeGxsTunnelId( /*static*/ RsGxsTunnelId p3GxsTunnelService::makeGxsTunnelId(
const RsGxsId &own_id, const RsGxsId &distant_id ) const RsGxsId &own_id, const RsGxsId &distant_id )
{ {
unsigned char mem[RsGxsId::SIZE_IN_BYTES * 2] ; unsigned char mem[RsGxsId::SIZE_IN_BYTES * 2] ;

View file

@ -908,12 +908,14 @@ bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &impo
return false ; return false ;
} }
if(pubkey == NULL || seckey == NULL || pubkey == seckey) if(pubkey == nullptr || seckey == nullptr || pubkey == seckey)
{ {
import_error = "File does not contain a public and a private key. Sorry." ; import_error = "File does not contain a public and a private key. Sorry." ;
return false ; return false ;
} }
if(memcmp(pubkey->fingerprint.fingerprint,seckey->fingerprint.fingerprint,PGP_KEY_FINGERPRINT_SIZE) != 0) if(memcmp( pubkey->fingerprint.fingerprint,
seckey->fingerprint.fingerprint,
RsPpgFingerprint::SIZE_IN_BYTES ) != 0)
{ {
import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ; import_error = "Public and private keys do nt have the same fingerprint. Sorry!" ;
return false ; return false ;
@ -940,7 +942,10 @@ bool PGPHandler::checkAndImportKeyPair(ops_keyring_t *tmp_keyring, RsPgpId &impo
bool found = false ; bool found = false ;
for(uint32_t i=0;i<result->valid_count;++i) for(uint32_t i=0;i<result->valid_count;++i)
if(!memcmp((unsigned char*)result->valid_sigs[i].signer_id,pubkey->key_id,PGP_KEY_ID_SIZE)) if(!memcmp(
static_cast<uint8_t*>(result->valid_sigs[i].signer_id),
pubkey->key_id,
RsPpgFingerprint::SIZE_IN_BYTES ))
{ {
found = true ; found = true ;
break ; break ;
@ -1087,7 +1092,10 @@ bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId&
bool found = false ; bool found = false ;
for(uint32_t i=0;i<result->valid_count;++i) for(uint32_t i=0;i<result->valid_count;++i)
if(!memcmp((unsigned char*)result->valid_sigs[i].signer_id,keydata->key_id,PGP_KEY_ID_SIZE)) if(!memcmp(
static_cast<uint8_t*>(result->valid_sigs[i].signer_id),
keydata->key_id,
RsPpgFingerprint::SIZE_IN_BYTES ))
{ {
found = true ; found = true ;
break ; break ;
@ -1164,7 +1172,9 @@ bool PGPHandler::locked_addOrMergeKey(ops_keyring_t *keyring,std::map<RsPgpId,PG
} }
else else
{ {
if(memcmp(existing_key->fingerprint.fingerprint, keydata->fingerprint.fingerprint,PGP_KEY_FINGERPRINT_SIZE)) if(memcmp( existing_key->fingerprint.fingerprint,
keydata->fingerprint.fingerprint,
RsPpgFingerprint::SIZE_IN_BYTES ))
{ {
std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl; std::cerr << "(EE) attempt to merge key with identical id, but different fingerprint!" << std::endl;
return false ; return false ;
@ -1792,7 +1802,8 @@ bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl)
struct PrivateTrustPacket struct PrivateTrustPacket
{ {
unsigned char user_id[PGP_KEY_ID_SIZE] ; // pgp id in unsigned char format. /// pgp id in unsigned char format.
unsigned char user_id[RsPgpId::SIZE_IN_BYTES];
uint8_t trust_level ; // trust level. From 0 to 6. uint8_t trust_level ; // trust level. From 0 to 6.
uint32_t time_stamp ; // last time the cert was ever used, in seconds since the epoch. 0 means not initialized. uint32_t time_stamp ; // last time the cert was ever used, in seconds since the epoch. 0 means not initialized.
}; };
@ -1854,9 +1865,12 @@ bool PGPHandler::locked_writePrivateTrustDatabase()
} }
PrivateTrustPacket trustpacket ; PrivateTrustPacket trustpacket ;
for(std::map<RsPgpId,PGPCertificateInfo>::iterator it = _public_keyring_map.begin();it!=_public_keyring_map.end() ;++it) for( std::map<RsPgpId,PGPCertificateInfo>::iterator it =
_public_keyring_map.begin(); it!=_public_keyring_map.end(); ++it )
{ {
memcpy(trustpacket.user_id,RsPgpId(it->first).toByteArray(),PGP_KEY_ID_SIZE) ; memcpy( trustpacket.user_id,
it->first.toByteArray(),
RsPgpId::SIZE_IN_BYTES );
trustpacket.trust_level = it->second._trustLvl ; trustpacket.trust_level = it->second._trustLvl ;
trustpacket.time_stamp = it->second._time_stamp ; trustpacket.time_stamp = it->second._time_stamp ;

View file

@ -34,10 +34,7 @@
#include "serialiser/rstypeserializer.h" #include "serialiser/rstypeserializer.h"
#include "util/rstime.h" #include "util/rstime.h"
typedef GXSGroupId RsGxsGroupId;
typedef Sha1CheckSum RsGxsMessageId; typedef Sha1CheckSum RsGxsMessageId;
typedef GXSId RsGxsId;
typedef GXSCircleId RsGxsCircleId;
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult; typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair; typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;

View file

@ -29,8 +29,6 @@
class RsGxsTunnelService class RsGxsTunnelService
{ {
public: public:
typedef GXSTunnelId RsGxsTunnelId ;
enum { enum {
RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000, RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000,
RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001 RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001

View file

@ -3,7 +3,8 @@
* * * *
* libretroshare: retroshare core library * * libretroshare: retroshare core library *
* * * *
* Copyright 2013 by Cyril Soler <csoler@users.sourceforge.net> * * Copyright (C) 2013 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* * * *
* This program is free software: you can redistribute it and/or modify * * This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -19,35 +20,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * * along with this program. If not, see <https://www.gnu.org/licenses/>. *
* * * *
*******************************************************************************/ *******************************************************************************/
// This class aims at defining a generic ID type that is a list of bytes. It
// can be converted into a hexadecial string for printing, mainly) or for
// compatibility with old methods.
//
// To use this class, derive your own ID type from it. Examples include:
//
// class RsPgpId: public t_RsGenericIdType<8>
// {
// [..]
// };
//
// class PGPFingerprintType: public t_RsGenericIdType<20>
// {
// [..]
// };
//
// With this, there is no implicit conversion between subtypes, and therefore ID mixup
// is impossible.
//
// A simpler way to make ID types is to
// typedef t_RsGenericIdType<MySize> MyType ;
//
// ID Types with different lengths will be incompatible on compilation.
//
// Warning: never store references to a t_RsGenericIdType accross threads, since the
// cached string convertion is not thread safe.
//
#pragma once #pragma once
#include <stdexcept> #include <stdexcept>
@ -55,79 +27,142 @@
#include <iostream> #include <iostream>
#include <ostream> #include <ostream>
#include <string.h> #include <string.h>
#include <stdint.h> #include <cstdint>
#include <util/rsrandom.h>
#include <vector> #include <vector>
#include <list> #include <list>
#include <set> #include <set>
#include <memory>
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> class t_RsGenericIdType #include "util/rsdebug.h"
#include "util/rsrandom.h"
#include "util/stacktrace.h"
/**
* RsGenericIdType values might be random, but must be different, in order to
* make the various IDs incompatible with each other.
*/
enum class RsGenericIdType
{ {
public: SSL,
PGP_ID,
SHA1,
PGP_FINGERPRINT,
GXS_GROUP,
GXS_ID,
GXS_MSG,
GXS_CIRCLE,
GROUTER,
GXS_TUNNEL,
DISTANT_CHAT,
NODE_GROUP,
SHA256,
BIAS_20_BYTES
};
typedef std::list<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_list; /**
typedef std::vector<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_vector; * This class aims at defining a generic ID type that is a list of bytes. It
typedef std::set<t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> > std_set; * can be converted into a hexadecial string for printing, mainly) or for
* compatibility with old methods.
t_RsGenericIdType() *
* To use this class, derive your own ID type from it.
* @see RsPpgFingerprint as an example.
*
* Take care to define and use a different @see RsGenericIdType for each ne type
* of ID you create, to avoid implicit conversion between subtypes, and
* therefore accidental ID mixup is impossible.
*
* ID Types with different lengths are not convertible even using explicit
* constructor and compilation would fail if that is attempted.
*
* Warning: never store references to a t_RsGenericIdType accross threads, since
* the cached string convertion is not thread safe.
*/
template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
struct t_RsGenericIdType
{ {
memset(bytes,0,ID_SIZE_IN_BYTES) ; // by default, ids are set to null() using Id_t = t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>;
} using std_list = std::list<Id_t>;
virtual ~t_RsGenericIdType() {} using std_vector = std::vector<Id_t>;
using std_set = std::set<Id_t>;
// Explicit constructor from a hexadecimal string /// by default, ids are set to null()
// t_RsGenericIdType() { memset(bytes, 0, ID_SIZE_IN_BYTES); }
/// Explicit constructor from a hexadecimal string
explicit t_RsGenericIdType(const std::string& hex_string); explicit t_RsGenericIdType(const std::string& hex_string);
// Explicit constructor from a byte array. The array should have size at least ID_SIZE_IN_BYTES /**
// * @brief Construct from a buffer of at least the size of SIZE_IN_BYTES
explicit t_RsGenericIdType(const unsigned char bytes[]) ; * This is dangerous if used without being absolutely sure of buffer size,
* nothing prevent a buffer of wrong size being passed at runtime!
// Explicit constructor from a different type, checking that the sizes are compatible. * @param[in] buff pointer to the buffer
// This is used for conversions such as * @return empty id on failure, an id initialized from the bytes in the
// * buffer
// GroupId -> CircleId */
// GroupId -> GxsId static Id_t fromBufferUnsafe(const uint8_t* buff)
//
template<bool UPPER_CASE2,uint32_t UNIQUE_IDENTIFIER2>
explicit t_RsGenericIdType(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE2,UNIQUE_IDENTIFIER2>& id)
{ {
memcpy(bytes,id.toByteArray(),ID_SIZE_IN_BYTES) ; Id_t ret;
if(!buff)
{
RsErr() << __PRETTY_FUNCTION__ << " invalid paramethers buff: "
<< buff << std::endl;
print_stacktrace();
return ret;
} }
// Random initialization. Can be useful for testing and to generate new ids. memmove(ret.bytes, buff, SIZE_IN_BYTES);
// return ret;
static t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> random() }
/**
* Explicit constructor from a different type but with same size.
*
* This is used for conversions such as
* GroupId -> CircleId
* GroupId -> GxsId
*/
template<bool UPPER_CASE2, RsGenericIdType UNIQUE_IDENTIFIER2>
explicit t_RsGenericIdType(
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE2, UNIQUE_IDENTIFIER2>&
id )
{ memmove(bytes, id.toByteArray(), ID_SIZE_IN_BYTES); }
/// Random initialization. Can be useful for testing and to generate new ids.
static Id_t random()
{ {
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> id ; Id_t id;
RsRandom::random_bytes(id.bytes, ID_SIZE_IN_BYTES);
RSRandom::random_bytes(id.bytes,ID_SIZE_IN_BYTES) ;
return id; return id;
} }
inline void clear() { memset(bytes, 0, SIZE_IN_BYTES); } inline void clear() { memset(bytes, 0, SIZE_IN_BYTES); }
// Converts to a std::string using cached value. /// Converts to a std::string using cached value.
// const uint8_t* toByteArray() const { return &bytes[0]; }
const unsigned char *toByteArray() const { return &bytes[0] ; }
static const uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES ;
inline bool operator==(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return !memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES) ; } static constexpr uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES;
inline bool operator!=(const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return !!memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES); }
inline bool operator< (const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const { return (memcmp(bytes,fp.bytes,ID_SIZE_IN_BYTES) < 0) ; } inline bool operator==(const Id_t& fp) const
inline t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> { return !memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); }
operator~ () const
inline bool operator!=(const Id_t& fp) const
{ return !!memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES); }
inline bool operator< (const Id_t& fp) const
{ return (memcmp(bytes, fp.bytes, ID_SIZE_IN_BYTES) < 0); }
inline Id_t operator~ () const
{ {
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> ret; Id_t ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i) for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = ~bytes[i]; ret.bytes[i] = ~bytes[i];
return ret; return ret;
} }
inline t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>
operator| (const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& fp) const inline Id_t operator| (const Id_t& fp) const
{ {
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER> ret; Id_t ret;
for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i) for(uint32_t i=0; i < ID_SIZE_IN_BYTES; ++i)
ret.bytes[i] = bytes[i] | fp.bytes[i]; ret.bytes[i] = bytes[i] | fp.bytes[i];
return ret; return ret;
@ -136,44 +171,69 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> c
inline bool isNull() const inline bool isNull() const
{ {
for(uint32_t i=0; i < SIZE_IN_BYTES; ++i) for(uint32_t i=0; i < SIZE_IN_BYTES; ++i)
if(bytes[i] != 0) if(bytes[i] != 0) return false;
return false ;
return true; return true;
} }
friend std::ostream& operator<<(std::ostream& out,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& id) friend std::ostream& operator<<(std::ostream& out, const Id_t& id)
{ {
return out << id.toStdString(UPPER_CASE) ; switch (UNIQUE_IDENTIFIER)
{
case RsGenericIdType::PGP_FINGERPRINT:
{
uint8_t index = 0;
for(char c : id.toStdString())
{
out << c;
if(++index % 4 == 0 && index < id.SIZE_IN_BYTES*2) out << ' ';
}
}
break;
default: out << id.toStdString(UPPER_CASE); break;
}
return out;
} }
inline std::string toStdString() const { return toStdString(UPPER_CASE); } inline std::string toStdString() const { return toStdString(UPPER_CASE); }
inline static uint32_t serial_size() { return SIZE_IN_BYTES; } inline static uint32_t serial_size() { return SIZE_IN_BYTES; }
bool serialise(void* data,uint32_t pktsize,uint32_t& offset) const bool serialise(void* data,uint32_t pktsize,uint32_t& offset) const
{ {
if(offset + SIZE_IN_BYTES > pktsize) if(offset + SIZE_IN_BYTES > pktsize) return false;
return false ; memmove( &(reinterpret_cast<uint8_t*>(data))[offset],
bytes, SIZE_IN_BYTES );
memcpy(&((uint8_t*)data)[offset],bytes,SIZE_IN_BYTES) ;
offset += SIZE_IN_BYTES; offset += SIZE_IN_BYTES;
return true; return true;
} }
bool deserialise(const void* data, uint32_t pktsize, uint32_t& offset) bool deserialise(const void* data, uint32_t pktsize, uint32_t& offset)
{ {
if(offset + SIZE_IN_BYTES > pktsize) if(offset + SIZE_IN_BYTES > pktsize) return false;
return false ; memmove( bytes,
&(reinterpret_cast<const uint8_t*>(data))[offset],
memcpy(bytes,&((uint8_t*)data)[offset],SIZE_IN_BYTES) ; SIZE_IN_BYTES );
offset += SIZE_IN_BYTES; offset += SIZE_IN_BYTES;
return true; return true;
} }
/** Explicit constructor from a byte array. The array must have size at
* least ID_SIZE_IN_BYTES
* @deprecated This is too dangerous!
* Nothing prevent a buffer of wrong size being passed at runtime!
*/
RS_DEPRECATED_FOR("fromBufferUnsafe(const uint8_t* buff)")
explicit t_RsGenericIdType(const uint8_t bytes[]);
private: private:
std::string toStdString(bool upper_case) const; std::string toStdString(bool upper_case) const;
uint8_t bytes[ID_SIZE_IN_BYTES];
unsigned char bytes[ID_SIZE_IN_BYTES] ;
}; };
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> std::string t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::toStdString(bool upper_case) const template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
std::string t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>
::toStdString(bool upper_case) const
{ {
static const char outh[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ; static const char outh[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ; static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ;
@ -195,14 +255,20 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> s
return res ; return res ;
} }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::t_RsGenericIdType(const std::string& s) template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>
::t_RsGenericIdType(const std::string& s)
{ {
int n=0; std::string::size_type n = 0;
if(s.length() != ID_SIZE_IN_BYTES*2) if(s.length() != ID_SIZE_IN_BYTES*2)
{ {
if(!s.empty()) if(!s.empty())
std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string in constructor has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2 << " String=\"" << s << "\" = " << s.length() << std::endl; {
RsErr() << __PRETTY_FUNCTION__ << " supplied string in constructor "
<< "has wrong size. Expected ID size=" << ID_SIZE_IN_BYTES*2
<< " String=\"" << s << "\" = " << s.length() << std::endl;
print_stacktrace();
}
clear(); clear();
return; return;
} }
@ -221,8 +287,10 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t
bytes[i] += (b-'a'+10) << 4*(1-k) ; bytes[i] += (b-'a'+10) << 4*(1-k) ;
else if(b >= '0' && b <= '9') else if(b >= '0' && b <= '9')
bytes[i] += (b-'0') << 4*(1-k) ; bytes[i] += (b-'0') << 4*(1-k) ;
else { else
std::cerr << "t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string is not purely hexadecimal: s=\"" << s << "\"" << std::endl; {
RsErr() << __PRETTY_FUNCTION__ << "supplied string is not "
<< "purely hexadecimal: s=\"" << s << "\"" << std::endl;
clear(); clear();
return; return;
} }
@ -230,49 +298,41 @@ template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t
} }
} }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>::t_RsGenericIdType(const unsigned char *mem) template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
RS_DEPRECATED_FOR("t_RsGenericIdType::fromBuffer(...)")
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>::
t_RsGenericIdType(const uint8_t mem[]) /// @deprecated Too dangerous!
{ {
if(mem == NULL) if(mem == nullptr) memset(bytes, 0, ID_SIZE_IN_BYTES);
memset(bytes,0,ID_SIZE_IN_BYTES) ; else memcpy(bytes, mem, ID_SIZE_IN_BYTES);
else
memcpy(bytes,mem,ID_SIZE_IN_BYTES) ;
} }
static const int SSL_ID_SIZE = 16 ; // = CERTSIGNLEN /**
static const int CERT_SIGN_LEN = 16 ; // = CERTSIGNLEN * This constants are meant to be used only inside this file.
static const int PGP_KEY_ID_SIZE = 8 ; * Use @see t_RsGenericIdType::SIZE_IN_BYTES in other places.
static const int PGP_KEY_FINGERPRINT_SIZE = 20 ; */
static const int SHA1_SIZE = 20 ; namespace _RsIdSize
static const int SHA256_SIZE = 32 ; {
constexpr uint32_t SSL_ID = 16; // = CERT_SIGN
constexpr uint32_t CERT_SIGN = 16; // = SSL_ID
constexpr uint32_t PGP_ID = 8;
constexpr uint32_t PGP_FINGERPRINT = 20;
constexpr uint32_t SHA1 = 20;
constexpr uint32_t SHA256 = 32;
}
// These constants are random, but should be different, in order to make the various IDs incompatible with each other. using RsPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::SSL >;
// using RsPgpId = t_RsGenericIdType<_RsIdSize::PGP_ID , true, RsGenericIdType::PGP_ID >;
static const uint32_t RS_GENERIC_ID_SSL_ID_TYPE = 0x0001 ; using Sha1CheckSum = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::SHA1 >;
static const uint32_t RS_GENERIC_ID_PGP_ID_TYPE = 0x0002 ; using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, RsGenericIdType::SHA256 >;
static const uint32_t RS_GENERIC_ID_SHA1_ID_TYPE = 0x0003 ; using RsPpgFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
static const uint32_t RS_GENERIC_ID_PGP_FINGERPRINT_TYPE = 0x0004 ; using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
static const uint32_t RS_GENERIC_ID_GXS_GROUP_ID_TYPE = 0x0005 ; using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
static const uint32_t RS_GENERIC_ID_GXS_ID_TYPE = 0x0006 ; using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
static const uint32_t RS_GENERIC_ID_GXS_MSG_ID_TYPE = 0x0007 ; using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
static const uint32_t RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE = 0x0008 ; using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;
static const uint32_t RS_GENERIC_ID_GROUTER_ID_TYPE = 0x0009 ; using DistantChatPeerId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::DISTANT_CHAT >;
static const uint32_t RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE = 0x0010 ; using RsNodeGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::NODE_GROUP >;
static const uint32_t RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE = 0x0011 ;
static const uint32_t RS_GENERIC_ID_NODE_GROUP_ID_TYPE = 0x0012 ;
static const uint32_t RS_GENERIC_ID_SHA256_ID_TYPE = 0x0013 ;
static const uint32_t RS_GENERIC_ID_20_BYTES_UNTYPED = 0x0014 ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_SSL_ID_TYPE> SSLIdType ;
typedef t_RsGenericIdType< PGP_KEY_ID_SIZE , true, RS_GENERIC_ID_PGP_ID_TYPE> PGPIdType ;
typedef t_RsGenericIdType< SHA1_SIZE , false, RS_GENERIC_ID_SHA1_ID_TYPE> Sha1CheckSum ;
typedef t_RsGenericIdType< SHA256_SIZE , false, RS_GENERIC_ID_SHA256_ID_TYPE> Sha256CheckSum ;
typedef t_RsGenericIdType< PGP_KEY_FINGERPRINT_SIZE, true, RS_GENERIC_ID_PGP_FINGERPRINT_TYPE> PGPFingerprintType ;
typedef t_RsGenericIdType< SHA1_SIZE , true, RS_GENERIC_ID_20_BYTES_UNTYPED> Bias20Bytes ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_GROUP_ID_TYPE > GXSGroupId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_ID_TYPE > GXSId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_GXS_CIRCLE_ID_TYPE > GXSCircleId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_TUNNEL_ID_TYPE > GXSTunnelId ;
typedef t_RsGenericIdType< SSL_ID_SIZE , false, RS_GENERIC_ID_GXS_DISTANT_CHAT_ID_TYPE > DistantChatPeerId ;
typedef t_RsGenericIdType< CERT_SIGN_LEN , false, RS_GENERIC_ID_NODE_GROUP_ID_TYPE > RsNodeGroupId ;
/// @deprecated Ugly name kept temporarly only because it is used in many places
using PGPFingerprintType RS_DEPRECATED_FOR(RsPpgFingerprint) = RsPpgFingerprint;

View file

@ -37,15 +37,6 @@
#define USE_NEW_CHUNK_CHECKING_CODE #define USE_NEW_CHUNK_CHECKING_CODE
// This adds a level of indirection to types, so we can easily change them if needed
//
//typedef std::string RsCertId; // unused
//typedef std::string RsChanId;
//typedef std::string RsMsgId;
//typedef std::string RsAuthId;
typedef SSLIdType RsPeerId ;
typedef PGPIdType RsPgpId ;
typedef Sha1CheckSum RsFileHash ; typedef Sha1CheckSum RsFileHash ;
typedef Sha1CheckSum RsMessageId ; typedef Sha1CheckSum RsMessageId ;

View file

@ -844,33 +844,33 @@ protected:
// t_RsGenericId<...> declarations // // t_RsGenericId<...> declarations //
//============================================================================// //============================================================================//
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool serialize( static bool serialize(
uint8_t data[], uint32_t size, uint32_t &offset, uint8_t data[], uint32_t size, uint32_t &offset,
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ); const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool deserialize( static bool deserialize(
const uint8_t data[], uint32_t size, uint32_t &offset, const uint8_t data[], uint32_t size, uint32_t &offset,
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ); t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static uint32_t serial_size( static uint32_t serial_size(
const t_RsGenericIdType< const t_RsGenericIdType<
ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ); ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static void print_data( static void print_data(
const std::string& name, const std::string& name,
const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member ); const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& member );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool to_JSON( static bool to_JSON(
const std::string& membername, const std::string& membername,
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member, const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
RsJson& jVal ); RsJson& jVal );
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
static bool from_JSON( static bool from_JSON(
const std::string& memberName, const std::string& memberName,
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member, t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
@ -914,7 +914,7 @@ protected:
// t_RsGenericId<...> // // t_RsGenericId<...> //
//============================================================================// //============================================================================//
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::serialize ( bool RsTypeSerializer::serialize (
uint8_t data[], uint32_t size, uint32_t &offset, uint8_t data[], uint32_t size, uint32_t &offset,
const t_RsGenericIdType< const t_RsGenericIdType<
@ -925,28 +925,30 @@ bool RsTypeSerializer::serialize (
).serialise(data, size, offset); ).serialise(data, size, offset);
} }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::deserialize( bool RsTypeSerializer::deserialize(
const uint8_t data[], uint32_t size, uint32_t &offset, const uint8_t data[], uint32_t size, uint32_t &offset,
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ) t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member )
{ return member.deserialise(data, size, offset); } { return member.deserialise(data, size, offset); }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
uint32_t RsTypeSerializer::serial_size( uint32_t RsTypeSerializer::serial_size(
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ) const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member )
{ return member.serial_size(); } { return member.serial_size(); }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
void RsTypeSerializer::print_data( void RsTypeSerializer::print_data(
const std::string& /*name*/, const std::string& /*name*/,
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member ) const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member )
{ {
std::cerr << " [RsGenericId<" << std::hex << UNIQUE_IDENTIFIER << ">] : " std::cerr << " [RsGenericId<" << std::hex
<< static_cast<uint32_t>(UNIQUE_IDENTIFIER) << ">] : "
<< member << std::endl; << member << std::endl;
} }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::to_JSON( const std::string& memberName, bool RsTypeSerializer::to_JSON(
const std::string& memberName,
const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member, const t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
RsJson& jDoc ) RsJson& jDoc )
{ {
@ -964,8 +966,9 @@ bool RsTypeSerializer::to_JSON( const std::string& memberName,
return true; return true;
} }
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER> template<uint32_t ID_SIZE_IN_BYTES, bool UPPER_CASE, RsGenericIdType UNIQUE_IDENTIFIER>
bool RsTypeSerializer::from_JSON( const std::string& membername, bool RsTypeSerializer::from_JSON(
const std::string& membername,
t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member, t_RsGenericIdType<ID_SIZE_IN_BYTES, UPPER_CASE, UNIQUE_IDENTIFIER>& member,
RsJson& jVal ) RsJson& jVal )
{ {
@ -975,7 +978,9 @@ bool RsTypeSerializer::from_JSON( const std::string& membername,
{ {
rapidjson::Value& v = jVal[mName]; rapidjson::Value& v = jVal[mName];
ret = ret && v.IsString(); ret = ret && v.IsString();
if(ret) member = t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>(std::string(v.GetString())); if(ret) member =
t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>(
std::string(v.GetString()) );
} }
return ret; return ret;
} }