SIGN IN SIGN UP
TarsCloud / Tars UNCLAIMED

Tars is a high-performance RPC framework based on name service and Tars protocol, also integrated administration platform, and implemented hosting-service via flexible schedule.

0 0 14 C++
2017-04-28 11:04:01 +08:00
/**
* Tencent is pleased to support the open source community by making Tars available.
*
* Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/BSD-3-Clause
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
#include "tars2php.h"
#include "util/tc_md5.h"
#include "util/tc_file.h"
#include "util/tc_common.h"
#include <string>
#define TAB g_parse->getTab()
#define INC_TAB g_parse->incTab()
#define DEL_TAB g_parse->delTab()
//////////////////////////////////////////////////////////////////////////////////
//
Tars2Php::Tars2Php(): m_bCheckDefault(false)
{
}
string Tars2Php::writeTo(const TypeIdPtr &pPtr) const
{
ostringstream s;
s << TAB << "$this->" << pPtr->getId() << "->write($_out," << pPtr->getTag() << ");" << endl;
return s.str();
}
string Tars2Php::readFrom(const TypeIdPtr &pPtr, bool bIsRequire) const
{
ostringstream s;
s<<TAB<<"$this->"<<pPtr->getId()<<"->read($_in ";
s << ", " << pPtr->getTag() << ", " << ((pPtr->isRequire() && bIsRequire)?"true":"false") << ");" << endl;
return s.str();
}
/*******************************获取定长数组坐标********************************/
int Tars2Php::getSuffix(const TypeIdPtr &pPtr) const
{
BuiltinPtr bPtr = BuiltinPtr::dynamicCast(pPtr->getTypePtr());
if(bPtr && bPtr->kind() == Builtin::KindString && bPtr->isArray())
{
return bPtr->getSize();
}
VectorPtr vPtr = VectorPtr::dynamicCast(pPtr->getTypePtr());
if(vPtr && vPtr->isArray())
{
return vPtr->getSize();
}
return -1;
}
/*******************************定长数组坐标********************************/
string Tars2Php::toStrSuffix(const TypeIdPtr &pPtr) const
{
ostringstream s;
int i = getSuffix(pPtr);
if(i >= 0)
{
s << "[" << i << "]";
}
return s.str();
}
/*******************************BuiltinPtr********************************/
string Tars2Php::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 Tars2Php::tostrBuiltin(const BuiltinPtr &pPtr) const
{
string s;
switch(pPtr->kind())
{
case Builtin::KindBool:
s = "c_char";
break;
case Builtin::KindByte:
s = (pPtr->isUnsigned()?"c_short":"c_char");
break;
case Builtin::KindShort:
s = (pPtr->isUnsigned()?"c_short":"c_short");
break;
case Builtin::KindInt:
s = (pPtr->isUnsigned()?"c_int":"c_int");
break;
case Builtin::KindLong:
s = "c_int64";
break;
case Builtin::KindFloat:
s = "c_float";
break;
case Builtin::KindDouble:
s = "c_double";
break;
case Builtin::KindString:
s = "c_string";
break;
case Builtin::KindVector:
s = "c_vector";
break;
case Builtin::KindMap:
s = "c_map";
break;
default:
assert(false);
break;
}
return s;
}
/*******************************VectorPtr********************************/
string Tars2Php::tostrVector(const VectorPtr &pPtr) const
{
string s = string("c_vector (new ") + tostr(pPtr->getTypePtr()) + string(")");
return s;
}
/*******************************MapPtr********************************/
string Tars2Php::tostrMap(const MapPtr &pPtr) const
{
string s = string("c_map (new ") + tostr(pPtr->getLeftTypePtr()) + ",new " + tostr(pPtr->getRightTypePtr()) + string(")");
return s;
}
/*******************************StructPtr********************************/
string Tars2Php::tostrStruct(const StructPtr &pPtr) const
{
return pPtr->getId();
}
/////////////////////////////////////////////////////////////////////
string Tars2Php::tostrEnum(const EnumPtr &pPtr) const
{
return "c_int";//pPtr->getId();
}
///////////////////////////////////////////////////////////////////////
string Tars2Php::generatePHP(const StructPtr &pPtr, const string& namespaceId) const
{
ostringstream s;
vector<TypeIdPtr>& member = pPtr->getAllMemberPtr();
s << TAB << "class " << pPtr->getId() << " extends c_struct" << endl;
s << TAB << "{" << endl;
INC_TAB;
//变量声明
for(size_t k = 0;k < member.size();k++)
{
s<< TAB << "public $" <<member[k]->getId()<<";"<<endl;
}
s<<endl;
s << TAB << "public function __clone()" << endl;
s << TAB << "{" << endl;
INC_TAB;
for(size_t k = 0;k < member.size();k++)
{
s<< TAB << "$this->" <<member[k]->getId()<<" = clone $this->"<<member[k]->getId()<<";"<<endl;
}
DEL_TAB;
s << TAB << "}" << endl;
s <<endl;
s << TAB << "public function __construct()" << endl;
s << TAB << "{" << endl;
INC_TAB;
for(size_t k = 0;k < member.size();k++)
{
s<< TAB << "$this->" <<member[k]->getId()<<" = new "<< tostr(member[k]->getTypePtr())<<";"<<endl;
}
DEL_TAB;
s << TAB << "}" << endl;
s <<endl;
////////////////////////////////////////////////////////////
s << TAB << "public function get_class_name()" << endl;
s << TAB << "{" << endl;
INC_TAB;
s << TAB << "return " << "\"" << namespaceId << "." << pPtr->getId() << "\"" << ";" << endl;
DEL_TAB;
s << TAB << "}" << endl;
s<<endl;
//write begin
s << TAB << "public function write(&$_out,$tag)" << endl;
s << TAB << "{" << endl;
INC_TAB;
s << TAB << "tars_header::_pack_header($_out,'c_struct_begin',$tag);" << endl;
for(size_t j = 0; j < member.size(); j++)
{
s << writeTo(member[j]);
}
s << TAB << "tars_header::_pack_header($_out,'c_struct_end',0);" << endl;
DEL_TAB;
s << TAB << "}" << endl;
//write end
///read begin
s << TAB << "public function read(&$_in,$tag,$isRequire = true)" << endl;
s << TAB << "{" << endl;
INC_TAB;
s << TAB << "tars_header::_check_struct($_in,$type,$tag,$isRequire);"<<endl;
s << TAB << "tars_header::_unpack_header($_in,$type,$this_tag);"<<endl;
for(size_t j = 0; j < member.size(); j++)
{
s << readFrom(member[j]);
}
s<< TAB << "$this->_skip_struct($_in);" << endl;
DEL_TAB;
s << TAB << "}" << endl;
//read end
DEL_TAB;
s << TAB << "}" << endl;
return s.str();
}
/******************************NamespacePtr***************************************/
string Tars2Php::generatePHP(const NamespacePtr &pPtr) const
{
ostringstream s;
vector<StructPtr> &ss = pPtr->getAllStructPtr();
for(size_t i = 0; i < ss.size(); i++)
{
s << generatePHP(ss[i], pPtr->getId()) << endl;
}
return s.str();
}
void Tars2Php::generatePHP(const ContextPtr &pPtr) const
{
string n = tars::TC_File::excludeFileExt(tars::TC_File::extractFileName(pPtr->getFileName()));
string fileH = m_sBaseDir + "/" + n + "_wup.php";
string define = "<?php";
ostringstream s;
s << define << endl;
s << endl;
s << g_parse->printHeaderRemark();
s << endl;
s << "require_once('tars.php');" <<endl;
s <<endl;
vector<NamespacePtr> namespaces = pPtr->getNamespaces();
for(size_t i = 0; i < namespaces.size(); i++)
{
s << generatePHP(namespaces[i]) << endl;
}
s << "?>"<<endl;
tars::TC_File::makeDirRecursive(m_sBaseDir, 0755);
tars::TC_File::save2file(fileH, s.str());
}
void Tars2Php::generatePHP_Pdu(const ContextPtr &pPtr) const
{
string n = tars::TC_File::excludeFileExt(tars::TC_File::extractFileName(pPtr->getFileName()));
string fileH = m_sBaseDir + "/" + n + "_pdu.php";
string define = "<?php";
ostringstream s;
s << define << endl;
s << endl;
s << g_parse->printHeaderRemark();
s << endl;
s << "require_once('tars.php');" <<endl;
vector<NamespacePtr> namespaces = pPtr->getNamespaces();
for(size_t i = 0; i < namespaces.size(); i++)
{
s << generatePHP(namespaces[i]) << endl;
}
s << "?>";
tars::TC_File::makeDirRecursive(m_sBaseDir, 0755);
tars::TC_File::save2file(fileH, s.str());
}
void Tars2Php::createFile(const string &file, const vector<string> &vsCoder)
{
std::vector<ContextPtr> contexts = g_parse->getContexts();
for(size_t i = 0; i < contexts.size(); i++)
{
if(file == contexts[i]->getFileName())
{
//tup版本的
generatePHP(contexts[i]);
}
}
}