mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
318 lines
9.1 KiB
C++
318 lines
9.1 KiB
C++
/*******************************************************************************
|
|
* libretroshare/src/util: contentvalue.cc *
|
|
* *
|
|
* libretroshare: retroshare core library *
|
|
* *
|
|
* Copyright 2012 Christopher Evi-Parker <retroshare@lunamutt.com> *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
* *
|
|
*******************************************************************************/
|
|
#include <iostream>
|
|
#include <memory.h>
|
|
|
|
#include "contentvalue.h"
|
|
|
|
|
|
|
|
|
|
const uint8_t ContentValue::BOOL_TYPE = 1;
|
|
const uint8_t ContentValue::DATA_TYPE = 2;
|
|
const uint8_t ContentValue::STRING_TYPE = 3;
|
|
const uint8_t ContentValue::DOUBLE_TYPE = 4;
|
|
const uint8_t ContentValue::INT32_TYPE = 5;
|
|
const uint8_t ContentValue::INT64_TYPE = 6;
|
|
|
|
|
|
/**************** content value implementation ******************/
|
|
|
|
typedef std::pair<std::string, uint8_t> KeyTypePair;
|
|
|
|
ContentValue::ContentValue(){
|
|
|
|
}
|
|
|
|
ContentValue::~ContentValue(){
|
|
// release resources held in data
|
|
clearData();
|
|
}
|
|
|
|
ContentValue::ContentValue(const ContentValue &from){
|
|
|
|
std::map<std::string, uint8_t> keyTypeMap;
|
|
from.getKeyTypeMap(keyTypeMap);
|
|
std::map<std::string, uint8_t>::const_iterator cit =
|
|
keyTypeMap.begin();
|
|
|
|
uint8_t type = 0;
|
|
std::string currKey;
|
|
std::string val = "";
|
|
char *src = NULL;
|
|
uint32_t data_len = 0;
|
|
|
|
for(; cit != keyTypeMap.end(); ++cit){
|
|
|
|
type = cit->second;
|
|
currKey = cit->first;
|
|
|
|
switch(type){
|
|
|
|
case INT32_TYPE:
|
|
{
|
|
int32_t value = 0;
|
|
if (from.getAsInt32(currKey, value))
|
|
put(currKey, value);
|
|
break;
|
|
}
|
|
case INT64_TYPE:
|
|
{
|
|
int64_t value = 0;
|
|
if (from.getAsInt64(currKey, value))
|
|
put(currKey, value);
|
|
break;
|
|
}
|
|
case STRING_TYPE:
|
|
{
|
|
if (from.getAsString(currKey, val))
|
|
put(currKey, val);
|
|
break;
|
|
}
|
|
case BOOL_TYPE:
|
|
{
|
|
bool value = false;
|
|
if (from.getAsBool(currKey, value))
|
|
put(currKey, value);
|
|
break;
|
|
}
|
|
case DATA_TYPE:
|
|
{
|
|
if (from.getAsData(currKey, data_len, src))
|
|
put(currKey, data_len, src);
|
|
break;
|
|
}
|
|
case DOUBLE_TYPE:
|
|
{
|
|
double value = 0;
|
|
if (from.getAsDouble(currKey, value))
|
|
put(currKey, value);
|
|
break;
|
|
}
|
|
default:
|
|
std::cerr << "ContentValue::ContentValue(ContentValue &from):"
|
|
<< "Error! Unrecognised data type!" << std::endl;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ContentValue::put(const std::string &key, bool value){
|
|
|
|
if(mKvSet.find(key) != mKvSet.end())
|
|
removeKeyValue(key);
|
|
|
|
mKvSet.insert(KeyTypePair(key, BOOL_TYPE));
|
|
mKvBool.insert(std::pair<std::string, bool>(key, value));
|
|
}
|
|
|
|
void ContentValue::put(const std::string &key, const std::string &value){
|
|
|
|
if(mKvSet.find(key) != mKvSet.end())
|
|
removeKeyValue(key);
|
|
|
|
mKvSet.insert(KeyTypePair(key, STRING_TYPE));
|
|
mKvString.insert(std::pair<std::string, std::string>(key, value));
|
|
}
|
|
|
|
void ContentValue::put(const std::string &key, double value){
|
|
|
|
if(mKvSet.find(key) != mKvSet.end())
|
|
removeKeyValue(key);
|
|
|
|
mKvSet.insert(KeyTypePair(key,DOUBLE_TYPE));
|
|
mKvDouble.insert(std::pair<std::string, double>(key, value));
|
|
}
|
|
|
|
void ContentValue::put(const std::string &key, int32_t value){
|
|
|
|
if(mKvSet.find(key) != mKvSet.end())
|
|
removeKeyValue(key);
|
|
|
|
mKvSet.insert(KeyTypePair(key, INT32_TYPE));
|
|
mKvInt32.insert(std::pair<std::string, int32_t>(key, value));
|
|
}
|
|
|
|
void ContentValue::put(const std::string &key, int64_t value){
|
|
|
|
if(mKvSet.find(key) != mKvSet.end())
|
|
removeKeyValue(key);
|
|
|
|
mKvSet.insert(KeyTypePair(key, INT64_TYPE));
|
|
mKvInt64.insert(std::pair<std::string, int64_t>(key, value));
|
|
}
|
|
|
|
void ContentValue::put(const std::string &key, uint32_t len, const char* value){
|
|
|
|
|
|
// release memory from old key value if key
|
|
// exists
|
|
if(mKvSet.find(key) != mKvSet.end()) {
|
|
removeKeyValue(key);
|
|
}
|
|
|
|
mKvSet.insert(KeyTypePair(key, DATA_TYPE));
|
|
char* dest = NULL;
|
|
|
|
// len is zero then just put a NULL entry
|
|
if(len != 0){
|
|
dest = new char[len];
|
|
memcpy(dest, value, len);
|
|
}
|
|
|
|
mKvData.insert(std::pair<std::string, std::pair<uint32_t, char*> >
|
|
(key, std::pair<uint32_t, char*>(len, dest)));
|
|
//delete[] dest; //Deleted by clearData()
|
|
// cppcheck-suppress memleak
|
|
}
|
|
|
|
bool ContentValue::getAsBool(const std::string &key, bool& value) const{
|
|
|
|
std::map<std::string, bool>::const_iterator it;
|
|
if((it = mKvBool.find(key)) == mKvBool.end())
|
|
return false;
|
|
|
|
value = it->second;
|
|
return true;
|
|
}
|
|
|
|
bool ContentValue::getAsInt32(const std::string &key, int32_t& value) const{
|
|
|
|
std::map<std::string, int32_t>::const_iterator it;
|
|
if((it = mKvInt32.find(key)) == mKvInt32.end())
|
|
return false;
|
|
|
|
value = it->second;
|
|
return true;
|
|
}
|
|
|
|
bool ContentValue::getAsInt64(const std::string &key, int64_t& value) const{
|
|
|
|
std::map<std::string, int64_t>::const_iterator it;
|
|
if((it = mKvInt64.find(key)) == mKvInt64.end())
|
|
return false;
|
|
|
|
value = it->second;
|
|
return true;
|
|
}
|
|
|
|
bool ContentValue::getAsString(const std::string &key, std::string &value) const{
|
|
|
|
std::map<std::string, std::string>::const_iterator it;
|
|
if((it = mKvString.find(key)) == mKvString.end())
|
|
return false;
|
|
|
|
value = it->second;
|
|
return true;
|
|
}
|
|
|
|
bool ContentValue::getAsData(const std::string& key, uint32_t &len, char*& value) const{
|
|
|
|
std::map<std::string, std::pair<uint32_t, char*> >::const_iterator it;
|
|
if((it = mKvData.find(key)) == mKvData.end())
|
|
return false;
|
|
|
|
const std::pair<uint32_t, char*> &kvRef = it->second;
|
|
|
|
len = kvRef.first;
|
|
value = kvRef.second;
|
|
return true;
|
|
}
|
|
|
|
bool ContentValue::getAsDouble(const std::string &key, double& value) const{
|
|
|
|
std::map<std::string, double>::const_iterator it;
|
|
if((it = mKvDouble.find(key)) == mKvDouble.end())
|
|
return false;
|
|
|
|
value = it->second;
|
|
return true;
|
|
}
|
|
|
|
bool ContentValue::removeKeyValue(const std::string &key){
|
|
|
|
std::map<std::string, uint8_t>::iterator mit;
|
|
|
|
if((mit = mKvSet.find(key)) == mKvSet.end())
|
|
return false;
|
|
|
|
if(mit->second == BOOL_TYPE)
|
|
mKvBool.erase(key);
|
|
|
|
if(mit->second == INT64_TYPE)
|
|
mKvInt64.erase(key);
|
|
|
|
if(mit->second == DATA_TYPE){
|
|
delete[] (mKvData[key].second);
|
|
mKvData.erase(key);
|
|
}
|
|
|
|
if(mit->second == DOUBLE_TYPE)
|
|
mKvDouble.erase(key);
|
|
|
|
if(mit->second == STRING_TYPE)
|
|
mKvString.erase(key);
|
|
|
|
if(mit->second == INT32_TYPE)
|
|
mKvInt32.erase(key);
|
|
|
|
|
|
mKvSet.erase(key);
|
|
return true;
|
|
}
|
|
|
|
|
|
void ContentValue::getKeyTypeMap(std::map<std::string, uint8_t> &keySet) const {
|
|
keySet = mKvSet;
|
|
}
|
|
|
|
void ContentValue::clear(){
|
|
mKvSet.clear();
|
|
mKvBool.clear();
|
|
mKvDouble.clear();
|
|
mKvString.clear();
|
|
mKvInt32.clear();
|
|
mKvInt64.clear();
|
|
clearData();
|
|
}
|
|
|
|
bool ContentValue::empty() const{
|
|
return mKvSet.empty();
|
|
}
|
|
|
|
void ContentValue::clearData(){
|
|
|
|
std::map<std::string, std::pair<uint32_t, char*> >::iterator
|
|
mit = mKvData.begin();
|
|
|
|
for(; mit != mKvData.end(); ++mit){
|
|
|
|
if(mit->second.first != 0)
|
|
delete[] (mit->second.second);
|
|
}
|
|
|
|
mKvData.clear();
|
|
}
|
|
|
|
|
|
|