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

📄 server.cpp

📁 一套Orbacus4.X下有关Corba的学习例程
💻 CPP
字号:
#include    <OB/CORBA.h>#include    <algorithm>#include    <signal.h>#include    <string>#ifdef HAVE_FSTREAM#   include <fstream>#else#   include <fstream.h>#endif#if defined(HAVE_STD_IOSTREAM) || defined(HAVE_STD_STL)using namespace std;#endif#include    "icp.h"#include    "server.h"//----------------------------------------------------------------// Helper function to write a stringified reference to a file.voidwrite_ref(const char * filename, const char * reference){    ofstream file(filename);    if (!file) {        string msg("Error opening ");        msg += filename;        throw msg.c_str();    }    file << reference << endl;    if (!file) {        string msg("Error writing ");        msg += filename;        throw msg.c_str();    }    file.close();    if (!file) {        string msg("Error closing ");        msg += filename;        throw msg.c_str();    }}//----------------------------------------------------------------Controller_impl * Thermometer_impl::m_ctrl; // static member// Helper function to read the model string from a device.CCS::ModelTypeThermometer_impl::get_model(){    char buf[32];    if (ICP_get(m_anum, "model", buf, sizeof(buf)) != 0)        abort();    return CORBA::string_dup(buf);}// Helper function to read the temperature from a device.CCS::TempTypeThermometer_impl::get_temp(){    short temp;    if (ICP_get(m_anum, "temperature", &temp, sizeof(temp)) != 0)        abort();    return temp;}// Helper function to read the location from a device.CCS::LocTypeThermometer_impl::get_loc(){    char buf[32];    if (ICP_get(m_anum, "location", buf, sizeof(buf)) != 0)        abort();    return CORBA::string_dup(buf);}// Helper function to set the location of a device.voidThermometer_impl::set_loc(const char * loc){    if (ICP_set(m_anum, "location", loc) != 0)        abort();}// Constructor.Thermometer_impl::Thermometer_impl(    CCS::AssetType      anum,    const char *        location) : m_anum(anum){    if (ICP_online(anum) != 0)      // Mark device as on-line        abort();    set_loc(location);              // Set its location    m_ctrl->add_impl(anum, this);   // Add self to controller's map}// Destructor.Thermometer_impl::~Thermometer_impl(){    try {        m_ctrl->remove_impl(m_anum); // Remove self from map        ICP_offline(m_anum);         // Mark device as off-line    } catch (...) {        abort();        // Prevent exceptions from escaping    }}// IDL model attribute.CCS::ModelTypeThermometer_impl::model() throw(CORBA::SystemException){    return get_model();}// IDL asset_num attribute.CCS::AssetTypeThermometer_impl::asset_num() throw(CORBA::SystemException){    return m_anum;}// IDL temperature attribute.CCS::TempTypeThermometer_impl::temperature() throw(CORBA::SystemException){    return get_temp();}// IDL location attribute accessor.CCS::LocTypeThermometer_impl::location() throw(CORBA::SystemException){    return get_loc();}// IDL location attribute modifier.voidThermometer_impl::location(const char * loc) throw(CORBA::SystemException){    set_loc(loc);}//----------------------------------------------------------------// Helper function to get a thermostat's nominal temperature.CCS::TempTypeThermostat_impl::get_nominal_temp(){    short temp;    if (ICP_get(m_anum, "nominal_temp", &temp, sizeof(temp)) != 0)        abort();    return temp;}// Helper function to set a thermostat's nominal temperature.CCS::TempTypeThermostat_impl::set_nominal_temp(CCS::TempType new_temp)throw(CCS::Thermostat::BadTemp){    short old_temp;    // We need to return the previous nominal temperature,    // so we first read the current nominal temperature before    // changing it.    if (ICP_get(        m_anum, "nominal_temp", &old_temp, sizeof(old_temp)       ) != 0) {        abort();    }    // Now set the nominal temperature to the new value.    if (ICP_set(m_anum, "nominal_temp", &new_temp) != 0) {        // If ICP_set() failed, read this thermostat's minimum        // and maximum so we can initialize the BadTemp exception.        CCS::Thermostat::BtData btd;        ICP_get(            m_anum, "MIN_TEMP",            &btd.min_permitted, sizeof(btd.min_permitted)        );        ICP_get(            m_anum, "MAX_TEMP",            &btd.max_permitted, sizeof(btd.max_permitted)        );        btd.requested = new_temp;        btd.error_msg = CORBA::string_dup(            new_temp > btd.max_permitted ? "Too hot" : "Too cold"        );        throw CCS::Thermostat::BadTemp(btd);    }    return old_temp;}// Constructor.Thermostat_impl::Thermostat_impl(    CCS::AssetType      anum,    const char *        location,    CCS::TempType       nominal_temp) : Thermometer_impl(anum, location){    // Base Thermometer_impl constructor does most of the    // work, so we need only set the nominal temperature here.    set_nominal_temp(nominal_temp);}// IDL get_nominal operation.CCS::TempTypeThermostat_impl::get_nominal() throw(CORBA::SystemException){    return get_nominal_temp();}// IDL set_nominal operation.CCS::TempTypeThermostat_impl::set_nominal(CCS::TempType new_temp)throw(CORBA::SystemException, CCS::Thermostat::BadTemp){    return set_nominal_temp(new_temp);}//----------------------------------------------------------------// Helper function for thermometers and thermostats to// add themselves to the m_assets map.voidController_impl::add_impl(CCS::AssetType anum, Thermometer_impl * tip){    m_assets[anum] = tip;}// Helper function for thermometers and thermostats to// remove themselves from the m_assets map.voidController_impl::remove_impl(CCS::AssetType anum){    m_assets.erase(anum);}// IDL list operation.CCS::Controller::ThermometerSeq *Controller_impl::list() throw(CORBA::SystemException){    // Create a new thermometer sequence. Because we know    // the number of elements we will put onto the sequence,    // we use the maximum constructor.    CCS::Controller::ThermometerSeq_var listv        = new CCS::Controller::ThermometerSeq(m_assets.size());    listv->length(m_assets.size());    // Loop over the m_assets map and create a    // reference for each device.    CORBA::ULong count = 0;    AssetMap::iterator i;    for (i = m_assets.begin(); i != m_assets.end(); ++i)        listv[count++] = i->second->_this();    return listv._retn();}// IDL change operation.voidController_impl::change(    const CCS::Controller::ThermostatSeq &  tlist,    CORBA::Short                            delta) throw(CORBA::SystemException, CCS::Controller::EChange){    CCS::Controller::EChange ec;    // Just in case we need it    // We cannot add a delta value to a thermostat's temperature    // directly, so for each thermostat, we read the nominal    // temperature, add the delta value to it, and write    // it back again.    CORBA::ULong i;    for (i = 0; i < tlist.length(); ++i) {        if (CORBA::is_nil(tlist[i]))            continue;                       // Skip nil references        // Read nominal temp and update it.        CCS::TempType tnom = tlist[i]->get_nominal();        tnom += delta;        try {            tlist[i]->set_nominal(tnom);        }        catch (const CCS::Thermostat::BadTemp & bt) {            // If the update failed because the temperature            // is out of range, we add the thermostat's info            // to the errors sequence.            CORBA::ULong len = ec.errors.length();            ec.errors.length(len + 1);            ec.errors[len].tmstat_ref = tlist[i];            ec.errors[len].info = bt.details;        }    }    // If we encountered errors in the above loop,    // we will have added elements to the errors sequence.    if (ec.errors.length() != 0)        throw ec;}// IDL find operationvoidController_impl::find(CCS::Controller::SearchSeq & slist)throw(CORBA::SystemException){    // Loop over input list and look up each device.    CORBA::ULong listlen = slist.length();    CORBA::ULong i;    for (i = 0; i < listlen; ++i) {        AssetMap::iterator where;   // Iterator for asset map        int num_found = 0;          // Num matched per iteration        // Assume we will not find a matching device.        slist[i].device = CCS::Thermometer::_nil();        // Work out whether we are searching by asset,        // model, or location.        CCS::Controller::SearchCriterion sc = slist[i].key._d();        if (sc == CCS::Controller::ASSET) {            // Search for matching asset number.            where = m_assets.find(slist[i].key.asset_num());            if (where != m_assets.end())                slist[i].device = where->second->_this();        } else {            // Search for model or location string.            const char * search_str;            if (sc == CCS::Controller::LOCATION)                search_str = slist[i].key.loc();            else                search_str = slist[i].key.model_desc();            // Find first matching device (if any).            where = find_if(                        m_assets.begin(), m_assets.end(),                        StrFinder(sc, search_str)                    );            // While there are matches...            while (where != m_assets.end()) {                if (num_found == 0) {                    // First match overwrites reference                    // in search record.                    slist[i].device = where->second->_this();                } else {                    // Each further match appends a new                    // element to the search sequence.                    CORBA::ULong len = slist.length();                    slist.length(len + 1);                    slist[len].key = slist[i].key;                    slist[len].device = where->second->_this();                }                ++num_found;                // Find next matching device with this key.                where = find_if(                            ++where, m_assets.end(),                            StrFinder(sc, search_str)                        );            }        }    }}//----------------------------------------------------------------voidrun(CORBA::ORB_ptr orb){    // Get reference to Root POA.    CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");    PortableServer::POA_var poa = PortableServer::POA::_narrow(obj);    // Create a controller and set static m_ctrl member    // for thermostats and thermometers.    Controller_impl ctrl_servant;    Thermometer_impl::m_ctrl = &ctrl_servant;    // Write controller stringified reference to ctrl.ref.    CCS::Controller_var ctrl = ctrl_servant._this();    CORBA::String_var str = orb->object_to_string(ctrl);    write_ref("ctrl.ref", str);    // Create a few devices. (Thermometers have odd asset    // numbers, thermostats have even asset numbers.)    Thermometer_impl thermo1(2029, "Deep Thought");    Thermometer_impl thermo2(8053, "HAL");    Thermometer_impl thermo3(1027, "ENIAC");    Thermostat_impl tmstat1(3032, "Colossus", 68);    Thermostat_impl tmstat2(4026, "ENIAC", 60);    Thermostat_impl tmstat3(4088, "ENIAC", 50);    Thermostat_impl tmstat4(8042, "HAL", 40);    // Write a thermostat reference to tmstat.ref.    CCS::Thermostat_var tmstat = tmstat1._this();    str = orb->object_to_string(tmstat);    write_ref("tmstat.ref", str);    // Activate POA manager    PortableServer::POAManager_var mgr = poa->the_POAManager();    mgr->activate();    // Accept requests    orb->run();}//----------------------------------------------------------------static CORBA::ORB_var orb; // Global, so handler can see it.//----------------------------------------------------------------#ifdef WIN32BOOLhandler(DWORD){    // Inform JTC of presence of new thread    JTCAdoptCurrentThread adopt;    // Terminate event loop    try {        if (!CORBA::is_nil(orb))            orb->shutdown(false);    } catch (...) {        // Can't throw here...    }    return TRUE;}#elseextern "C"voidhandler(int){     // Ignore further signals    struct sigaction ignore;    ignore.sa_handler = SIG_IGN;    sigemptyset(&ignore.sa_mask);    ignore.sa_flags = 0;    if (sigaction(SIGINT, &ignore, (struct sigaction *)0) == -1)        abort();    if (sigaction(SIGTERM, &ignore, (struct sigaction *)0) == -1)        abort();    if (sigaction(SIGHUP, &ignore, (struct sigaction *)0) == -1)        abort();    // Terminate event loop    try {        if (!CORBA::is_nil(orb))            orb->shutdown(false);    } catch (...) {        // Can't throw here...    }}#endif//----------------------------------------------------------------intmain(int argc, char* argv[]){    // Install signal handler for cleanup#ifdef WIN32    BOOL rc = SetConsoleCtrlHandler((PHANDLER_ROUTINE)handler, TRUE);    if (!rc)        abort();#else    struct sigaction sa;            // New signal state    sa.sa_handler = handler;        // Set handler function    sigfillset(&sa.sa_mask);        // Mask all other signals                                    // while handler runs    sa.sa_flags = 0 | SA_RESTART;   // Restart interrupted syscalls    if (sigaction(SIGINT, &sa, (struct sigaction *)0) == -1)        abort();    if (sigaction(SIGHUP, &sa, (struct sigaction *)0) == -1)        abort();    if (sigaction(SIGTERM, &sa, (struct sigaction *)0) == -1)        abort();#endif    // Initialize the ORB and start working...    int status = 0;    try {        orb = CORBA::ORB_init(argc, argv);        run(orb);    } catch (const CORBA::Exception & ex) {        cerr << "Uncaught CORBA exception: " << ex << endl;        status = 1;    } catch (...) {        cerr << "Uncaught non-CORBA exception" << endl;        status = 1;    }    // Destroy the ORB.    if (!CORBA::is_nil(orb)) {        try {            orb->destroy();        } catch (const CORBA::Exception & ex) {            cerr << "Cannot destroy ORB: " << ex << endl;            status = 1;        }    }    return status;}

⌨️ 快捷键说明

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