diff options
Diffstat (limited to 'TAO/examples/Advanced/ch_18/icp.cpp')
-rw-r--r-- | TAO/examples/Advanced/ch_18/icp.cpp | 386 |
1 files changed, 0 insertions, 386 deletions
diff --git a/TAO/examples/Advanced/ch_18/icp.cpp b/TAO/examples/Advanced/ch_18/icp.cpp deleted file mode 100644 index e8ba75d6ef7..00000000000 --- a/TAO/examples/Advanced/ch_18/icp.cpp +++ /dev/null @@ -1,386 +0,0 @@ -// $Id$ -// ============================================================================ -// -// = LIBRARY -// TAO/examples/Advanced/ch_18 -// -// = FILENAME -// icp.cpp -// -// = AUTHORS -// Source code used in TAO has been modified and adapted from the code -// provided in the book, "Advanced CORBA Programming with C++" by Michi -// Henning and Steve Vinoski. Copyright 1999. Addison-Wesley, Reading, -// MA. -// -// Modified for TAO by Mike Moran <mm4@cs.wustl.edu> -// -// ============================================================================ - - - - -#include <string> -#include <map> -#include <algorithm> -#include "icp.h" -// #include <stdlib.h> - -//---------------------------------------------------------------- - -enum DeviceType { thermometer, thermostat }; - -struct DeviceState { // State for a device - DeviceType type; - const char * model; - string location; - short nominal_temp; // For thermostats only -}; -typedef map<unsigned long, DeviceState> StateMap; - -//---------------------------------------------------------------- - -const size_t MAXSTR = 32; // Max len of string including NUL - -const short MIN_TEMP = 40; // 40 F == 4.44 C -const short MAX_TEMP = 90; // 90 F == 32.22 C -const short DFLT_TEMP = 68; // 68 F == 20.00 C - -static StateMap dstate; // Map of known devices - -//---------------------------------------------------------------- - -// ICP_online() simulates adding a new device to the network by -// adding it to the dstate map. -// -// For this simple simulation, devices with odd asset numbers -// are thermometers and devices with even asset numbers -// are thermostats. -// -// Thermostats get an initial nominal temperature of DFLT_TEMP. -// The location string is intentionally left blank because it -// must be programmed by the controller after putting the device -// on-line (as should be the nominal temperature). -// -// If a device with the specified ID is already on-line, the -// return value is -1. A zero return value indicates success. - -extern "C" -int -ICP_online(unsigned long id) -{ - // Look for id in state map. - StateMap::iterator pos = dstate.find(id); - if (pos != dstate.end()) - return -1; // Already exists - - // Fill in state. - DeviceState ds; - ds.type = (id % 2) ? thermometer : thermostat; - ds.model = (ds.type == thermometer) - ? "Sens-A-Temp" : "Select-A-Temp"; - ds.nominal_temp = DFLT_TEMP; - - // Insert new device into map - dstate[id] = ds; - - return 0; -} - -//---------------------------------------------------------------- - -// ICP_offline() simulates removing a device from the network by -// removing it from the dstate map. If the device isn't known, the -// return value is -1. A zero return value indicates success. - -extern "C" -int -ICP_offline(unsigned long id) -{ - // Look for id in state map - StateMap::iterator pos = dstate.find(id); - if (pos == dstate.end()) - return -1; // No such device - dstate.erase(id); - return 0; -} - -//---------------------------------------------------------------- - -// vary_temp() simulates the variation in actual temperature -// around a thermostat.The function randomly varies the -// temperature as a percentage of calls as follows: -// -// 3 degrees too cold: 5% -// 3 degrees too hot: 5% -// 2 degrees too cold: 10% -// 2 degrees too hot: 10% -// 1 degree too cold: 15% -// 1 degree too hot: 15% -// exact temperature: 40% - -static -short -vary_temp(short temp) -{ - long r = lrand48() % 50; - long delta; - if (r < 5) - delta = 3; - else if (r < 15) - delta = 2; - else if (r < 30) - delta = 1; - else - delta = 0; - if (lrand48() % 2) - delta = -delta; - return temp + delta; -} - -//---------------------------------------------------------------- - -// Function object. Locates a thermostat that is in the same room -// as the device at position pos. - -class ThermostatInSameRoom { -public: - ThermostatInSameRoom( - const StateMap::iterator & pos - ) : m_pos(pos) {} - bool operator()( - pair<const unsigned long, DeviceState> & p - ) const - { - return( - p.second.type == thermostat - && p.second.location - == m_pos->second.location - ); - } -private: - const StateMap::iterator & m_pos; -}; - -//---------------------------------------------------------------- - -// actual_temp() is a helper function to determine the actual -// temperature returned by a particular thermometer or thermostat. -// The pos argument indicates the device. -// -// The function locates all thermostats that are in the same room -// as the device denoted by pos and computes the average of all -// the thermostats' nominal temperatures. (If no thermostats are -// in the same room as the device, the function assumes that the -// average of the nominal temperatures is DFLT_TEMP.) -// -// The returned temperature varies from the average as -// determined by vary_temp(). - -static -short -actual_temp(const StateMap::iterator & pos) -{ - long sum = 0; - long count = 0; - StateMap::iterator where = find_if( - dstate.begin(), dstate.end(), - ThermostatInSameRoom(pos) - ); - while (where != dstate.end()) { - count++; - sum += where->second.nominal_temp; - where = find_if( - ++where, dstate.end(), - ThermostatInSameRoom(pos) - ); - } - return vary_temp(count == 0 ? DFLT_TEMP : sum / count); -} - -//---------------------------------------------------------------- - -// ICP_get() returns an attribute value of the device with the -// given id. The attribute is named by the attr parameter. The -// value is copied into the buffer pointed to by the value -// pointer. The len parameter is the size of the passed buffer, -// so ICP_get can avoid overrunning the buffer. -// -// By default, thermometers report a temperature that varies -// somewhat around DFLT_TEMP. However, if there is another -// thermostat in the same room as the the thermometer, the -// thermometer reports a temperature that varies around that -// thermostat's temperature. For several thermostats that are in -// the same room, the thermometer reports around the average -// nominal temperature of all the thermostats. -// -// Attempts to read from a non-existent device or to read a -// non-existent attribute return -1. A return value of zero -// indicates success. If the supplied buffer is too short to hold -// a value, ICP_get() silently truncates the value and -// returns success. - -extern "C" -int -ICP_get( - unsigned long id, - const char * attr, - void * value, - size_t len) -{ - // Look for id in state map - StateMap::iterator pos = dstate.find(id); - if (pos == dstate.end()) - return -1; // No such device - - // Depending on the attribute, return the - // corresponding piece of state. - if (strcmp(attr, "model") == 0) { - strncpy((char *)value, pos->second.model, len); - } else if (strcmp(attr, "location") == 0) { - strncpy((char *)value, pos->second.location.c_str(), len); - } else if (strcmp(attr, "nominal_temp") == 0) { - if (pos->second.type != thermostat) - return -1; // Must be thermostat - memcpy( - value, &pos->second.nominal_temp, - min(len, sizeof(pos->second.nominal_temp)) - ); - } else if (strcmp(attr, "temperature") == 0) { - short temp = actual_temp(pos); - memcpy(value, &temp, min(len, sizeof(temp))); - } else if (strcmp(attr, "MIN_TEMP") == 0) { - memcpy(value, &MIN_TEMP, min(len, sizeof(MIN_TEMP))); - } else if (strcmp(attr, "MAX_TEMP") == 0) { - memcpy(value, &MAX_TEMP, min(len, sizeof(MAX_TEMP))); - } else { - return -1; // No such attribute - } - return 0; // OK -} - -//---------------------------------------------------------------- - -// ICP_set() sets the the attributed specified by attr to the -// value specified by value for the device with ID id. Attempts to -// write a string longer than MAXSTR bytes (including the -// terminating NUL) result in silent truncation of the string. -// Attempts to access a non-existent device or attribute -// return -1. Attempts to set a nominal temperature outside the -// legal range also return -1. A zero return value -// indicates success. - -extern "C" -int -ICP_set(unsigned long id, const char * attr, const void * value) -{ - // Look for id in state map - StateMap::iterator pos = dstate.find(id); - if (pos == dstate.end()) - return -1; // No such device - - // Change either location or nominal temp, depending on attr. - if (strcmp(attr, "location") == 0) { - pos->second.location.assign( - (const char *)value, MAXSTR - 1 - ); - } else if (strcmp(attr, "nominal_temp") == 0) { - if (pos->second.type != thermostat) - return -1; // Must be thermostat - short temp; - memcpy(&temp, value, sizeof(temp)); - if (temp < MIN_TEMP || temp > MAX_TEMP) - return -1; - pos->second.nominal_temp = temp; - } else { - return -1; // No such attribute - } - return 0; // OK -} - -//---------------------------------------------------------------- - -#include <fstream.h> - -class ICP_Persist { -public: - ICP_Persist(const char * file); - ~ICP_Persist(); -private: - string m_filename; -}; - -// Read device state from a file and initialize the dstate map. - -ICP_Persist:: -ICP_Persist(const char * file) : m_filename(file) -{ - // Open input file, creating it if necessary. - fstream db(m_filename.c_str(), ios::in|ios::out, 0666); - if (!db) { - cerr << "Error opening " << m_filename << endl; - exit(1); - } - - // Read device details, one attribute per line. - DeviceState ds; - unsigned long id; - while (db >> id) { - // Read device type and set model string accordingly. - int dtype; - db >> dtype; - ds.type = dtype == thermometer - ? thermometer : thermostat; - ds.model = dtype == thermometer - ? "Sens-A-Temp" : "Select-A-Temp"; - char loc[MAXSTR]; - db.get(loc[0]); // Skip newline - db.getline(loc, sizeof(loc)); // Read location - ds.location = loc; - if (ds.type == thermostat) - db >> ds.nominal_temp; // Read temperature - dstate[id] = ds; // Add entry to map - } - - //db.close(); - //if (!db) { - // cerr << "Error closing " << m_filename << endl; - // exit(1); - //} -} - -// Write device state to the file. - -ICP_Persist:: -~ICP_Persist() -{ - // Open input file, truncating it. - ofstream db(m_filename.c_str()); - if (!db) { - cerr << "Error opening " << m_filename << endl; - exit(1); - } - - // Write the state details for each device. - StateMap::iterator i; - for (i = dstate.begin(); i != dstate.end(); i++) { - db << i->first << endl; - db << (unsigned long)(i->second.type) << endl; - db << i->second.location << endl; - if (i->second.type == thermostat) - db << i->second.nominal_temp << endl; - } - if (!db) { - cerr << "Error writing " << m_filename << endl; - exit(1); - } - - db.close(); - if (!db) { - cerr << "Error closing " << m_filename << endl; - exit(1); - } -} - -// Instantiate a single global instance of the class. -static ICP_Persist mydb("/tmp/CCS_DB"); |