TarsCloud_TarsCpp/servant/tup/tup.h

757 lines
18 KiB
C
Raw Normal View History

2020-02-07 13:50:04 +08:00
/**
2018-09-05 11:26:21 +08:00
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
#ifndef _WUP_H_
#define _WUP_H_
#include <map>
#include <string>
#include <vector>
#include <sstream>
//支持iphone
#ifdef __APPLE__
#include "RequestF.h"
#elif defined ANDROID // android
#include "RequestF.h"
#else
#include "tup/RequestF.h"
#endif
2020-01-27 20:13:21 +08:00
// #ifdef __GNUC__
// # if __GNUC__ >3 || __GNUC_MINOR__ > 3
// # include <ext/pool_allocator.h>
// # endif
// #endif
2018-09-05 11:26:21 +08:00
using namespace std;
using namespace tars;
namespace tup
{
//存放tars返回值的key
const string STATUS_RESULT_CODE = "STATUS_RESULT_CODE";
const string STATUS_RESULT_DESC = "STATUS_RESULT_DESC";
/////////////////////////////////////////////////////////////////////////////////
// 属性封装类
template<typename TWriter = BufferWriter, typename TReader = BufferReader,template<typename> class Alloc = std::allocator >
//template<typename> class Alloc = __gnu_cxx::__pool_alloc >
class UniAttribute
{
typedef vector<char,Alloc<char> > VECTOR_CHAR_TYPE;
2018-12-11 19:20:27 +08:00
typedef map<string, VECTOR_CHAR_TYPE, less<string>,Alloc< pair<const string,VECTOR_CHAR_TYPE > > > VECTOR_CHAR_IN_MAP_TYPE;
typedef map<string, VECTOR_CHAR_IN_MAP_TYPE, less<string>,Alloc< pair<const string,VECTOR_CHAR_IN_MAP_TYPE > > > WUP_DATA_TYPE;
2018-09-05 11:26:21 +08:00
public:
/**
*
*/
UniAttribute()
{
_iVer = 3;
}
void setVersion(short iVer)
{
_iVer = iVer;
}
/**
*
*
* @param T:
* @param name:
* @param t:
*/
template<typename T> void put(const string& name, const T& t)
{
os.reset();
os.write(t, 0);
VECTOR_CHAR_TYPE & v = _data[name];
2020-02-07 14:55:31 +08:00
os.swap(v);
// v.assign(os.getBuffer(), os.getBuffer() + os.getLength());
2018-09-05 11:26:21 +08:00
}
void putUnknown(const string& name, const string& value)
{
os.reset();
os.writeUnknownV2(value);
VECTOR_CHAR_TYPE & v = _data[name];
2020-02-07 14:55:31 +08:00
os.swap(v);
// v.assign(os.getBuffer(), os.getBuffer() + os.getLength());
2018-09-05 11:26:21 +08:00
}
void getUnknown(const string& name, string& value)
{
typename VECTOR_CHAR_IN_MAP_TYPE::iterator mit;
mit = _data.find(name);
if (mit != _data.end() && mit->second.size()>2)
{
//去掉DataHead::eStructBegin,DataHead::eStructEnd
value = string(&mit->second[0]+1, mit->second.size()-2);
return;
}
throw runtime_error(string("UniAttribute not found key:") + name);
}
/**
*
*
* @throw runtime_error
* @param T:
* @param name:
* @param t:
*/
template<typename T> void get(const string& name, T& t)
{
typename VECTOR_CHAR_IN_MAP_TYPE::iterator mit;
mit = _data.find(name);
if (mit != _data.end())
{
is.reset();
is.setBuffer(mit->second);
is.read(t, 0, true);
return;
}
throw runtime_error(string("UniAttribute not found key:") + name);
}
/**
*
*
* @throw runtime_error
* @param T:
* @param name:
* @return T:
*/
template<typename T> T get(const string& name)
{
T t;
get<T>(name, t);
return t;
}
/**
*
*
* @param T:
* @param name:
* @param t:
* @param def:
*/
template<typename T> void getByDefault(const string& name, T& t, const T& def)
{
try
{
get<T>(name, t);
}
catch (runtime_error& e)
{
t = def;
}
}
/**
* (def为缺省值)
*
* @param T:
* @param name:
* @param:
* @return T:
*/
template<typename T> T getByDefault(const string& name, const T& def)
{
T t;
getByDefault<T>(name, t, def);
return t;
}
/**
*
*/
void clear()
{
_data.clear();
}
/** 编码
*
* @param buff
*/
void encode(string& buff)
{
os.reset();
os.write(_data, 0);
2020-02-07 14:55:31 +08:00
os.swap(buff);
// buff.assign(os.getBuffer(), os.getLength());
2018-09-05 11:26:21 +08:00
}
/** 编码
*
* @param buff
*/
void encode(vector<char>& buff)
{
os.reset();
os.write(_data, 0);
2020-02-07 14:55:31 +08:00
os.swap(buff);
// buff.assign(os.getBuffer(), os.getBuffer() + os.getLength());
2018-09-05 11:26:21 +08:00
}
/** 编码
*
* @throw runtime_error
* @param buffbuffer指针
* @param len buff长度
*/
void encode(char* buff, size_t & len)
{
os.reset();
os.write(_data, 0);
if(len < os.getLength()) throw runtime_error("encode error, buffer length too short");
memcpy(buff, os.getBuffer(), os.getLength());
len = os.getLength();
}
/** 解码
*
* @throw runtime_error
* @param buffbuffer指针
* @param len
*/
void decode(const char* buff, size_t len)
{
is.reset();
is.setBuffer(buff, len);
_data.clear();
is.read(_data, 0, true);
}
/**
*
*
* @throw runtime_error
* @param buff
*/
void decode(const vector<char>& buff)
{
is.reset();
is.setBuffer(buff);
_data.clear();
is.read(_data, 0, true);
}
/**
*
*
* @return const map<string,map<string,vector<char>>>& : map
*/
const map<string, vector<char> >& getData() const
{
return _data;
}
/**
*
*
* @return bool:
*/
bool isEmpty()
{
return _data.empty();
}
/**
*
*
* @return size_t:
*/
size_t size()
{
return _data.size();
}
/**
*
*
* @param key:
* @return bool:
*/
bool containsKey(const string & key)
{
return _data.find(key) != _data.end();
}
protected:
VECTOR_CHAR_IN_MAP_TYPE _data;
short _iVer;
public:
TarsInputStream<TReader> is;
TarsOutputStream<TWriter> os;
};
/////////////////////////////////////////////////////////////////////////////////
// 请求、回应包封装类
template<typename TWriter = BufferWriter, typename TReader = BufferReader,template<typename> class Alloc = std::allocator >
struct UniPacket : protected RequestPacket, public UniAttribute<TWriter, TReader, Alloc>
{
public:
/**
*
*/
UniPacket()
{
iVersion = 3; cPacketType = 0;
iMessageType = 0; iRequestId = 0;
sServantName = ""; sFuncName = "";
iTimeout = 0; sBuffer.clear();
context.clear(); status.clear();
UniAttribute<TWriter, TReader,Alloc>::_iVer = iVersion;
UniAttribute<TWriter, TReader,Alloc>::_data.clear();
UniAttribute<TWriter, TReader,Alloc>::_data.clear();
}
/**
*
* @param tup
*/
UniPacket(const UniPacket &tup) { *this = tup;}
void setVersion(short iVer)
{
UniAttribute<TWriter, TReader,Alloc>::_iVer = iVer;
iVersion = iVer;
}
/**
*
*
* @return UniPacket
*/
UniPacket createResponse()
{
UniPacket respPacket;
respPacket.sServantName = sServantName;
respPacket.sFuncName = sFuncName;
respPacket.iRequestId = iRequestId;
return respPacket;
}
/**
* 4
*
* @throw runtime_error
* @param buff
*/
void encode(string& buff)
{
2020-02-07 14:55:31 +08:00
encodeBuff<string>(buff);
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// TarsOutputStream<TWriter> &os = UniAttribute<TWriter, TReader,Alloc>::os;
// os.reset();
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// doEncode(os);
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// tars::Int32 iHeaderLen = htonl(sizeof(tars::Int32) + os.getLength());
// buff.assign((const char*)&iHeaderLen, sizeof(tars::Int32));
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// buff.append(os.getBuffer(), os.getLength());
2018-09-05 11:26:21 +08:00
}
/**
* 4
*
* @throw runtime_error
* @param buff
*/
void encode(vector<char>& buff)
{
2020-02-07 14:55:31 +08:00
encodeBuff<vector<char>>(buff);
// TarsOutputStream<TWriter> & os = UniAttribute<TWriter, TReader,Alloc>::os;
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// os.reset();
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// doEncode(os);
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// tars::Int32 iHeaderLen = htonl(sizeof(tars::Int32) + os.getLength());
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
// buff.resize(sizeof(tars::Int32) + os.getLength());
// memcpy(&buff[0], &iHeaderLen, sizeof(tars::Int32));
// memcpy(&buff[sizeof(tars::Int32)], os.getBuffer(), os.getLength());
2018-09-05 11:26:21 +08:00
}
/**
* 4
* @throw runtime_error
* @param buffbuffer指针
* @param len buff长度
*/
void encode(char* buff, size_t & len)
{
2020-02-07 14:55:31 +08:00
TarsOutputStream<TWriter>& os = UniAttribute<TWriter, TReader>::os;
2018-09-05 11:26:21 +08:00
os.reset();
doEncode(os);
2020-02-07 14:55:31 +08:00
os.reset();
writeTo(os);
2018-09-05 11:26:21 +08:00
tars::Int32 iHeaderLen = htonl(sizeof(tars::Int32) + os.getLength());
2020-02-07 14:55:31 +08:00
if (len < sizeof(tars::Int32) + os.getLength()) throw runtime_error("encode error, buffer length too short");
2018-09-05 11:26:21 +08:00
memcpy(buff, &iHeaderLen, sizeof(tars::Int32));
memcpy(buff + sizeof(tars::Int32), os.getBuffer(), os.getLength());
len = sizeof(tars::Int32) + os.getLength();
2020-02-07 14:55:31 +08:00
// TarsOutputStream<TWriter> &os = UniAttribute<TWriter, TReader,Alloc>::os;
// os.reset();
// doEncode(os);
// tars::Int32 iHeaderLen = htonl(sizeof(tars::Int32) + os.getLength());
// if(len < sizeof(tars::Int32) + os.getLength()) throw runtime_error("encode error, buffer length too short");
// memcpy(buff, &iHeaderLen, sizeof(tars::Int32));
// memcpy(buff + sizeof(tars::Int32), os.getBuffer(), os.getLength());
// len = sizeof(tars::Int32) + os.getLength();
2018-09-05 11:26:21 +08:00
}
/** 解码
*
* @throw runtime_error
* @param buffbuffer指针
* @param len
*/
void decode(const char* buff, size_t len)
{
2020-02-07 14:55:31 +08:00
if(len < sizeof(tars::Int32)) throw runtime_error("packet length too short, first 4 bytes must be buffer length.");
2018-09-05 11:26:21 +08:00
TarsInputStream<TReader> &is = UniAttribute<TWriter, TReader,Alloc>::is;
is.reset();
is.setBuffer(buff + sizeof(tars::Int32), len - sizeof(tars::Int32));
readFrom(is);
UniAttribute<TWriter, TReader,Alloc>::_iVer = iVersion;
is.reset();
is.setBuffer(sBuffer);
UniAttribute<TWriter, TReader,Alloc>::_data.clear();
is.read(UniAttribute<TWriter, TReader,Alloc>::_data, 0, true);
}
public:
/**
* version
* @return tars::Short
*/
tars::Short getVersion() const { return iVersion; }
/**
* ID
* @return tars::Int32
*/
tars::Int32 getRequestId() const { return iRequestId; }
/**
* ID
* @param value
*/
void setRequestId(tars::Int32 value) { iRequestId = value; }
/**
*
* @return const std::string&
*/
const std::string& getServantName() const { return sServantName; }
/**
*
* @param value
*/
void setServantName(const std::string& value) { sServantName = value; }
/**
*
* @return const std::string&
*/
const std::string& getFuncName() const { return sFuncName; }
/**
*
* @param value
*/
void setFuncName(const std::string& value) { sFuncName = value; }
protected:
2020-02-07 14:55:31 +08:00
template<typename T>
void encodeBuff(T& buff)
{
TarsOutputStream<TWriter>& os = UniAttribute<TWriter, TReader>::os;
os.reset();
doEncode(os);
os.reset();
tars::Int32 iHeaderLen = 0;
// 先预留4个字节长度
os.writeBuf((const char *)&iHeaderLen, sizeof(iHeaderLen));
writeTo(os);
os.swap(buff);
assert(buff.size() >= 4);
iHeaderLen = htonl((int)(buff.size()));
memcpy(&buff[0], (const char *)&iHeaderLen, sizeof(iHeaderLen));
}
2018-09-05 11:26:21 +08:00
/**
*
*/
void doEncode(TarsOutputStream<TWriter>& os)
{
//ServantName、FuncName不能为空
2020-02-07 14:55:31 +08:00
if (sServantName.empty()) throw runtime_error("ServantName must not be empty");
if (sFuncName.empty()) throw runtime_error("FuncName must not be empty");
2018-09-05 11:26:21 +08:00
os.reset();
2020-02-07 14:55:31 +08:00
os.write(UniAttribute<TWriter, TReader>::_data, 0);
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
os.swap(sBuffer);
2018-09-05 11:26:21 +08:00
2020-02-07 14:55:31 +08:00
os.reset();
2018-09-05 11:26:21 +08:00
}
2020-02-07 14:55:31 +08:00
// /**
// * 内部编码
// */
// void doEncode(TarsOutputStream<TWriter>& os)
// {
// //ServantName、FuncName不能为空
// if(sServantName.empty()) throw runtime_error("ServantName must not be empty");
// if(sFuncName.empty()) throw runtime_error("FuncName must not be empty");
// os.reset();
// os.write(UniAttribute<TWriter, TReader,Alloc>::_data, 0);
// sBuffer.assign(os.getBuffer(), os.getBuffer() + os.getLength());
// os.reset();
// writeTo(os);
// }
2018-09-05 11:26:21 +08:00
};
/////////////////////////////////////////////////////////////////////////////////
// 调用TARS的服务时使用的类
template<typename TWriter = BufferWriter, typename TReader = BufferReader,template<typename> class Alloc = std::allocator>
struct TarsUniPacket: public UniPacket<TWriter, TReader,Alloc>
{
public:
TarsUniPacket(){};
TarsUniPacket(const UniPacket<TWriter, TReader,Alloc> &tup)
: UniPacket<TWriter, TReader,Alloc>(tup) {};
/**
*
* @param value
*/
void setTarsVersion(tars::Short value) { UniPacket<TWriter, TReader,Alloc>::setVersion(value); }
/**
*
* @param value
*/
void setTarsPacketType(tars::Char value) { this->cPacketType = value; }
/**
*
* @param value
*/
void setTarsMessageType(tars::Int32 value) { this->iMessageType = value; }
/**
*
* @param value
*/
void setTarsTimeout(tars::Int32 value) { this->iTimeout = value; }
/**
*
* @param value
*/
void setTarsBuffer(const vector<tars::Char>& value) { this->sBuffer = value; }
/**
*
* @param value
*/
void setTarsContext(const map<std::string, std::string>& value) { this->context = value; }
/**
*
* @param value
*/
void setTarsStatus(const map<std::string, std::string>& value) { this->status = value; }
/**
*
* @return tars::Short
*/
tars::Short getTarsVersion() const { return this->iVersion; }
/**
*
* @return tars::Char
*/
tars::Char getTarsPacketType() const { return this->cPacketType; }
/**
*
* @return tars::Int32
*/
tars::Int32 getTarsMessageType() const { return this->iMessageType; }
/**
*
* @return tars::Int32
*/
tars::Int32 getTarsTimeout() const { return this->iTimeout; }
/**
*
* @return const vector<tars::Char>&
*/
const vector<tars::Char>& getTarsBuffer() const { return this->sBuffer; }
/**
*
* @return const map<std::string,std::string>&
*/
const map<std::string, std::string>& getTarsContext() const { return this->context; }
/**
*
* @return const map<std::string,std::string>&
*/
const map<std::string, std::string>& getTarsStatus() const { return this->status; }
/**
* tars的返回值
*
* @retrun tars::Int32
*/
tars::Int32 getTarsResultCode() const
{
map<std::string, std::string>::const_iterator it;
if((it = this->status.find(STATUS_RESULT_CODE)) == this->status.end())
{
return 0;
}
else
{
return atoi(it->second.c_str());
}
}
/**
* tars的返回描述
*
* @retrun string
*/
string getTarsResultDesc() const
{
map<std::string, std::string>::const_iterator it;
if((it = this->status.find(STATUS_RESULT_DESC)) == this->status.end())
{
return "";
}
else
{
return it->second;
}
}
};
2020-01-27 20:13:21 +08:00
// #ifdef __GNUC__
// # if __GNUC__ >3 || __GNUC_MINOR__ > 3
// typedef UniAttribute<BufferWriter,BufferReader, __gnu_cxx::__pool_alloc> UniAttrPoolAlloc;
// typedef UniPacket<BufferWriter,BufferReader, __gnu_cxx::__pool_alloc> UniPacketPoolAlloc;
// typedef TarsUniPacket<BufferWriter,BufferReader, __gnu_cxx::__pool_alloc> TarsUniPacketPoolAlloc;
// # endif
// #endif
2018-09-05 11:26:21 +08:00
}
////////////////////////////////////////////////////////////////////////////////////////////////
#endif