mirror of
https://gitee.com/TarsCloud/TarsCpp.git
synced 2024-12-22 22:16:38 +08:00
Merge branch 'master' of https://github.com/forrestlinfeng/TarsCpp into forrestlinfeng-master
This commit is contained in:
commit
84c14951cb
780
servant/tup/TarsXml.h
Executable file
780
servant/tup/TarsXml.h
Executable file
@ -0,0 +1,780 @@
|
||||
#ifndef __TARS_XML_H__
|
||||
#define __TARS_XML_H__
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "util/tc_xml.h"
|
||||
#include "util/tc_common.h"
|
||||
|
||||
namespace tars
|
||||
{
|
||||
class XmlInput
|
||||
{
|
||||
public:
|
||||
static void readXml(Bool& b, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
b = TC_Common::lower(XmlValueStringPtr::dynamicCast(p)->value) == "true";
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Bool' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(Char& c, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
c = TC_Common::strto<Char>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Char' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(UInt8& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<UInt8>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Uint8' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(Short& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<Short>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Short' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(UInt16& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<UInt16>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Uint16' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(Int32& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<Int32>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Int32' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(UInt32& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<UInt32>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'UInt32' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(Int64& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<Int64>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Int64' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(Float& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<Float>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Float' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(Double& n, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
n = TC_Common::strto<Double>(XmlValueStringPtr::dynamicCast(p)->value);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Double' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(std::string& s, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
s = XmlValueStringPtr::dynamicCast(p)->value;
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'string' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void readXml(char *buf, const UInt32 bufLen, UInt32 & readLen, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeString)
|
||||
{
|
||||
XmlValueStringPtr pString=XmlValueStringPtr::dynamicCast(p);
|
||||
if((UInt32)pString->value.size()>bufLen)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "invalid char * size, size: %u", (UInt32)pString->value.size());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
memcpy(buf,pString->value.c_str(),pString->value.size());
|
||||
readLen = pString->value.size();
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'char *' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<string, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<string, V> pr;
|
||||
pr.first=iter->first;
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<bool, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<bool, V> pr;
|
||||
pr.first=TC_Common::strto<bool>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<Char, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<Char, V> pr;
|
||||
pr.first=TC_Common::strto<Int32>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<UInt8, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<UInt8, V> pr;
|
||||
pr.first=TC_Common::strto<UInt8>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<Short, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<Short, V> pr;
|
||||
pr.first=TC_Common::strto<Short>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<UInt16, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<UInt16, V> pr;
|
||||
pr.first=TC_Common::strto<UInt16>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<Int32, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<Int32, V> pr;
|
||||
pr.first=TC_Common::strto<Int32>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<UInt32, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<UInt32, V> pr;
|
||||
pr.first=TC_Common::strto<UInt32>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<Int64, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<Int64, V> pr;
|
||||
pr.first=TC_Common::strto<Int64>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<Float, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<Float, V> pr;
|
||||
pr.first=TC_Common::strto<Float>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<Double, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
map<string,XmlValuePtr>::iterator iter;
|
||||
iter=pObj->value.begin();
|
||||
for(;iter!=pObj->value.end();++iter)
|
||||
{
|
||||
std::pair<Double, V> pr;
|
||||
pr.first=TC_Common::strto<Double>(iter->first);
|
||||
readXml(pr.second,iter->second);
|
||||
m.insert(pr);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'map' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename K, typename V, typename Cmp, typename Alloc>
|
||||
static void readXml(std::map<K, V, Cmp, Alloc>& m, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "map key is not Basic type. map key is only string|bool|num");
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static void readXml(std::vector<T, Alloc>& v, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if (NULL != p.get() && p->getType() == eXmlTypeArray)
|
||||
{
|
||||
XmlValueArrayPtr pArray=XmlValueArrayPtr::dynamicCast(p);
|
||||
v.resize(pArray->value.size());
|
||||
for(size_t i=0;i<pArray->value.size();++i)
|
||||
{
|
||||
readXml(v[i],pArray->value[i]);
|
||||
}
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'vector' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
/// 读取结构数组
|
||||
template<typename T>
|
||||
static void readXml(T* v, const UInt32 len, UInt32 & readLen, const XmlValuePtr & p, bool isRequire = true)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeArray)
|
||||
{
|
||||
XmlValueArrayPtr pArray=XmlValueArrayPtr::dynamicCast(p);
|
||||
if(pArray->value.size()>len)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'T *' invalid size, size: %u", (uint32_t)pArray->value.size());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
for(size_t i=0;i<pArray->value.size();++i)
|
||||
{
|
||||
readXml(v[i],pArray->value[i]);
|
||||
}
|
||||
readLen=pArray->value.size();
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'T *' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void readXml(T& v, const XmlValuePtr & p, bool isRequire = true, typename detail::disable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
|
||||
{
|
||||
Int32 n = 0;
|
||||
readXml(n, p, isRequire);
|
||||
v = (T) n;
|
||||
}
|
||||
|
||||
/// 读取结构
|
||||
template<typename T>
|
||||
static void readXml(T& v, const XmlValuePtr & p, bool isRequire = true, typename detail::enable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
|
||||
{
|
||||
if(NULL != p.get() && p->getType() == eXmlTypeObj)
|
||||
{
|
||||
XmlValueObjPtr pObj=XmlValueObjPtr::dynamicCast(p);
|
||||
v.readFromXml(pObj);
|
||||
}
|
||||
else if (isRequire)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "read 'Char' type mismatch, get type: %d.", p->getType());
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class XmlOutput
|
||||
{
|
||||
public:
|
||||
static XmlValueStringPtr writeXml(Bool b, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(b ? "true" : "false", cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(Char n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(UInt8 n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(Short n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(UInt16 n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(Int32 n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(UInt32 n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(Int64 n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(Float n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(Double n, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(TC_Common::tostr(n), cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(const std::string& s, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(s, cdata));
|
||||
}
|
||||
|
||||
static XmlValueStringPtr writeXml(const char *buf, const UInt32 len, bool cdata = false)
|
||||
{
|
||||
return (new XmlValueString(string(buf,len), cdata));
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<string, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<string, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[i->first]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<Bool, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<Bool, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<Char, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<Char, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr((Int32)i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<UInt8, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<UInt8, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<Short, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<Short, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<UInt16, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<UInt16, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<Int32, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<Int32, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<UInt32, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<UInt32, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<Int64, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<Int64, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<Float, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<Float, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<Double, V, Cmp, Alloc>& m)
|
||||
{
|
||||
XmlValueObjPtr pObj=new XmlValueObj();
|
||||
typedef typename std::map<Double, V, Cmp, Alloc>::const_iterator IT;
|
||||
for (IT i = m.begin(); i != m.end(); ++i)
|
||||
{
|
||||
pObj->value[TC_Common::tostr(i->first)]=writeXml(i->second);
|
||||
}
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template<typename K, typename V, typename Cmp, typename Alloc>
|
||||
static XmlValueObjPtr writeXml(const std::map<K, V, Cmp, Alloc>& m)
|
||||
{
|
||||
char s[128];
|
||||
snprintf(s, sizeof(s), "map key is not Basic type. map key is only string|bool|num");
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static XmlValueArrayPtr writeXml(const std::vector<T, Alloc>& v)
|
||||
{
|
||||
XmlValueArrayPtr pArray=new XmlValueArray();
|
||||
typedef typename std::vector<T, Alloc>::const_iterator IT;
|
||||
for (IT i = v.begin(); i != v.end(); ++i)
|
||||
pArray->value.push_back(writeXml(*i));
|
||||
return pArray;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static XmlValueArrayPtr writeXml(const T *v, const UInt32 len)
|
||||
{
|
||||
XmlValueArrayPtr pArray=new XmlValueArray();
|
||||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
pArray->value.push_back(writeXml(v[i]));
|
||||
}
|
||||
return pArray;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static XmlValueStringPtr writeXml(const T& v, typename detail::disable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
|
||||
{
|
||||
return writeXml((Int32) v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static XmlValueObjPtr writeXml(const T& v, typename detail::enable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
|
||||
{
|
||||
return v.writeToXml();
|
||||
}
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
|
||||
#endif
|
3
tools/CMakeLists.txt
Normal file → Executable file
3
tools/CMakeLists.txt
Normal file → Executable file
@ -11,7 +11,7 @@ function(tars2language TARGET)
|
||||
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/bin)
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/tarsparse)
|
||||
|
||||
@ -38,6 +38,7 @@ add_subdirectory(tars2oc)
|
||||
add_subdirectory(tars2php)
|
||||
add_subdirectory(tars2android)
|
||||
add_subdirectory(tars2node)
|
||||
add_subdirectory(tars2case)
|
||||
|
||||
IF(TARS_PROTOBUF)
|
||||
add_subdirectory(pb2tarscpp)
|
||||
|
1
tools/README.md
Normal file → Executable file
1
tools/README.md
Normal file → Executable file
@ -17,4 +17,5 @@ tars2php | Source code implementation of IDL tool for generating PHP code t
|
||||
tars2python | Source code implementation of IDL tool for generating Python code through tars file
|
||||
tars2node | Source code implementation of IDL tool for generating Node.js code through tars file
|
||||
tars2android | Source code implementation of IDL tool for generating Android code through tars file
|
||||
tars2case | Generate test case for tars server
|
||||
pb2tarscpp | Generate protoc plugin source code for tars C++ code via proto file
|
||||
|
1
tools/README.zh.md
Normal file → Executable file
1
tools/README.zh.md
Normal file → Executable file
@ -15,4 +15,5 @@ tars2php | 通过tars文件生成 PHP 代码的IDL工具的源码实现
|
||||
tars2python | 通过tars文件生成 Python 代码的IDL工具的源码实现
|
||||
tars2node | 通过tars文件生成 Node.js 代码的IDL工具的源码实现
|
||||
tars2android | 通过tars文件生成 Android 代码的IDL工具的源码实现
|
||||
tars2case | 通过tars文件生成 tars 服务生成测试用例
|
||||
pb2tarscpp | 通过proto文件生成tars C++ 代码的protoc插件源码实现
|
||||
|
1
tools/tars2case/CMakeLists.txt
Executable file
1
tools/tars2case/CMakeLists.txt
Executable file
@ -0,0 +1 @@
|
||||
tars2language("tars2case")
|
105
tools/tars2case/main.cpp
Executable file
105
tools/tars2case/main.cpp
Executable file
@ -0,0 +1,105 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "util/tc_file.h"
|
||||
#include "util/tc_option.h"
|
||||
|
||||
#include "tars2case.h"
|
||||
|
||||
void usage()
|
||||
{
|
||||
cout << "Usage : tars2case [OPTION] tarsfile" << endl;
|
||||
cout << " --dir=DIRECTORY generate source file to DIRECTORY(create tars protocol file to DIRECTORY, default is current directory)" << endl;
|
||||
|
||||
cout << endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void check(vector<string> &vTars)
|
||||
{
|
||||
for(size_t i = 0; i < vTars.size(); i++)
|
||||
{
|
||||
string ext = TC_File::extractFileExt(vTars[i]);
|
||||
if(ext == "tars")
|
||||
{
|
||||
if(!TC_File::isFileExist(vTars[i]))
|
||||
{
|
||||
cerr << "file '" << vTars[i] << "' not exists" << endl;
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "only support tars file." << endl;
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void doTars2Test(TC_Option& option, const vector<string>& vTars)
|
||||
{
|
||||
Tars2Case j2t;
|
||||
//设置生成文件的根目录
|
||||
if (option.getValue("dir") != "")
|
||||
{
|
||||
j2t.setBaseDir(option.getValue("dir"));
|
||||
}
|
||||
else
|
||||
{
|
||||
j2t.setBaseDir(".");
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < vTars.size(); i++)
|
||||
{
|
||||
g_parse->parse(vTars[i]);
|
||||
j2t.createFile(vTars[i], option.getValue("out"));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
TC_Option option;
|
||||
option.decode(argc, argv);
|
||||
vector<string> vTars = option.getSingle();
|
||||
|
||||
check(vTars);
|
||||
::chdir(TC_File::extractFilePath(vTars[0]).c_str());
|
||||
if (option.hasParam("help"))
|
||||
{
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
doTars2Test(option, vTars);
|
||||
}
|
||||
catch(exception& e)
|
||||
{
|
||||
cerr<<e.what()<<endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
551
tools/tars2case/tars2case.cpp
Executable file
551
tools/tars2case/tars2case.cpp
Executable file
@ -0,0 +1,551 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "tars2case.h"
|
||||
#include "util/tc_md5.h"
|
||||
#include "util/tc_file.h"
|
||||
#include "util/tc_common.h"
|
||||
#include <string>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
Tars2Case::Tars2Case()
|
||||
{
|
||||
}
|
||||
|
||||
string Tars2Case::toStr(const TypePtr &pPtr) const
|
||||
{
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
|
||||
if (bPtr) return tostrBuiltin(bPtr);
|
||||
|
||||
VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
|
||||
if (vPtr) return tostrVector(vPtr);
|
||||
|
||||
MapPtr mPtr = MapPtr::dynamicCast(pPtr);
|
||||
if (mPtr) return tostrMap(mPtr);
|
||||
|
||||
StructPtr sPtr = StructPtr::dynamicCast(pPtr);
|
||||
if (sPtr) return tostrStruct(sPtr);
|
||||
|
||||
EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
|
||||
if (ePtr) return tostrEnum(ePtr);
|
||||
|
||||
if (!pPtr) return "void";
|
||||
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
string Tars2Case::toCase(const TypePtr &pPtr, const string& varName) const
|
||||
{
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
|
||||
if (bPtr) return tocaseBuiltin(bPtr, varName);
|
||||
|
||||
VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
|
||||
if (vPtr) return tocaseVector(vPtr, varName);
|
||||
|
||||
MapPtr mPtr = MapPtr::dynamicCast(pPtr);
|
||||
if (mPtr) return tocaseMap(mPtr, varName);
|
||||
|
||||
StructPtr sPtr = StructPtr::dynamicCast(pPtr);
|
||||
if (sPtr) return tocaseStruct(sPtr, varName);
|
||||
|
||||
EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
|
||||
if (ePtr) return tocaseEnum(ePtr, varName);
|
||||
|
||||
if (!pPtr) return "void";
|
||||
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
|
||||
/*******************************BuiltinPtr********************************/
|
||||
string Tars2Case::tostrBuiltin(const BuiltinPtr &pPtr) const
|
||||
{
|
||||
string s;
|
||||
|
||||
switch (pPtr->kind())
|
||||
{
|
||||
case Builtin::KindBool:
|
||||
s = "bool";
|
||||
break;
|
||||
case Builtin::KindByte:
|
||||
s = pPtr->isUnsigned() ? "short" : "byte";
|
||||
break;
|
||||
case Builtin::KindShort:
|
||||
s = pPtr->isUnsigned() ? "int" : "short";
|
||||
break;
|
||||
case Builtin::KindInt:
|
||||
s = pPtr->isUnsigned() ? "long" : "int";
|
||||
break;
|
||||
case Builtin::KindLong:
|
||||
s = "long";
|
||||
break;
|
||||
case Builtin::KindFloat:
|
||||
s = "float";
|
||||
break;
|
||||
case Builtin::KindDouble:
|
||||
s = "double";
|
||||
break;
|
||||
case Builtin::KindString:
|
||||
s = "string";
|
||||
break;
|
||||
case Builtin::KindVector:
|
||||
s = "vector";
|
||||
break;
|
||||
case Builtin::KindMap:
|
||||
s = "map";
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
string Tars2Case::tocaseBuiltin(const BuiltinPtr &pPtr, const string& varName) const
|
||||
{
|
||||
string s;
|
||||
|
||||
switch (pPtr->kind())
|
||||
{
|
||||
case Builtin::KindBool:
|
||||
s = "true";
|
||||
break;
|
||||
case Builtin::KindByte:
|
||||
s = "0";
|
||||
break;
|
||||
case Builtin::KindShort:
|
||||
s = "0";
|
||||
break;
|
||||
case Builtin::KindInt:
|
||||
s = "0";
|
||||
break;
|
||||
case Builtin::KindLong:
|
||||
s = "0";
|
||||
break;
|
||||
case Builtin::KindFloat:
|
||||
s = "0.0";
|
||||
break;
|
||||
case Builtin::KindDouble:
|
||||
s = "0.00";
|
||||
break;
|
||||
case Builtin::KindString:
|
||||
s = "key";
|
||||
break;
|
||||
/*
|
||||
case Builtin::KindVector:
|
||||
s = "vector";
|
||||
break;
|
||||
case Builtin::KindMap:
|
||||
s = "map";
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
/*******************************VectorPtr********************************/
|
||||
string Tars2Case::tostrVector(const VectorPtr &pPtr) const
|
||||
{
|
||||
string s;
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
|
||||
s = "vector" + string("<") + toStr(pPtr->getTypePtr()) + ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
string Tars2Case::tocaseVector(const VectorPtr &pPtr, const string& varName) const
|
||||
{
|
||||
string s;
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
|
||||
s = string("<");
|
||||
for(int i = 0; i < 2; i++) {
|
||||
if(i != 0) {
|
||||
s += ",";
|
||||
}
|
||||
s += toCase(pPtr->getTypePtr(), varName);
|
||||
}
|
||||
s += ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
string Tars2Case::tostrMap(const MapPtr &pPtr, bool bNew) const
|
||||
{
|
||||
string s = "map";
|
||||
s += string("<") + toStr(pPtr->getLeftTypePtr()) + "," + toStr(pPtr->getRightTypePtr()) + ">";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
string Tars2Case::tocaseMap(const MapPtr &pPtr, const string& varName) const
|
||||
{
|
||||
string s = string("[");
|
||||
for(int i = 0; i < 2; i++) {
|
||||
if(i != 0) {
|
||||
s += ",";
|
||||
}
|
||||
s += toCase(pPtr->getLeftTypePtr(), varName) + "=" + toCase(pPtr->getRightTypePtr(), varName);
|
||||
}
|
||||
s += "]";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
string Tars2Case::tostrStruct(const StructPtr &pPtr) const
|
||||
{
|
||||
vector<TypeIdPtr>& members = pPtr->getAllMemberPtr();
|
||||
string s;
|
||||
|
||||
//是否生成tag和require等信息
|
||||
bool genTag = false;
|
||||
for(size_t i = 0; i < members.size(); i++) {
|
||||
TypeIdPtr typeId = members[i];
|
||||
if(!s.empty()) {
|
||||
s += ",";
|
||||
}
|
||||
|
||||
if(i == 0) {
|
||||
if(typeId->getTag() == 0) {
|
||||
genTag = false;
|
||||
}
|
||||
else {
|
||||
genTag = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//检查tag是否连续
|
||||
if(typeId->getTag() == members[i-1]->getTag() + 1) {
|
||||
genTag = false;
|
||||
}
|
||||
else {
|
||||
genTag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(genTag) {
|
||||
s+=genratePrefix(typeId) + " ";
|
||||
}
|
||||
|
||||
|
||||
s += toStr(typeId->getTypePtr());
|
||||
}
|
||||
return "struct<" + s + ">";
|
||||
}
|
||||
|
||||
string Tars2Case::tocaseStruct(const StructPtr &pPtr, const string& varName) const
|
||||
{
|
||||
vector<TypeIdPtr>& members = pPtr->getAllMemberPtr();
|
||||
string s = string("<");
|
||||
|
||||
for(size_t i = 0; i < members.size(); i++) {
|
||||
if(i != 0) {
|
||||
s += ",";
|
||||
}
|
||||
s += toCase(members[i]->getTypePtr(), varName);
|
||||
}
|
||||
s += ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
string Tars2Case::genratePrefix(const TypeIdPtr &ptr) const
|
||||
{
|
||||
string s = TC_Common::tostr(ptr->getTag()) + " ";
|
||||
if(ptr->isRequire()) {
|
||||
s += "require";
|
||||
}
|
||||
else {
|
||||
s += "optional";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
string Tars2Case::tostrEnum(const EnumPtr &pPtr) const
|
||||
{
|
||||
return "int";
|
||||
}
|
||||
|
||||
string Tars2Case::tocaseEnum(const EnumPtr &pPtr, const string& varName) const
|
||||
{
|
||||
return "19";
|
||||
}
|
||||
|
||||
|
||||
string Tars2Case::generateTest(const ParamDeclPtr &pPtr) const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
TypePtr typePtr = pPtr->getTypeIdPtr()->getTypePtr();
|
||||
s << toStr(typePtr);
|
||||
return s.str();
|
||||
}
|
||||
|
||||
string Tars2Case::generateCase(const ParamDeclPtr &pPtr) const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
TypePtr typePtr = pPtr->getTypeIdPtr()->getTypePtr();
|
||||
string varName = pPtr->getTypeIdPtr()->getId();
|
||||
s << toCase(typePtr, varName);
|
||||
return s.str();
|
||||
}
|
||||
|
||||
struct SortOperation
|
||||
{
|
||||
bool operator()(const OperationPtr &o1, const OperationPtr &o2)
|
||||
{
|
||||
return o1->getId() < o2->getId();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
string Tars2Case::generateTest(const InterfacePtr &pPtr, const string& outfile) const
|
||||
{
|
||||
ostringstream s;
|
||||
vector<OperationPtr>& vOperation = pPtr->getAllOperationPtr();
|
||||
std::sort(vOperation.begin(), vOperation.end(), SortOperation());
|
||||
|
||||
//生成客户端接口的声明
|
||||
TC_File::makeDirRecursive(_baseDir);
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
string sCase = "";
|
||||
string sInParams = "";
|
||||
string sOutParams = "";
|
||||
|
||||
vector<ParamDeclPtr>& vParamDecl = vOperation[i]->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
if(vParamDecl[j]->isOut()) {
|
||||
if(!sOutParams.empty()) {
|
||||
sOutParams += "|";
|
||||
}
|
||||
sOutParams += generateTest(vParamDecl[j]);
|
||||
}
|
||||
else {
|
||||
if(!sInParams.empty()) {
|
||||
sInParams += "|";
|
||||
}
|
||||
sInParams += generateTest(vParamDecl[j]);
|
||||
|
||||
//测试用例每个参数一行
|
||||
if(!sCase.empty()) {
|
||||
sCase += "\r\n";
|
||||
}
|
||||
sCase += generateCase(vParamDecl[j]);
|
||||
}
|
||||
}
|
||||
|
||||
ostringstream sc;
|
||||
sc << sInParams << endl << "#### 隔离符 ####" << endl << sCase << endl;
|
||||
string filecase = _baseDir + "/" + vOperation[i]->getId() + ".case";
|
||||
TC_File::save2file(filecase, sc.str());
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
JsonValuePtr Tars2Case::toJsonBuiltin(const BuiltinPtr &pPtr) const
|
||||
{
|
||||
JsonValuePtr p;
|
||||
switch (pPtr->kind())
|
||||
{
|
||||
case Builtin::KindBool:
|
||||
p = JsonOutput::writeJson(true);
|
||||
break;
|
||||
case Builtin::KindByte:
|
||||
p = JsonOutput::writeJson(8);
|
||||
break;
|
||||
case Builtin::KindShort:
|
||||
p = JsonOutput::writeJson(16);
|
||||
break;
|
||||
case Builtin::KindInt:
|
||||
p = JsonOutput::writeJson(32);
|
||||
break;
|
||||
case Builtin::KindLong:
|
||||
p = JsonOutput::writeJson(64);
|
||||
break;
|
||||
case Builtin::KindFloat:
|
||||
p = JsonOutput::writeJson(1.01);
|
||||
break;
|
||||
case Builtin::KindDouble:
|
||||
p = JsonOutput::writeJson((double)2.0000005);
|
||||
break;
|
||||
case Builtin::KindString:
|
||||
p = JsonOutput::writeJson(string("string"));
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
JsonValuePtr Tars2Case::toJsonEnum(const EnumPtr &pPtr) const
|
||||
{
|
||||
return JsonOutput::writeJson(string("int32"));
|
||||
}
|
||||
|
||||
JsonValueArrayPtr Tars2Case::toJsonVector(const VectorPtr &pPtr) const
|
||||
{
|
||||
JsonValueArrayPtr p = new JsonValueArray();
|
||||
|
||||
JsonValuePtr p1 = generateJson(pPtr->getTypePtr());
|
||||
p->push_back(p1);
|
||||
p->push_back(p1);
|
||||
return p;
|
||||
}
|
||||
|
||||
JsonValueObjPtr Tars2Case::toJsonMap(const MapPtr &pPtr) const
|
||||
{
|
||||
JsonValueObjPtr p = new JsonValueObj();
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getLeftTypePtr());
|
||||
if (bPtr)
|
||||
{
|
||||
p->value["key"] = generateJson(pPtr->getRightTypePtr());
|
||||
// p->value[tocaseBuiltin(bPtr, "")] = generateJson(pPtr->getRightTypePtr());
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
JsonValueObjPtr Tars2Case::toJsonStruct(const StructPtr &pPtr) const
|
||||
{
|
||||
JsonValueObjPtr p = new JsonValueObj();
|
||||
vector<TypeIdPtr>& members = pPtr->getAllMemberPtr();
|
||||
|
||||
//是否生成tag和require等信息
|
||||
for(size_t i = 0; i < members.size(); i++)
|
||||
{
|
||||
TypeIdPtr typeId = members[i];
|
||||
string keyName = typeId->getId();
|
||||
p->value[keyName] = generateJson(typeId->getTypePtr());
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
JsonValuePtr Tars2Case::generateJson(const TypePtr &pPtr) const
|
||||
{
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr);
|
||||
if (bPtr) return toJsonBuiltin(bPtr);
|
||||
|
||||
VectorPtr vPtr = VectorPtr::dynamicCast(pPtr);
|
||||
if (vPtr) return toJsonVector(vPtr);
|
||||
|
||||
MapPtr mPtr = MapPtr::dynamicCast(pPtr);
|
||||
if (mPtr) return toJsonMap(mPtr);
|
||||
|
||||
StructPtr sPtr = StructPtr::dynamicCast(pPtr);
|
||||
if (sPtr) return toJsonStruct(sPtr);
|
||||
|
||||
EnumPtr ePtr = EnumPtr::dynamicCast(pPtr);
|
||||
if (ePtr) return toJsonEnum(ePtr);
|
||||
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
string Tars2Case::generateJson(const InterfacePtr &pPtr, const string& outfile) const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
vector<OperationPtr>& vOperation = pPtr->getAllOperationPtr();
|
||||
std::sort(vOperation.begin(), vOperation.end(), SortOperation());
|
||||
|
||||
// 生成客户端接口的声明
|
||||
JsonValueArrayPtr v = new JsonValueArray();
|
||||
for (size_t i = 0; i < vOperation.size(); i++)
|
||||
{
|
||||
JsonValueObjPtr inParam = new JsonValueObj();
|
||||
JsonValueObjPtr outParam = new JsonValueObj();
|
||||
|
||||
vector<ParamDeclPtr>& vParamDecl = vOperation[i]->getAllParamDeclPtr();
|
||||
for (size_t j = 0; j < vParamDecl.size(); j++)
|
||||
{
|
||||
string sTypeName(vParamDecl[j]->getTypeIdPtr()->getId());
|
||||
if(vParamDecl[j]->isOut())
|
||||
{
|
||||
outParam->value[sTypeName] = generateJson(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
else
|
||||
{
|
||||
inParam->value[sTypeName] = generateJson(vParamDecl[j]->getTypeIdPtr()->getTypePtr());
|
||||
}
|
||||
}
|
||||
|
||||
JsonValueObjPtr p = new JsonValueObj();
|
||||
p->value["function"] = JsonOutput::writeJson(vOperation[i]->getId());
|
||||
p->value["funinput"] = inParam;
|
||||
p->value["funoutput"] = outParam;
|
||||
p->value["rettype"] = JsonOutput::writeJson(toStr(vOperation[i]->getReturnPtr()->getTypePtr()));
|
||||
|
||||
JsonValuePtr pp = p;
|
||||
v->push_back(pp);
|
||||
}
|
||||
|
||||
string filetest = _baseDir + "/" + (outfile.empty() ? pPtr->getId() : outfile) + ".json";
|
||||
TC_File::makeDirRecursive(_baseDir);
|
||||
TC_File::save2file(filetest, TC_Json::writeValue(v));
|
||||
|
||||
return TC_Json::writeValue(v);
|
||||
}
|
||||
|
||||
/******************************Tars2Case***************************************/
|
||||
|
||||
void Tars2Case::generateFile(const ContextPtr &pPtr, const string& outfile) const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
vector<NamespacePtr> namespaces = pPtr->getNamespaces();
|
||||
for (size_t i = 0; i < namespaces.size(); i++)
|
||||
{
|
||||
vector<InterfacePtr> &is = namespaces[i]->getAllInterfacePtr();
|
||||
for (size_t j = 0; j < is.size(); j++)
|
||||
{
|
||||
// 生成SRF TEST 测试用例的文件
|
||||
generateTest(is[j], outfile);
|
||||
|
||||
// 生成前台访问的JSON串
|
||||
generateJson(is[j], outfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tars2Case::createFile(const string &jcefile, const string& outfile)
|
||||
{
|
||||
std::vector<ContextPtr> contexts = g_parse->getContexts();
|
||||
for (size_t i = 0; i < contexts.size(); i++)
|
||||
{
|
||||
if (jcefile == contexts[i]->getFileName())
|
||||
{
|
||||
generateFile(contexts[i], outfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tars2Case::setBaseDir(const string &dir)
|
||||
{
|
||||
_baseDir = dir;
|
||||
}
|
||||
|
||||
string Tars2Case::getFilePath(const string &ns) const
|
||||
{
|
||||
return _baseDir + "/" + ns + "/";
|
||||
}
|
199
tools/tars2case/tars2case.h
Executable file
199
tools/tars2case/tars2case.h
Executable file
@ -0,0 +1,199 @@
|
||||
/**
|
||||
* 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 __TARS2CASE_H_
|
||||
#define __TARS2CASE_H_
|
||||
|
||||
#include "parse.h"
|
||||
#include "util/tc_common.h"
|
||||
#include "util/tc_option.h"
|
||||
#include "tup/Tars.h"
|
||||
#include "tup/TarsJson.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace tars;
|
||||
/**
|
||||
* 根据jce生成自动测试的字符串
|
||||
*/
|
||||
class Tars2Case
|
||||
{
|
||||
public:
|
||||
Tars2Case();
|
||||
|
||||
/**
|
||||
* 设置代码生成的根目录
|
||||
* @param dir
|
||||
*/
|
||||
void setBaseDir(const string &dir);
|
||||
|
||||
/**
|
||||
* 生成
|
||||
* @param file
|
||||
* @param isFramework 是否是框架
|
||||
*/
|
||||
void createFile(const string &jcefile, const string& outfile = "");
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 根据命名空间获取文件路径
|
||||
* @param ns 命名空间
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string getFilePath(const string &ns) const;
|
||||
|
||||
string _baseDir;
|
||||
|
||||
|
||||
//下面是类型描述的源码生成
|
||||
protected:
|
||||
|
||||
/**
|
||||
* 生成某类型的字符串描述源码
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string toStr(const TypePtr &pPtr) const;
|
||||
|
||||
/**
|
||||
* 生成内建类型的字符串源码
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string tostrBuiltin(const BuiltinPtr &pPtr) const;
|
||||
/**
|
||||
* 生成vector的字符串描述
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string tostrVector(const VectorPtr &pPtr) const;
|
||||
|
||||
/**
|
||||
* 生成map的字符串描述
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string tostrMap(const MapPtr &pPtr, bool bNew = false) const;
|
||||
|
||||
/**
|
||||
* 生成某种结构的符串描述
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string tostrStruct(const StructPtr &pPtr) const;
|
||||
|
||||
/**
|
||||
* 生成某种枚举的符串描述
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string tostrEnum(const EnumPtr &pPtr) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* 生成某类型的JSON描述源码
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
JsonValuePtr generateJson(const TypePtr &pPtr) const;
|
||||
|
||||
JsonValuePtr toJsonBuiltin(const BuiltinPtr &pPtr) const;
|
||||
|
||||
JsonValuePtr toJsonEnum(const EnumPtr &pPtr) const;
|
||||
|
||||
JsonValueObjPtr toJsonMap(const MapPtr &pPtr) const;
|
||||
|
||||
JsonValueObjPtr toJsonStruct(const StructPtr &pPtr) const;
|
||||
|
||||
JsonValueArrayPtr toJsonVector(const VectorPtr &pPtr) const;
|
||||
|
||||
protected:
|
||||
|
||||
string tocaseBuiltin(const BuiltinPtr &pPtr, const string& varName) const;
|
||||
|
||||
string tocaseVector(const VectorPtr &pPtr, const string& varName) const;
|
||||
|
||||
string tocaseMap(const MapPtr &pPtr, const string& varName) const;
|
||||
|
||||
string tocaseStruct(const StructPtr &pPtr, const string& varName) const;
|
||||
|
||||
string tocaseEnum(const EnumPtr &pPtr, const string& varName) const;
|
||||
|
||||
string toCase(const TypePtr &pPtr, const string& varName) const;
|
||||
|
||||
//以下是h和java文件的具体生成
|
||||
protected:
|
||||
/**
|
||||
* 生成参数声明的test文件内容
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string generateTest(const ParamDeclPtr &pPtr) const;
|
||||
|
||||
/**
|
||||
*
|
||||
* 生成测试用例
|
||||
**/
|
||||
string generateCase(const ParamDeclPtr &pPtr) const;
|
||||
|
||||
/**
|
||||
* 生成WEB代理请求访问的JSON串
|
||||
* @param pPtr
|
||||
* @param outfile
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string generateJson(const InterfacePtr &pPtr, const string& outfile = "") const;
|
||||
|
||||
/**
|
||||
* 生成TEST接口访问的测试
|
||||
* @param pPtr
|
||||
* @param outfile
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string generateTest(const InterfacePtr &pPtr, const string& outfile = "") const;
|
||||
|
||||
|
||||
/**
|
||||
* 生成每个jce文件的java文件源码
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
void generateFile(const ContextPtr &pPtr, const string& outfile = "") const;
|
||||
|
||||
/**
|
||||
* 生成tag和require、optional信息
|
||||
*/
|
||||
string genratePrefix(const TypeIdPtr &ptr) const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
0
tools/tars2cpp/CMakeLists.txt
Normal file → Executable file
0
tools/tars2cpp/CMakeLists.txt
Normal file → Executable file
29
tools/tars2cpp/main.cpp
Normal file → Executable file
29
tools/tars2cpp/main.cpp
Normal file → Executable file
@ -111,6 +111,35 @@ int main(int argc, char* argv[])
|
||||
t2c.setJsonSupport(false);
|
||||
}
|
||||
|
||||
if (option.hasParam("sql"))
|
||||
{
|
||||
t2c.setSqlSupport(true);
|
||||
t2c.setJsonSupport(true);
|
||||
}
|
||||
|
||||
if (option.hasParam("xml"))
|
||||
{
|
||||
vector<string> vXmlIntf;
|
||||
string sXml = tars::TC_Common::trim(option.getValue("xml"));
|
||||
sXml = tars::TC_Common::trimleft(tars::TC_Common::trimright(sXml, "]"), "[");
|
||||
if (!sXml.empty())
|
||||
{
|
||||
vXmlIntf = tars::TC_Common::sepstr<string>(sXml, ",", false);
|
||||
}
|
||||
t2c.setXmlSupport(true, vXmlIntf);
|
||||
}
|
||||
|
||||
if (option.hasParam("json"))
|
||||
{
|
||||
t2c.setJsonSupport(true);
|
||||
string sJson = tars::TC_Common::trim(option.getValue("json"));
|
||||
sJson = tars::TC_Common::trimleft(tars::TC_Common::trimright(sJson, "]"), "[");
|
||||
if (!sJson.empty())
|
||||
{
|
||||
t2c.setJsonSupport(tars::TC_Common::sepstr<string>(sJson, ",", false));
|
||||
}
|
||||
}
|
||||
|
||||
t2c.setTarsMaster(option.hasParam("tarsMaster"));
|
||||
|
||||
try
|
||||
|
417
tools/tars2cpp/tars2cpp.cpp
Normal file → Executable file
417
tools/tars2cpp/tars2cpp.cpp
Normal file → Executable file
@ -3,14 +3,14 @@
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
Tars2Cpp::Tars2Cpp()
|
||||
: _checkDefault(false)
|
||||
, _onlyStruct(false)
|
||||
, _bSqlSupport(false)
|
||||
, _bXmlSupport(false)
|
||||
, _bJsonSupport(true)
|
||||
, _namespace("tars")
|
||||
// , _unknownField(false)
|
||||
@ -37,6 +39,182 @@ Tars2Cpp::Tars2Cpp()
|
||||
|
||||
}
|
||||
|
||||
string Tars2Cpp::writeToXml(const TypeIdPtr &pPtr) const
|
||||
{
|
||||
ostringstream s;
|
||||
if(EnumPtr::dynamicCast(pPtr->getTypePtr()))
|
||||
{
|
||||
s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace+ "::XmlOutput::writeXml((" + _namespace+ "::Int32)" << pPtr->getId() << ", _cdata_format);" << endl;
|
||||
}
|
||||
else if(pPtr->getTypePtr()->isArray())
|
||||
{
|
||||
s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace+ "::XmlOutput::writeXml((const "
|
||||
<< tostr(pPtr->getTypePtr()) << " *)" << pPtr->getId() << "Len" << ");" << endl;
|
||||
}
|
||||
else if(pPtr->getTypePtr()->isPointer())
|
||||
{
|
||||
s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace+ "::XmlOutput::writeXml((const "
|
||||
<< tostr(pPtr->getTypePtr()) << " )" << pPtr->getId() << "Len" << ");" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
MapPtr mPtr = MapPtr::dynamicCast(pPtr->getTypePtr());
|
||||
VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
|
||||
if (!_checkDefault || pPtr->isRequire() || (!pPtr->hasDefault() && !mPtr && !vPtr))
|
||||
{
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
|
||||
if (pPtr->getTypePtr()->isSimple() || (bPtr && bPtr->kind() == Builtin::KindString))
|
||||
{
|
||||
s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace + "::XmlOutput::writeXml(" << pPtr->getId() << ", _cdata_format);" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace + "::XmlOutput::writeXml(" << pPtr->getId() << ");" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string sDefault = pPtr->def();
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
|
||||
if (bPtr && bPtr->kind() == Builtin::KindString)
|
||||
{
|
||||
sDefault = "\"" + TC_Common::replace(pPtr->def(), "\"", "\\\"") + "\"";
|
||||
}
|
||||
|
||||
if (mPtr || vPtr)
|
||||
{
|
||||
s << TAB << "if (" << pPtr->getId() << ".size() > 0)" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << TAB << "if (" << pPtr->getId() << " != " << sDefault << ")" << endl;
|
||||
}
|
||||
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "p->value[\"" << pPtr->getId() << "\"] = " + _namespace+ "::XmlOutput::writeXml(" << pPtr->getId() << ");" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
string Tars2Cpp::readFromXml(const TypeIdPtr &pPtr, bool bIsRequire) const
|
||||
{
|
||||
ostringstream s;
|
||||
if(EnumPtr::dynamicCast(pPtr->getTypePtr()))
|
||||
{
|
||||
s << TAB << "tars::XmlInput::readXml((tars::Int32&)" << pPtr->getId() <<", pObj->value[\"" << pPtr->getId() << "\"]";
|
||||
}
|
||||
else if(pPtr->getTypePtr()->isArray())
|
||||
{
|
||||
s << TAB << "tars::XmlInput::readXml(" << pPtr->getId() << "Len" <<", pObj->value[\"" << pPtr->getId() << "\"]" << getSuffix(pPtr);
|
||||
}
|
||||
else if(pPtr->getTypePtr()->isPointer())
|
||||
{
|
||||
// "not support";
|
||||
}
|
||||
else
|
||||
{
|
||||
s << TAB << "tars::XmlInput::readXml(" << pPtr->getId() << ",pObj->value[\"" << pPtr->getId() << "\"]";
|
||||
}
|
||||
s << ", " << ((pPtr->isRequire() && bIsRequire)?"true":"false") << ");" << endl;
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
string Tars2Cpp::writeToSql(const TypeIdPtr &pPtr) const
|
||||
{
|
||||
ostringstream s;
|
||||
if(EnumPtr::dynamicCast(pPtr->getTypePtr()))
|
||||
{
|
||||
s << TAB << "_mycols[\"" << pPtr->getId() << "\"] = make_pair(tars::TC_Mysql::DB_INT, tars::TC_Common::tostr(" << pPtr->getId() << "));" << endl;
|
||||
}
|
||||
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
|
||||
if (bPtr)
|
||||
{
|
||||
switch(bPtr->kind())
|
||||
{
|
||||
case Builtin::KindBool:
|
||||
case Builtin::KindByte:
|
||||
case Builtin::KindShort:
|
||||
case Builtin::KindInt:
|
||||
case Builtin::KindLong:
|
||||
s << TAB << "_mycols[\"" << pPtr->getId() << "\"] = make_pair(tars::TC_Mysql::DB_INT, tars::TC_Common::tostr(" << pPtr->getId() << "));" << endl;
|
||||
break;
|
||||
case Builtin::KindFloat:
|
||||
case Builtin::KindDouble:
|
||||
s << TAB << "_mycols[\"" << pPtr->getId() << "\"] = make_pair(tars::TC_Mysql::DB_STR, tars::TC_Common::tostr(" << pPtr->getId() << "));" << endl;
|
||||
break;
|
||||
case Builtin::KindString:
|
||||
s << TAB << "_mycols[\"" << pPtr->getId() << "\"] = make_pair(tars::TC_Mysql::DB_STR, tars::TC_Common::trim(" << pPtr->getId() << "));" << endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!pPtr->getTypePtr()->isSimple())
|
||||
{
|
||||
s << TAB << "_mycols[\"" << pPtr->getId() << "\"] = make_pair(tars::TC_Mysql::DB_STR, tars::TC_Json::writeValue(tars::JsonOutput::writeJson(" << pPtr->getId() << ")));" << endl;
|
||||
}
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
string Tars2Cpp::readFromSql(const TypeIdPtr &pPtr, bool bIsRequire) const
|
||||
{
|
||||
ostringstream s;
|
||||
EnumPtr ePtr = EnumPtr::dynamicCast(pPtr->getTypePtr());
|
||||
if(ePtr)
|
||||
{
|
||||
s << TAB << pPtr->getId() << " = (" << ePtr->getSid() <<")TC_Common::strto<tars::Int32>(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
}
|
||||
|
||||
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
|
||||
if (bPtr)
|
||||
{
|
||||
switch(bPtr->kind())
|
||||
{
|
||||
case Builtin::KindBool:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::strto<tars::Bool>(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
case Builtin::KindByte:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::strto<tars::" << (bPtr->isUnsigned() ? "UInt8" : "Char") << ">(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
case Builtin::KindShort:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::strto<tars::" << (bPtr->isUnsigned() ? "UInt16" : "Short") << ">(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
case Builtin::KindInt:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::strto<tars::" << (bPtr->isUnsigned() ? "UInt32" : "Int32") << ">(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
case Builtin::KindLong:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::strto<tars::" << (bPtr->isUnsigned() ? "UInt64" : "Int64") << ">(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
case Builtin::KindFloat:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::strto<tars::Float>(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
case Builtin::KindDouble:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::strto<tars::Double>(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
case Builtin::KindString:
|
||||
s << TAB << pPtr->getId() << " = TC_Common::trim(_mysrd[\"" << pPtr->getId() << "\"]);" << endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!pPtr->getTypePtr()->isSimple() )
|
||||
{
|
||||
s << TAB << "tars::JsonInput::readJson(" << pPtr->getId() << ", tars::TC_Json::getValue(_mysrd[\"" << pPtr->getId() << "\"]), false);" << endl;
|
||||
}
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
string Tars2Cpp::writeToJson(const TypeIdPtr& pPtr) const
|
||||
{
|
||||
ostringstream s;
|
||||
@ -109,7 +287,7 @@ string Tars2Cpp::readFromJson(const TypeIdPtr& pPtr, bool bIsRequire) const
|
||||
// s << TAB << _namespace + "::JsonInput::readJson((" + _namespace + "::Int32&)" << pPtr->getId() << ",pObj->value[\"" << pPtr->getId() << "\"]";
|
||||
// }
|
||||
// else
|
||||
|
||||
|
||||
if (pPtr->getTypePtr()->isArray())
|
||||
{
|
||||
s << TAB << _namespace + "::JsonInput::readJson(" << pPtr->getId() << "Len" << ",pObj->value[\"" << pPtr->getId() << "\"]" << getSuffix(pPtr);
|
||||
@ -507,13 +685,16 @@ string Tars2Cpp::generateH(const StructPtr& pPtr, const string& namespaceId) con
|
||||
////////////////////////////////////////////////////////////
|
||||
//定义缺省构造函数
|
||||
s << TAB << pPtr->getId() << "()" << endl;
|
||||
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "resetDefautlt();" << endl;
|
||||
vector<TypeIdPtr>& member = pPtr->getAllMemberPtr();
|
||||
|
||||
/*
|
||||
bool b = false;
|
||||
//定义初始化列表
|
||||
for (size_t j = 0; j < member.size(); j++)
|
||||
{
|
||||
|
||||
if (member[j]->getTypePtr()->isArray())
|
||||
{
|
||||
if (!b) s << TAB << ":";
|
||||
@ -596,9 +777,18 @@ string Tars2Cpp::generateH(const StructPtr& pPtr, const string& namespaceId) con
|
||||
}
|
||||
s << TAB << "memset(" << member[j]->getId() << ", 0, " << "sizeof(" << member[j]->getId() << "));" << endl;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
if (_bXmlSupport)
|
||||
{
|
||||
s << TAB << "_cdata_format = false;" << endl;
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
|
||||
//resetDefault()函数
|
||||
s << TAB << "void resetDefautlt()" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
@ -730,6 +920,86 @@ string Tars2Cpp::generateH(const StructPtr& pPtr, const string& namespaceId) con
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
if (_bXmlSupport)
|
||||
{
|
||||
s << TAB << "void setXmlFormat(bool cdata = false)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "_cdata_format = cdata;" <<endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
s << TAB << "tars::XmlValueObjPtr writeToXml() const" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "tars::XmlValueObjPtr p = new tars::XmlValueObj();" << endl;
|
||||
for(size_t j = 0; j < member.size(); j++)
|
||||
{
|
||||
s << writeToXml(member[j]);
|
||||
}
|
||||
s << TAB << "return p;" <<endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
s << TAB << "string writeToXmlString() const" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "return tars::TC_Xml::writeValue(writeToXml());" <<endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
s << TAB << "void readFromXml(const tars::XmlValuePtr & p, bool isRequire = true)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "resetDefautlt();" << endl;
|
||||
s << TAB << "if(NULL == p.get() || p->getType() != eXmlTypeObj)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "char s[128];" << endl;
|
||||
s << TAB << "snprintf(s, sizeof(s), \"read 'struct' type mismatch, get type: %d.\", p->getType());" << endl;
|
||||
s << TAB << "throw TC_Xml_Exception(s);" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
s << TAB << "tars::XmlValueObjPtr pObj= tars::XmlValueObjPtr::dynamicCast(p);" << endl;
|
||||
for(size_t j = 0; j < member.size(); j++)
|
||||
{
|
||||
s << readFromXml(member[j]);
|
||||
}
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
s << TAB << "void readFromXmlString(const string & str)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "readFromXml(tars::TC_Xml::getValue(str));" <<endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
if (_bSqlSupport)
|
||||
{
|
||||
s << TAB << "tars::TC_Mysql::RECORD_DATA& toSql(tars::TC_Mysql::RECORD_DATA& _mycols) const" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
for(size_t j = 0; j < member.size(); j++)
|
||||
{
|
||||
s << writeToSql(member[j]);
|
||||
}
|
||||
s << TAB << "return _mycols;" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
s << TAB << "void fromSql(tars::TC_Mysql::MysqlRecord& _mysrd)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "resetDefautlt();" << endl;
|
||||
for(size_t j = 0; j < member.size(); j++)
|
||||
{
|
||||
s << readFromSql(member[j]);
|
||||
}
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
s << TAB << "ostream& display(ostream& _os, int _level=0) const" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
@ -771,6 +1041,15 @@ string Tars2Cpp::generateH(const StructPtr& pPtr, const string& namespaceId) con
|
||||
s << TAB << tostr(member[j]->getTypePtr()) << " " << member[j]->getId() << toStrSuffix(member[j]) << ";" << endl;
|
||||
|
||||
}
|
||||
|
||||
if (_bXmlSupport)
|
||||
{
|
||||
DEL_TAB;
|
||||
s << TAB << "private:" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "bool _cdata_format;" << endl;
|
||||
}
|
||||
|
||||
// if (_unknownField)
|
||||
// {
|
||||
// s << TAB << "std::string sUnknownField;" << endl;
|
||||
@ -1284,6 +1563,58 @@ string Tars2Cpp::generateServantDispatch(const OperationPtr& pPtr, const string&
|
||||
}
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
// 支持JSON协议分发
|
||||
if (_bJsonSupport && tars::TC_Common::matchPeriod(pPtr->getId(), _vJsonIntf))
|
||||
{
|
||||
s << TAB << "else if (_current->getRequestVersion() == JSONVERSION)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << _namespace << "::JsonValueObjPtr _jsonPtr = " << _namespace << "::JsonValueObjPtr::dynamicCast(" << _namespace << "::TC_Json::getValue(_current->getRequestBuffer()));" << endl;
|
||||
for(size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
string sParamName = vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
string sEnum2Int = (EnumPtr::dynamicCast(vParamDecl[i]->getTypeIdPtr()->getTypePtr())) ? "(" + _namespace + "::Int32)" : "";
|
||||
if (!vParamDecl[i]->isOut())
|
||||
{
|
||||
// tars::JsonInput::readJson(uin, _jsonPtr->value["uin"], true); 枚举类型转成int
|
||||
s << TAB << _namespace << "::JsonInput::readJson(" << sParamName << ", _jsonPtr->value[\"" << sParamName << "\"], true);" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << TAB << _namespace << "::JsonInput::readJson(" << sParamName << ", _jsonPtr->value[\"" << sParamName << "\"], false);" << endl;
|
||||
}
|
||||
}
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
// 支持XML协议分发
|
||||
if (_bXmlSupport && tars::TC_Common::matchPeriod(pPtr->getId(), _vXmlIntf))
|
||||
{
|
||||
s << TAB << "else if (_current->getRequestVersion() == XMLVERSION)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
|
||||
s << TAB << "tars::XmlValueObjPtr _xmlPtr = tars::XmlValueObjPtr::dynamicCast(tars::TC_Xml::getValue(_current->getRequestBuffer()));" << endl;
|
||||
for(size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
string sParamName = vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
if(!vParamDecl[i]->isOut())
|
||||
{
|
||||
//枚举类型转成int
|
||||
s << TAB << "tars::XmlInput::readXml(" << sParamName << ", _xmlPtr->value[\"" << sParamName << "\"], true);" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << TAB << "tars::XmlInput::readXml(" << sParamName << ", _xmlPtr->value[\"" << sParamName << "\"], false);" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
s << TAB << "else" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
@ -1346,6 +1677,70 @@ string Tars2Cpp::generateServantDispatch(const OperationPtr& pPtr, const string&
|
||||
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
|
||||
// 支持JSON协议分发
|
||||
if (_bJsonSupport && tars::TC_Common::matchPeriod(pPtr->getId(), _vJsonIntf))
|
||||
{
|
||||
s << TAB << "else if (_current->getRequestVersion() == JSONVERSION)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << _namespace << "::JsonValueObjPtr _p = new " << _namespace << "::JsonValueObj();" << endl;
|
||||
for(size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
string sParamName = vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
if (vParamDecl[i]->isOut())
|
||||
{
|
||||
s << TAB << "_p->value[\"" << sParamName << "\"] = "<< _namespace << "::JsonOutput::writeJson(" << sParamName << ");" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (pPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
BuiltinPtr retPtr = BuiltinPtr::dynamicCast(pPtr->getReturnPtr()->getTypePtr());
|
||||
if (retPtr->kind() >= Builtin::KindBool && retPtr->kind() <= Builtin::KindLong)
|
||||
{
|
||||
s << TAB << "_p->value[\"ret\"] = "<< _namespace << "::JsonOutput::writeJson(" << pPtr->getReturnPtr()->getId() << ");" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
s << TAB << _namespace << "::TC_Json::writeValue(_p, _sResponseBuffer);" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
// 支持XML协议分发
|
||||
if (_bXmlSupport && tars::TC_Common::matchPeriod(pPtr->getId(), _vXmlIntf))
|
||||
{
|
||||
s << TAB << "else if (_current->getRequestVersion() == XMLVERSION)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
|
||||
s << TAB << "tars::XmlValueObjPtr _p = new tars::XmlValueObj();" << endl;
|
||||
|
||||
for(size_t i = 0; i < vParamDecl.size(); i++)
|
||||
{
|
||||
string sParamName = vParamDecl[i]->getTypeIdPtr()->getId();
|
||||
if (vParamDecl[i]->isOut())
|
||||
{
|
||||
s << TAB << "_p->value[\"" << sParamName << "\"] = tars::XmlOutput::writeXml(" << sParamName << ");" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (pPtr->getReturnPtr()->getTypePtr())
|
||||
{
|
||||
BuiltinPtr retPtr = BuiltinPtr::dynamicCast(pPtr->getReturnPtr()->getTypePtr());
|
||||
if (retPtr->kind() >= Builtin::KindBool && retPtr->kind() <= Builtin::KindLong)
|
||||
{
|
||||
s << TAB << "_p->value[\"ret\"] = tars::XmlOutput::writeXml(" << pPtr->getReturnPtr()->getId() << ");" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
s << TAB << "tars::TC_Xml::writeValue(_p, _sResponseBuffer);" << endl;
|
||||
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
}
|
||||
|
||||
s << TAB << "else" << endl;
|
||||
|
||||
//普通tars调用输出参数
|
||||
@ -1831,7 +2226,7 @@ string Tars2Cpp::generateHPromiseAsync(const InterfacePtr &pInter, const Operati
|
||||
s << TAB << "virtual void " << "callback_" << pPtr->getId() << "(const " << pInter->getId() << "PrxCallbackPromise::Promise" << sStruct << "Ptr &ptr)" << endl;
|
||||
s << TAB << "{" << endl;
|
||||
INC_TAB;
|
||||
s << TAB << "_promise_" << sStruct << ".setValue(ptr);" << endl;
|
||||
s << TAB << "_promise_" << sStruct << ".setValue(ptr);" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
s << TAB << "virtual void " << "callback_" << pPtr->getId() << "_exception(" + _namespace + "::Int32 ret)" << endl;
|
||||
@ -1839,7 +2234,7 @@ string Tars2Cpp::generateHPromiseAsync(const InterfacePtr &pInter, const Operati
|
||||
INC_TAB;
|
||||
s << TAB << "std::string str(\"\");" << endl;
|
||||
s << TAB << "str += \"Function:" << pPtr->getId() << "_exception|Ret:\";" << endl;
|
||||
s << TAB << "str += TC_Common::tostr(ret);" << endl;
|
||||
s << TAB << "str += TC_Common::tostr(ret);" << endl;
|
||||
s << TAB << "_promise_" << sStruct << ".setException(tars::copyException(str, ret));" << endl;
|
||||
DEL_TAB;
|
||||
s << TAB << "}" << endl;
|
||||
@ -2457,6 +2852,8 @@ void Tars2Cpp::generateH(const ContextPtr &pPtr) const
|
||||
s << "#include <vector>" << endl;
|
||||
s << "#include \"tup/Tars.h\"" << endl;
|
||||
if (_bJsonSupport) s << "#include \"tup/TarsJson.h\"" << endl;
|
||||
if (_bSqlSupport) s << "#include \"util/tc_mysql.h\"" << endl;
|
||||
if (_bXmlSupport) s << "#include \"tup/TarsXml.h\"" << endl;
|
||||
|
||||
s << "using namespace std;" << endl;
|
||||
|
||||
@ -2863,4 +3260,4 @@ StructPtr Tars2Cpp::findStruct(const ContextPtr& pPtr, const string& id)
|
||||
// s << endl;
|
||||
// s << "#endif" << endl;
|
||||
|
||||
//
|
||||
//
|
58
tools/tars2cpp/tars2cpp.h
Normal file → Executable file
58
tools/tars2cpp/tars2cpp.h
Normal file → Executable file
@ -51,11 +51,30 @@ public:
|
||||
*/
|
||||
void setCheckDefault(bool bCheck) { _checkDefault = bCheck; }
|
||||
|
||||
/**
|
||||
* 根据命令选项设置是否需要生成sql支持
|
||||
*/
|
||||
void setSqlSupport(bool bSqlSupport) { _bSqlSupport = bSqlSupport;}
|
||||
|
||||
/**
|
||||
* 根据命令选项设置是否需要生成xml支持
|
||||
*/
|
||||
void setXmlSupport(bool bXmlSupport, const vector<string>& vXmlIntf)
|
||||
{
|
||||
_bXmlSupport = bXmlSupport;
|
||||
_vXmlIntf = vXmlIntf;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据命令选项设置是否需要生成json支持
|
||||
*/
|
||||
void setJsonSupport(bool bJsonSupport) { _bJsonSupport = bJsonSupport; }
|
||||
|
||||
/**
|
||||
* 根据命令选项设置是否需要生成json支持
|
||||
*/
|
||||
void setJsonSupport(const vector<string>& vJsonIntf) { _vJsonIntf = vJsonIntf; }
|
||||
|
||||
/**
|
||||
* 设置是否只生成struct
|
||||
*/
|
||||
@ -74,6 +93,37 @@ public:
|
||||
|
||||
//下面是编解码的源码生成
|
||||
protected:
|
||||
/**
|
||||
* 生成xml
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string writeToXml(const TypeIdPtr &pPtr) const;
|
||||
|
||||
/**
|
||||
* 生成xml
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string readFromXml(const TypeIdPtr &pPtr, bool bIsRequire = true) const;
|
||||
|
||||
/**
|
||||
* 生成sql
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string writeToSql(const TypeIdPtr &pPtr) const;
|
||||
|
||||
/**
|
||||
* 生成sql
|
||||
* @param pPtr
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
string readFromSql(const TypeIdPtr &pPtr, bool bIsRequire = true) const;
|
||||
|
||||
/**
|
||||
* 生成json
|
||||
@ -449,8 +499,16 @@ private:
|
||||
|
||||
bool _onlyStruct;
|
||||
|
||||
bool _bSqlSupport;
|
||||
|
||||
bool _bXmlSupport;
|
||||
|
||||
bool _bJsonSupport;
|
||||
|
||||
vector<string> _vJsonIntf;
|
||||
vector<string> _vXmlIntf;
|
||||
|
||||
|
||||
std::string _namespace ;
|
||||
|
||||
// bool _unknownField;
|
||||
|
2
util/include/util/tc_json.h
Normal file → Executable file
2
util/include/util/tc_json.h
Normal file → Executable file
@ -256,9 +256,11 @@ public:
|
||||
//json类型到字符串的转换
|
||||
static string writeValue(const JsonValuePtr & p);
|
||||
static void writeValue(const JsonValuePtr & p, string& ostr);
|
||||
static void writeValue(const JsonValuePtr & p, vector<char>& buf);
|
||||
|
||||
//json字符串到json结构的转换
|
||||
static JsonValuePtr getValue(const string & str);
|
||||
static JsonValuePtr getValue(const vector<char>& buf);
|
||||
private:
|
||||
//string 类型到json字符串
|
||||
static void writeString(const JsonValueStringPtr & p, string& ostr);
|
||||
|
226
util/include/util/tc_xml.h
Executable file
226
util/include/util/tc_xml.h
Executable file
@ -0,0 +1,226 @@
|
||||
#ifndef __TC_XML_H_
|
||||
#define __TC_XML_H_
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util/tc_autoptr.h"
|
||||
using namespace std;
|
||||
|
||||
namespace tars
|
||||
{
|
||||
/////////////////////////////////////////////////
|
||||
// 说明: Xml编解码的公共库
|
||||
// Author : linfengchen@tencent.com
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* 编解码抛出的异常
|
||||
*/
|
||||
struct TC_Xml_Exception : public TC_Exception
|
||||
{
|
||||
TC_Xml_Exception(const string &buffer) : TC_Exception(buffer){};
|
||||
TC_Xml_Exception(const string &buffer, int err) : TC_Exception(buffer, err){};
|
||||
~TC_Xml_Exception() throw(){};
|
||||
};
|
||||
|
||||
enum eXmlType
|
||||
{
|
||||
eXmlTypeString = 1,
|
||||
eXmlTypeArray,
|
||||
eXmlTypeObj,
|
||||
};
|
||||
|
||||
/*
|
||||
* Xml类型的基类。没有任何意义
|
||||
*/
|
||||
class XmlValue : public tars::TC_HandleBase
|
||||
{
|
||||
public:
|
||||
virtual eXmlType getType()=0;
|
||||
virtual ~XmlValue(){}
|
||||
protected:
|
||||
XmlValue* parent;
|
||||
};
|
||||
typedef tars::TC_AutoPtr<XmlValue> XmlValuePtr;
|
||||
|
||||
|
||||
/*
|
||||
* Xml类型 string类型
|
||||
*/
|
||||
class XmlValueString : public XmlValue
|
||||
{
|
||||
public:
|
||||
XmlValueString(const string & s, bool _cdata = false):value(s), cdata(_cdata)
|
||||
{
|
||||
}
|
||||
XmlValueString(bool _cdata = false):cdata(_cdata)
|
||||
{
|
||||
}
|
||||
|
||||
eXmlType getType()
|
||||
{
|
||||
return eXmlTypeString;
|
||||
}
|
||||
virtual ~XmlValueString(){}
|
||||
string value;
|
||||
bool cdata;
|
||||
};
|
||||
typedef tars::TC_AutoPtr<XmlValueString> XmlValueStringPtr;
|
||||
|
||||
|
||||
/*
|
||||
* Xml类型 object类型 例如
|
||||
*/
|
||||
class XmlValueObj: public XmlValue
|
||||
{
|
||||
public:
|
||||
eXmlType getType()
|
||||
{
|
||||
return eXmlTypeObj;
|
||||
}
|
||||
virtual ~XmlValueObj(){}
|
||||
public:
|
||||
map<string, XmlValuePtr> value;
|
||||
};
|
||||
typedef tars::TC_AutoPtr<XmlValueObj> XmlValueObjPtr;
|
||||
|
||||
/*
|
||||
* Xml类型 array类型 例如
|
||||
*/
|
||||
class XmlValueArray: public XmlValue
|
||||
{
|
||||
public:
|
||||
eXmlType getType()
|
||||
{
|
||||
return eXmlTypeArray;
|
||||
}
|
||||
void push_back(XmlValuePtr & p)
|
||||
{
|
||||
value.push_back(p);
|
||||
}
|
||||
virtual ~XmlValueArray(){}
|
||||
public:
|
||||
vector<XmlValuePtr> value;
|
||||
};
|
||||
typedef tars::TC_AutoPtr<XmlValueArray> XmlValueArrayPtr;
|
||||
|
||||
/*
|
||||
* 分析Xml字符串用到的 读字符的类
|
||||
*/
|
||||
class BufferXmlReader
|
||||
{
|
||||
public:
|
||||
const char * _buf; ///< 缓冲区
|
||||
size_t _len; ///< 缓冲区长度
|
||||
size_t _pos; ///< 当前位置
|
||||
|
||||
public:
|
||||
|
||||
BufferXmlReader () :_buf(NULL),_len(0), _pos(0) {}
|
||||
|
||||
void reset() { _pos = 0;}
|
||||
|
||||
void setBuffer(const char * buf, size_t len)
|
||||
{
|
||||
_buf = buf;
|
||||
_len = len;
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
void setBuffer(const std::vector<char> &buf)
|
||||
{
|
||||
_buf = &buf[0];
|
||||
_len = buf.size();
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
bool hasEnd()
|
||||
{
|
||||
return (_pos >= _len || *(_buf + _pos) == 0);
|
||||
}
|
||||
|
||||
bool expect(char ch)
|
||||
{
|
||||
if (get() == ch)
|
||||
{
|
||||
_pos++;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void skip(size_t i = 1)
|
||||
{
|
||||
_pos += i;
|
||||
}
|
||||
|
||||
char read()
|
||||
{
|
||||
check(++_pos);
|
||||
return *(_buf+_pos-1);
|
||||
}
|
||||
|
||||
char get(size_t pos = 0)
|
||||
{
|
||||
check(pos + _pos);
|
||||
return *(_buf+_pos + pos);
|
||||
}
|
||||
|
||||
size_t pos()
|
||||
{
|
||||
return _pos;
|
||||
}
|
||||
|
||||
void check(size_t pos)
|
||||
{
|
||||
if (pos > _len)
|
||||
{
|
||||
char s[64];
|
||||
snprintf(s, sizeof(s), "buffer[%u] overflow when peekBuf, over %u.", (uint32_t)pos, (uint32_t)_len);
|
||||
throw TC_Xml_Exception(s);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* 分析Xml的类。都是static
|
||||
*/
|
||||
class TC_Xml
|
||||
{
|
||||
public:
|
||||
//Xml类型到字符串的转换
|
||||
static string writeValue(const XmlValuePtr& p, bool bHead = true);
|
||||
static void writeValue(const XmlValuePtr& p, vector<char>& buf, bool bHead = true);
|
||||
//Xml字符串到Xml结构的转换
|
||||
static XmlValuePtr getValue(const string& str);
|
||||
static XmlValuePtr getValue(const vector<char>& buf);
|
||||
private:
|
||||
static XmlValuePtr getNode(BufferXmlReader& reader, const string& nodename = "");
|
||||
static XmlValueStringPtr getValue(BufferXmlReader& reader);
|
||||
static XmlValueStringPtr getCdata(BufferXmlReader& reader);
|
||||
|
||||
static void insertArray(const string& name, XmlValuePtr& v, XmlValueObjPtr& p);
|
||||
static bool isEndNode(BufferXmlReader& reader, const string& nodename);
|
||||
static void ignoreDeclaration(BufferXmlReader& reader);
|
||||
static bool ignoreComment(BufferXmlReader& reader);
|
||||
|
||||
|
||||
static void writeArray(std::ostream& os, const string& name, const XmlValuePtr& p);
|
||||
static void writeString(std::ostream& os, const XmlValuePtr& p);
|
||||
static void writeEChar(std::ostream& os, const string& data);
|
||||
static void writeObj(std::ostream& os, const XmlValuePtr& p);
|
||||
|
||||
//判断一个字符是否符合Xml定义的空白字符
|
||||
static bool isspace(char c);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
15
util/src/tc_json.cpp
Normal file → Executable file
15
util/src/tc_json.cpp
Normal file → Executable file
@ -333,6 +333,7 @@ JsonValueNumPtr TC_Json::getNum(BufferJsonReader & reader,char head)
|
||||
dResult=0-dResult;
|
||||
JsonValueNumPtr p = new JsonValueNum();
|
||||
p->value=dResult;
|
||||
p->isInt=!bFloat;
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -449,6 +450,13 @@ string TC_Json::writeValue(const JsonValuePtr & p)
|
||||
return ostr;
|
||||
}
|
||||
|
||||
void TC_Json::writeValue(const JsonValuePtr& p, vector<char>& buf)
|
||||
{
|
||||
string ostr;
|
||||
writeValue(p, ostr);
|
||||
buf.assign(ostr.begin(), ostr.end());
|
||||
}
|
||||
|
||||
void TC_Json::writeValue(const JsonValuePtr & p, string& ostr)
|
||||
{
|
||||
if(!p)
|
||||
@ -600,6 +608,13 @@ JsonValuePtr TC_Json::getValue(const string & str)
|
||||
return getValue(reader);
|
||||
}
|
||||
|
||||
JsonValuePtr TC_Json::getValue(const vector<char>& buf)
|
||||
{
|
||||
BufferJsonReader reader;
|
||||
reader.setBuffer(buf);
|
||||
return getValue(reader);
|
||||
}
|
||||
|
||||
//json里面定义的空白字符
|
||||
bool TC_Json::isspace(char c)
|
||||
{
|
||||
|
532
util/src/tc_xml.cpp
Executable file
532
util/src/tc_xml.cpp
Executable file
@ -0,0 +1,532 @@
|
||||
#include "util/tc_xml.h"
|
||||
#include "util/tc_common.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace tars
|
||||
{
|
||||
|
||||
#define FILTER_SPACE while(isspace((int)reader.get())) {reader.skip();}
|
||||
#define FILTER_NODENAME while(lookup_node_name[(int)reader.get()]) {reader.skip();}
|
||||
#define XML_PARSE_ERROR(what) { throw TC_Xml_Exception(what); }
|
||||
|
||||
// Node name (anything but space \n \r \t / > ? \0)
|
||||
const unsigned char lookup_node_name[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
|
||||
};
|
||||
|
||||
// Text (i.e. PCDATA) (anything but < \0)
|
||||
const unsigned char lookup_text[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
|
||||
};
|
||||
|
||||
// Text (i.e. PCDATA) that does not require processing when ws normalization is disabled
|
||||
// (anything but < \0 &)
|
||||
const unsigned char lookup_text_pure_no_ws[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
|
||||
1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
|
||||
};
|
||||
|
||||
|
||||
// Digits (dec and hex, 255 denotes end of numeric character reference)
|
||||
const unsigned char lookup_digits[256] =
|
||||
{
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3
|
||||
255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5
|
||||
255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E
|
||||
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F
|
||||
};
|
||||
|
||||
XmlValuePtr TC_Xml::getValue(const string& str)
|
||||
{
|
||||
BufferXmlReader reader;
|
||||
XmlValueObjPtr p = new XmlValueObj();
|
||||
|
||||
// Parse BOM, if any
|
||||
reader.setBuffer(str.c_str(), str.length());
|
||||
if ((unsigned char)reader.get(0) == 0xEF &&
|
||||
(unsigned char)reader.get(1) == 0xBB &&
|
||||
(unsigned char)reader.get(2) == 0xBF)
|
||||
{
|
||||
reader._pos += 3; // Skup utf-8 bom
|
||||
}
|
||||
|
||||
FILTER_SPACE;
|
||||
// Parse and append new child
|
||||
if (reader.get() == '<' && reader.get(1) == '?')
|
||||
{
|
||||
reader.skip(2);
|
||||
ignoreDeclaration(reader);
|
||||
}
|
||||
|
||||
FILTER_SPACE;
|
||||
return getNode(reader);
|
||||
}
|
||||
|
||||
XmlValuePtr TC_Xml::getValue(const vector<char>& buf)
|
||||
{
|
||||
BufferXmlReader reader;
|
||||
XmlValueObjPtr p = new XmlValueObj();
|
||||
|
||||
// Parse BOM, if any
|
||||
reader.setBuffer(buf);
|
||||
if ((unsigned char)reader.get(0) == 0xEF &&
|
||||
(unsigned char)reader.get(1) == 0xBB &&
|
||||
(unsigned char)reader.get(2) == 0xBF)
|
||||
{
|
||||
reader._pos += 3; // Skup utf-8 bom
|
||||
}
|
||||
|
||||
FILTER_SPACE;
|
||||
// Parse and append new child
|
||||
if (reader.get() == '<' && reader.get(1) == '?')
|
||||
{
|
||||
reader.skip(2);
|
||||
ignoreDeclaration(reader);
|
||||
}
|
||||
|
||||
FILTER_SPACE;
|
||||
return getNode(reader);
|
||||
}
|
||||
|
||||
XmlValuePtr TC_Xml::getNode(BufferXmlReader& reader, const string& nodename)
|
||||
{
|
||||
XmlValueObjPtr p = new XmlValueObj();
|
||||
while(1)
|
||||
{
|
||||
// 开始符号
|
||||
if (!reader.expect('<'))
|
||||
{
|
||||
return getValue(reader);
|
||||
}
|
||||
|
||||
// 判断是否是注释
|
||||
if (ignoreComment(reader))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// CDATA
|
||||
if (reader.get(0) == '!' && reader.get(1) == '[' && reader.get(2) == 'C' && reader.get(3) == 'D' &&
|
||||
reader.get(4) == 'A' && reader.get(5) == 'T' && reader.get(6) == 'A' && reader.get(7) == '[')
|
||||
{
|
||||
reader.skip(8);
|
||||
return getCdata(reader);
|
||||
}
|
||||
|
||||
// 判断是否是node结束符
|
||||
if (isEndNode(reader, nodename))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// 取node名称
|
||||
FILTER_SPACE;
|
||||
size_t pos = reader.pos();
|
||||
FILTER_NODENAME;
|
||||
string name = string(reader._buf + pos, reader.pos() - pos);
|
||||
while(reader.read() != '>');
|
||||
if (reader.get(-2) == '/')
|
||||
{
|
||||
XmlValuePtr s = new XmlValueString();
|
||||
insertArray(name, s, p);
|
||||
FILTER_SPACE;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 取Node内容
|
||||
FILTER_SPACE;
|
||||
XmlValuePtr q = getNode(reader, name);
|
||||
insertArray(name, q, p);
|
||||
|
||||
// 遇到尾部就退出
|
||||
FILTER_SPACE;
|
||||
if (reader.hasEnd())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->value.size() == 0) // node内容为空直接返回空字符对象
|
||||
{
|
||||
XmlValuePtr ss = new XmlValueString();
|
||||
return ss;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
bool TC_Xml::isEndNode(BufferXmlReader& reader, const string& nodename)
|
||||
{
|
||||
if (reader.get() == '/' && reader.get(1) != '>' && !nodename.empty())
|
||||
{
|
||||
size_t lastpos = reader.pos();
|
||||
size_t start = 0;
|
||||
while (isspace(reader.get(start++)));
|
||||
size_t end = start;
|
||||
while(lookup_node_name[(int)reader.get(++end)]);
|
||||
string backname = string(reader._buf + lastpos + start, end - start);
|
||||
if (backname == nodename)
|
||||
{
|
||||
while(reader.read() != '>');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
XmlValueStringPtr TC_Xml::getCdata(BufferXmlReader& reader)
|
||||
{
|
||||
size_t pos = reader.pos();
|
||||
XmlValueStringPtr p = new XmlValueString(true);
|
||||
while (reader.get() != ']' || reader.get(1) != ']' || reader.get(2) != '>')
|
||||
{
|
||||
reader.skip(1);
|
||||
}
|
||||
p->value = string(reader._buf + pos, reader.pos() - pos);
|
||||
reader.skip(3);
|
||||
while(reader.read() != '>');
|
||||
return p;
|
||||
}
|
||||
|
||||
XmlValueStringPtr TC_Xml::getValue(BufferXmlReader& reader)
|
||||
{
|
||||
XmlValueStringPtr p = new XmlValueString();
|
||||
FILTER_SPACE
|
||||
while (lookup_text_pure_no_ws[(int)reader.get()])
|
||||
{
|
||||
if (reader.get() != '&')
|
||||
{
|
||||
p->value.append(1, reader.read());
|
||||
}
|
||||
|
||||
if (reader.get(1) == 'g' && reader.get(2) == 't' && reader.get(3) == ';')
|
||||
{
|
||||
p->value.append(1, '>');
|
||||
reader.skip(4);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reader.get(1) == 'l' && reader.get(2) == 't' && reader.get(3) == ';')
|
||||
{
|
||||
p->value.append(1, '<');
|
||||
reader.skip(4);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reader.get(1) == 'a' && reader.get(2) == 'm' && reader.get(3) == 'p' && reader.get(4) == ';')
|
||||
{
|
||||
p->value.append(1, '&');
|
||||
reader.skip(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reader.get(1) == 'a' && reader.get(2) == 'p' && reader.get(3) == 'o' && reader.get(4) == 's' && reader.get(5) == ';')
|
||||
{
|
||||
p->value.append(1, '\'');
|
||||
reader.skip(6);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reader.get(1) == 'q' && reader.get(2) == 'u' && reader.get(3) == 'o' && reader.get(4) == 's' && reader.get(5) == ';')
|
||||
{
|
||||
p->value.append(1, '"');
|
||||
reader.skip(6);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 中文转码
|
||||
if (reader.get(1) == '#')
|
||||
{
|
||||
unsigned long code = 0;
|
||||
if (reader.get(2) == 'x')
|
||||
{
|
||||
reader.skip(3);
|
||||
unsigned char digit = reader.get();
|
||||
while (lookup_digits[digit] != 0xFF)
|
||||
{
|
||||
code = code * 16 + digit;
|
||||
digit = (unsigned char)reader.read();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.skip(2);
|
||||
unsigned char digit = reader.get();
|
||||
while (lookup_digits[digit] != 0xFF)
|
||||
{
|
||||
code = code * 10 + digit;
|
||||
digit = (unsigned char)reader.read();
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.read() != ';')
|
||||
{
|
||||
XML_PARSE_ERROR("expected ;");
|
||||
}
|
||||
|
||||
// Insert UTF8 sequence
|
||||
char text[8] = {0};
|
||||
if (code < 0x80) // 1 byte sequence
|
||||
{
|
||||
text[0] = static_cast<char>(code);
|
||||
}
|
||||
else if (code < 0x800) // 2 byte sequence
|
||||
{
|
||||
text[1] = static_cast<char>((code | 0x80) & 0xBF); code >>= 6;
|
||||
text[0] = static_cast<char>(code | 0xc0);
|
||||
}
|
||||
else if (code < 0x10000) // 3 byte sequence
|
||||
{
|
||||
text[2] = static_cast<char>((code | 0x80) & 0xBF); code >>= 6;
|
||||
text[1] = static_cast<char>((code | 0x80) & 0xBF); code >>= 6;
|
||||
text[0] = static_cast<char>(code | 0xE0);
|
||||
}
|
||||
else if (code < 0x110000) // 4 byte sequence
|
||||
{
|
||||
text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
|
||||
text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
|
||||
text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
|
||||
text[0] = static_cast<unsigned char>(code | 0xF0);
|
||||
}
|
||||
else // Invalid, only codes up to 0x10FFFF are allowed in Unicode
|
||||
{
|
||||
XML_PARSE_ERROR("invalid numeric character entity");
|
||||
}
|
||||
p->value.append(text);
|
||||
}
|
||||
}
|
||||
while(reader.read() != '>');
|
||||
return p;
|
||||
}
|
||||
|
||||
void TC_Xml::insertArray(const string& name, XmlValuePtr& v, XmlValueObjPtr& p)
|
||||
{
|
||||
if (p->value.find(name) == p->value.end())
|
||||
{
|
||||
p->value[name] = v;
|
||||
}
|
||||
else if (p->value[name]->getType() == v->getType())
|
||||
{
|
||||
XmlValueArrayPtr array = new XmlValueArray();
|
||||
array->push_back(p->value[name]);
|
||||
array->push_back(v);
|
||||
p->value[name] = array;
|
||||
}
|
||||
else if (p->value[name]->getType() == eXmlTypeArray)
|
||||
{
|
||||
XmlValueArrayPtr array = XmlValueArrayPtr::dynamicCast(p->value[name]);
|
||||
if (array->value.size() > 0 && array->value[0]->getType() == v->getType())
|
||||
{
|
||||
array->push_back(v);
|
||||
p->value[name] = array;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TC_Xml::ignoreComment(BufferXmlReader& reader)
|
||||
{
|
||||
if (reader.get() == '!' && reader.get(1) == '-' && reader.get(2) == '-')
|
||||
{
|
||||
reader.skip(3);
|
||||
while (1)
|
||||
{
|
||||
if (reader.read() == '-' && reader.read() == '-' && reader.read() == '>')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TC_Xml::ignoreDeclaration(BufferXmlReader& reader)
|
||||
{
|
||||
if ((reader.get(0) == 'x' || reader.get(0) == 'X') &&
|
||||
(reader.get(1) == 'm' || reader.get(1) == 'M') &&
|
||||
(reader.get(2) == 'l' || reader.get(2) == 'L') &&
|
||||
isspace(reader.get(3)))
|
||||
{
|
||||
// '<?xml ' - xml declaration, ignore it
|
||||
reader.skip(4);
|
||||
while (1)
|
||||
{
|
||||
if (reader.read() == '?' && reader.read() == '>')
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
XML_PARSE_ERROR("unexpected xml head")
|
||||
}
|
||||
|
||||
string TC_Xml::writeValue(const XmlValuePtr & p, bool bHead)
|
||||
{
|
||||
ostringstream os;
|
||||
os << (bHead ? "<?xml version='1.0' encoding='utf-8'?>" : "");
|
||||
if(!p || p->getType() != eXmlTypeObj)
|
||||
{
|
||||
return os.str();
|
||||
}
|
||||
|
||||
writeObj(os, XmlValueObjPtr::dynamicCast(p));
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void TC_Xml::writeValue(const XmlValuePtr& p, vector<char>& buf, bool bHead)
|
||||
{
|
||||
if(!p || p->getType() != eXmlTypeObj)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ostringstream os;
|
||||
os << (bHead ? "<?xml version='1.0' encoding='utf-8'?>" : "");
|
||||
writeObj(os, XmlValueObjPtr::dynamicCast(p));
|
||||
string s = os.str();
|
||||
buf.assign(s.begin(), s.end());
|
||||
}
|
||||
|
||||
void TC_Xml::writeObj(std::ostream& os, const XmlValuePtr& p)
|
||||
{
|
||||
if (p->getType() != eXmlTypeObj)
|
||||
{
|
||||
XML_PARSE_ERROR("not support but xmlobj")
|
||||
}
|
||||
|
||||
os << "\n";
|
||||
XmlValueObjPtr q = XmlValueObjPtr::dynamicCast(p);
|
||||
for (map<string, XmlValuePtr>::const_iterator it = q->value.begin(); it != q->value.end(); it++)
|
||||
{
|
||||
switch (it->second->getType())
|
||||
{
|
||||
case eXmlTypeString:
|
||||
os << "<" << it->first << ">";
|
||||
writeString(os, it->second);
|
||||
os << "</" << it->first << ">\n";
|
||||
break;
|
||||
case eXmlTypeArray:
|
||||
writeArray(os, it->first, it->second);
|
||||
break;
|
||||
case eXmlTypeObj:
|
||||
default:
|
||||
os << "<" << it->first << ">";
|
||||
writeObj(os, it->second);
|
||||
os << "</" << it->first << ">\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TC_Xml::writeString(std::ostream& os, const XmlValuePtr& p)
|
||||
{
|
||||
XmlValueStringPtr q = XmlValueStringPtr::dynamicCast(p);
|
||||
if (q->cdata)
|
||||
{
|
||||
os << "<![CDATA[" << q->value << "]]>";
|
||||
return;
|
||||
}
|
||||
writeEChar(os, q->value);
|
||||
}
|
||||
|
||||
void TC_Xml::writeArray(std::ostream& os, const string& name, const XmlValuePtr& p)
|
||||
{
|
||||
XmlValueArrayPtr q = XmlValueArrayPtr::dynamicCast(p);
|
||||
for (size_t i = 0; i < q->value.size(); i++)
|
||||
{
|
||||
os << "<" << name << ">";
|
||||
if (q->value[i]->getType() == eXmlTypeString)
|
||||
{
|
||||
writeString(os, q->value[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeObj(os, q->value[i]);
|
||||
}
|
||||
os << "</" << name << ">\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
void TC_Xml::writeEChar(std::ostream& os, const string& data)
|
||||
{
|
||||
string s(data);
|
||||
s = TC_Common::replace(s, "<", "<");
|
||||
s = TC_Common::replace(s, ">", "<");
|
||||
s = TC_Common::replace(s, "\'", "'");
|
||||
s = TC_Common::replace(s, "\"", """);
|
||||
os << s;
|
||||
}
|
||||
|
||||
//Xml里面定义的空白字符
|
||||
bool TC_Xml::isspace(char c)
|
||||
{
|
||||
if(c == ' ' || c == '\t' || c == '\r' || c == '\n')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user