⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpcgen.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * =========================================================================== * PRODUCTION $Log: rpcgen.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 19:43:40  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13 * PRODUCTION * =========================================================================== *//*  $Id: rpcgen.cpp,v 1000.3 2004/06/01 19:43:40 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Author:  Aaron Ucko, NCBI** File Description:*   ASN.1/XML RPC client generator** ===========================================================================*/#include <ncbi_pch.hpp>#include <serial/datatool/exceptions.hpp>#include <serial/datatool/rpcgen.hpp>#include <serial/datatool/choicetype.hpp>#include <serial/datatool/classstr.hpp>#include <serial/datatool/code.hpp>#include <serial/datatool/generate.hpp>#include <serial/datatool/srcutil.hpp>#include <serial/datatool/statictype.hpp>#include <serial/datatool/stdstr.hpp>BEGIN_NCBI_SCOPE// Does all the actual workclass CClientPseudoTypeStrings : public CClassTypeStrings{public:    CClientPseudoTypeStrings(const CClientPseudoDataType& source);    void GenerateClassCode(CClassCode& code, CNcbiOstream& getters,                           const string& methodPrefix, bool haveUserClass,                           const string& classPrefix) const;private:    const CClientPseudoDataType& m_Source;};static void s_SplitName(const string& name, string& type, string& field){    for (SIZE_TYPE pos = name.find('.');  pos != NPOS;         pos = name.find('.', pos + 1)) {        if (islower(name[pos + 1])) {            type.assign(name, 0, pos);            field.assign(name, pos + 1, NPOS);            return;        }    }    type.assign(name);    field.erase();}static const CChoiceDataType* s_ChoiceType(const CDataType* dtype,                                           const string& element){    vector<string> v;    if ( !element.empty() ) {        NStr::Tokenize(element, ".", v);    }    ITERATE (vector<string>, subelement, v) {        const CDataMemberContainerType* dct            = dynamic_cast<const CDataMemberContainerType*>(dtype);        if ( !dct ) {            NCBI_THROW(CDatatoolException, eInvalidData,                       dtype->GlobalName() + " is not a container type");        }        bool found = false;        ITERATE (CDataMemberContainerType::TMembers, it, dct->GetMembers()) {            if ((*it)->GetName() == *subelement) {                found = true;                dtype = (*it)->GetType()->Resolve();                break;            }        }        if (!found) {            NCBI_THROW(CDatatoolException, eInvalidData,                       dtype->GlobalName() + " has no element " + *subelement);        }    }    const CChoiceDataType* choicetype        = dynamic_cast<const CChoiceDataType*>(dtype);    if ( !choicetype ) {        NCBI_THROW(CDatatoolException, eInvalidData,                   dtype->GlobalName() + " is not a choice type");    }    return choicetype;}static string s_SetterName(const string& element) {    if (element.empty()) {        return kEmptyStr;    }    SIZE_TYPE start = 0, dot;    string    result;    do {        dot = element.find('.', start);        result += ".Set" + Identifier(element.substr(start, dot - start))            + "()";        start = dot + 1;    } while (dot != NPOS);    return result;}CClientPseudoDataType::CClientPseudoDataType(const CCodeGenerator& generator,                                             const string& section_name,                                             const string& class_name)    : m_Generator(generator), m_SectionName(section_name),      m_ClassName(class_name){    // Just take the first potential module; should normally give sane    // results.    SetParent(generator.GetMainModules().GetModuleSets().front()              ->GetModules().front().get(),              class_name);    s_SplitName(generator.GetConfig().Get(m_SectionName, "request"),                m_RequestType, m_RequestElement);    s_SplitName(generator.GetConfig().Get(m_SectionName, "reply"),                m_ReplyType, m_ReplyElement);    if (m_RequestType.empty()) {        NCBI_THROW(CDatatoolException, eInvalidData,                   "No request type supplied for " + m_ClassName);    } else if (m_ReplyType.empty()) {        NCBI_THROW(CDatatoolException, eInvalidData,                   "No reply type supplied for " + m_ClassName);    }    m_RequestDataType = m_Generator.ResolveMain(m_RequestType);    m_ReplyDataType = m_Generator.ResolveMain(m_ReplyType);    _ASSERT(m_RequestDataType  &&  m_ReplyDataType);    m_RequestChoiceType = s_ChoiceType(m_RequestDataType, m_RequestElement);    m_ReplyChoiceType   = s_ChoiceType(m_ReplyDataType,   m_ReplyElement);}AutoPtr<CTypeStrings>CClientPseudoDataType::GenerateCode(void) const{    return new CClientPseudoTypeStrings(*this);}CClientPseudoTypeStrings::CClientPseudoTypeStrings(const CClientPseudoDataType& source)    : CClassTypeStrings(kEmptyStr, source.m_ClassName), m_Source(source){    // SetClassNamespace(generator.GetNamespace()); // not defined(!)    SetParentClass("CRPCClient<" + source.m_RequestDataType->ClassName()                   + ", " + source.m_ReplyDataType->ClassName() + '>',                   CNamespace::KNCBINamespace, "serial/rpcbase");    SetObject(true);    SetHaveUserClass(true);    SetHaveTypeInfo(false);}static string s_QualClassName(const CDataType* dt){    _ASSERT(dt);    string result;    const CDataType* parent = dt->GetParentType();    if (parent) {        result = s_QualClassName(parent) + "::";    }    result += dt->ClassName();    return result;}void CClientPseudoTypeStrings::GenerateClassCode(CClassCode& code,                                                 CNcbiOstream& /* getters */,                                                 const string& /* methodPfx */,                                                 bool /* haveUserClass */,                                                 const string& /* classPfx */)    const{    const string&         sect_name  = m_Source.m_SectionName;    const string&         class_name = m_Source.m_ClassName;    string                class_base = class_name + "_Base";    const CCodeGenerator& generator  = m_Source.m_Generator;    string                treq       = class_base + "::TRequest";    string                trep       = class_base + "::TReply";    const CNamespace&     ns         = code.GetNamespace();    // Pull in the relevant headers, and add corresponding typedefs    code.HPPIncludes().insert(m_Source.m_RequestDataType->FileName());    code.ClassPublic() << "    typedef "                       << m_Source.m_RequestDataType->ClassName()                       << " TRequest;\n";    code.HPPIncludes().insert(m_Source.m_ReplyDataType->FileName());    code.ClassPublic() << "    typedef "                       << m_Source.m_ReplyDataType->ClassName()                       << " TReply;\n";    if ( !m_Source.m_RequestElement.empty() ) {        code.HPPIncludes().insert(m_Source.m_RequestChoiceType->FileName());        code.ClassPublic() << "    typedef "                           << s_QualClassName(m_Source.m_RequestChoiceType)                           << " TRequestChoice;\n";        code.ClassPrivate() << "    TRequest m_DefaultRequest;\n\n";    } else {        code.ClassPublic() << "    typedef TRequest TRequestChoice;\n";    }    {{        if ( !m_Source.m_ReplyElement.empty() ) {            code.HPPIncludes().insert(m_Source.m_ReplyChoiceType->FileName());            code.ClassPublic() << "    typedef "                               << s_QualClassName(m_Source.m_ReplyChoiceType)                               << " TReplyChoice;\n\n";        } else {            code.ClassPublic() << "    typedef TReply TReplyChoice;\n\n";        }        code.ClassPrivate()            << "    TReplyChoice& x_Choice(TReply& reply);\n";        code.MethodStart(true)            << trep << "Choice& " << class_base << "::x_Choice(" << trep            << "& reply)\n"            << "{\n    return reply" << s_SetterName(m_Source.m_ReplyElement)            << ";\n}\n\n";    }}    {{        // Figure out arguments to parent's constructor        string service = generator.GetConfig().Get(sect_name, "service");        string format  = generator.GetConfig().Get(sect_name, "serialformat");        string args;        if (service.empty()) {            ERR_POST(Warning << "No service name provided for " << class_name);            args = "kEmptyStr";        } else {            args = '\"' + NStr::PrintableString(service) + '\"';        }        if ( !format.empty() ) {            args += ", eSerial_" + format;        }        code.AddInitializer("Tparent", args);    }}    // This should just be a simple using-declaration, but that breaks    // on GCC 2.9x at least, even with a full parent class name :-/    code.ClassPublic()        // << "    using Tparent::Ask;\n"        << "    virtual void Ask(const TRequest& request, TReply& reply);\n"        << "    virtual void Ask(const TRequest& request, TReply& reply,\n"        << "                     TReplyChoice::E_Choice wanted);\n\n";    // second version defined further down    code.MethodStart(true)        << "void " << class_base << "::Ask(const " << treq << "& request, "        << trep << "& reply)\n"        << "{\n    Tparent::Ask(request, reply);\n}\n\n\n";    // Add appropriate infrastructure if TRequest is not itself the choice    // (m_DefaultRequest declared earlier to reduce ugliness)    if ( !m_Source.m_RequestElement.empty() ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -