Changes to attempt to silence bcc64x
[ACE_TAO.git] / TAO / examples / Advanced / ch_8_and_10 / server.cpp
blob8847fab5345b5fe49f6f8bbb1e2bee2c3215d06a
2 //=============================================================================
3 /**
4 * @file server.cpp
6 * @author Source code used in TAO has been modified and adapted from the codeprovided in the book
7 * @author "Advanced CORBA Programming with C++" by MichiHenning and Steve Vinoski. Copyright 1999. Addison-Wesley
8 * @author Reading
9 * @author MA.Modified for TAO by Mike Moran <mm4@cs.wustl.edu>
11 //=============================================================================
14 #include "server.h"
15 #include <algorithm>
16 #include "icp.h"
17 //#include <iostream.h>
18 //#include <assert.h>
19 //----------------------------------------------------------------
22 // Generic ostream inserter for exceptions. Inserts the exception
23 // name, if available, and the repository ID otherwise.
25 #if 0 //This inserter may or may not be needed for your ORB.
27 static ostream &
28 operator<< (ostream & os, const CORBA::Exception & e)
30 CORBA::Any tmp;
31 tmp <<= e;
32 CORBA::TypeCode_var tc = tmp.type ();
33 const char * p = tc->name ();
34 if (*p != '\0')
35 os << p;
36 else
37 os << tc->id ();
38 return os;
41 #endif
43 //----------------------------------------------------------------
45 Controller_impl * Thermometer_impl::m_ctrl; // static member
47 // Helper function to read the model string from a device.
49 CCS::ModelType
50 Thermometer_impl::
51 get_model ()
53 char buf[32];
54 assert (ICP_get (m_anum, "model", buf, sizeof (buf)) == 0);
55 return CORBA::string_dup (buf);
58 // Helper function to read the temperature from a device.
60 CCS::TempType
61 Thermometer_impl::
62 get_temp ()
64 short temp;
65 assert (
66 ICP_get (m_anum, "temperature", &temp, sizeof (temp)
67 ) == 0);
68 return temp;
71 // Helper function to read the location from a device.
73 CCS::LocType
74 Thermometer_impl::
75 get_loc ()
77 char buf[32];
78 assert (ICP_get (m_anum, "location", buf, sizeof (buf)) == 0);
79 return CORBA::string_dup (buf);
82 // Helper function to set the location of a device.
84 void
85 Thermometer_impl::
86 set_loc (const char * loc)
88 long result = 0;
89 result = ICP_set (m_anum, "location", loc);
90 assert (result == 0);
93 // Constructor.
95 Thermometer_impl::
96 Thermometer_impl (
97 CCS::AssetType anum,
98 const char * location
99 ) : m_anum (anum)
101 assert (ICP_online (anum) == 0); // Mark device as on-line
102 set_loc (location);
103 m_ctrl->add_impl (anum, this); // Add self to controller's map
106 // Destructor.
108 Thermometer_impl::
109 ~Thermometer_impl ()
111 try {
112 m_ctrl->remove_impl (m_anum); // Remove self from map
113 ICP_offline (m_anum); // Mark device as off-line
115 catch (...) {
116 assert (0); // Prevent exceptions from escaping
120 // IDL model attribute.
122 CCS::ModelType
123 Thermometer_impl::model ()
125 return get_model ();
128 // IDL asset_num attribute.
130 CCS::AssetType
131 Thermometer_impl::asset_num ()
133 return m_anum;
136 // IDL temperature attribute.
138 CCS::TempType
139 Thermometer_impl::temperature ()
141 return get_temp ();
144 // IDL location attribute accessor.
146 CCS::LocType
147 Thermometer_impl::location ()
149 return get_loc ();
152 // IDL location attribute modifier.
154 void
155 Thermometer_impl::location (const char * loc)
157 set_loc (loc);
160 //----------------------------------------------------------------
162 // Helper function to get a thermostat's nominal temperature.
164 CCS::TempType
165 Thermostat_impl::get_nominal_temp ()
167 short temp;
168 assert (
169 ICP_get (m_anum, "nominal_temp", &temp, sizeof (temp)
170 ) == 0);
171 return temp;
174 // Helper function to set a thermostat's nominal temperature.
176 CCS::TempType
177 Thermostat_impl::
178 set_nominal_temp (CCS::TempType new_temp)
180 short old_temp;
182 // We need to return the previous nominal temperature,
183 // so we first read the current nominal temperature before
184 // changing it.
185 assert (ICP_get (
186 m_anum, "nominal_temp",
187 &old_temp, sizeof (old_temp)
188 ) == 0
191 // Now set the nominal temperature to the new value.
192 if (ICP_set (m_anum, "nominal_temp", &new_temp) != 0) {
193 // If ICP_set () failed, read this thermostat's minimum
194 // and maximum so we can initialize the BadTemp exception.
195 CCS::Thermostat::BtData btd;
196 ICP_get (
197 m_anum, "MIN_TEMP",
198 &btd.min_permitted, sizeof (btd.min_permitted)
200 ICP_get (
201 m_anum, "MAX_TEMP",
202 &btd.max_permitted, sizeof (btd.max_permitted)
204 btd.requested = new_temp;
205 btd.error_msg = CORBA::string_dup (
206 new_temp > btd.max_permitted ? "Too hot" : "Too cold"
208 throw CCS::Thermostat::BadTemp (btd);
210 return old_temp;
213 // Constructor.
215 Thermostat_impl::
216 Thermostat_impl (
217 CCS::AssetType anum,
218 const char * location,
219 CCS::TempType nominal_temp
220 ) : Thermometer_impl (anum, location)
222 // Base Thermometer_impl constructor does most of the
223 // work, so we need only set the nominal temperature here.
224 set_nominal_temp (nominal_temp);
227 // IDL get_nominal operation.
229 CCS::TempType
230 Thermostat_impl::get_nominal ()
232 return get_nominal_temp ();
235 // IDL set_nominal operation.
237 CCS::TempType
238 Thermostat_impl::
239 set_nominal (CCS::TempType new_temp)
241 return set_nominal_temp (new_temp);
244 //----------------------------------------------------------------
246 // Helper function for thermometers and thermostats to
247 // add themselves to the m_assets map.
249 void
250 Controller_impl::
251 add_impl (CCS::AssetType anum, Thermometer_impl * tip)
253 m_assets[anum] = tip;
256 // Helper function for thermometers and thermostats to
257 // remove themselves from the m_assets map.
259 void
260 Controller_impl::
261 remove_impl (CCS::AssetType anum)
263 m_assets.erase (anum);
266 // IDL list operation.
268 CCS::Controller::ThermometerSeq *
269 Controller_impl::list ()
271 // Create a new thermometer sequence. Because we know
272 // the number of elements we will put onto the sequence,
273 // we use the maximum constructor.
274 CCS::Controller::ThermometerSeq_var listv
275 = new CCS::Controller::ThermometerSeq (m_assets.size ());
276 listv->length (m_assets.size ());
278 // Loop over the m_assets map and create a
279 // reference for each device.
280 CORBA::ULong count = 0;
281 AssetMap::iterator i;
282 for (i = m_assets.begin (); i != m_assets.end (); i++)
283 listv[count++] = i->second->_this ();
284 return listv._retn ();
287 // IDL change operation.
289 void
290 Controller_impl::
291 change (
292 const CCS::Controller::ThermostatSeq & tlist,
293 CORBA::Short delta
296 CCS::Controller::EChange ec; // Just in case we need it
298 // We cannot add a delta value to a thermostat's temperature
299 // directly, so for each thermostat, we read the nominal
300 // temperature, add the delta value to it, and write
301 // it back again.
302 for (CORBA::ULong i = 0; i < tlist.length (); i++) {
303 if (CORBA::is_nil (tlist[i]))
304 continue; // Skip nil references
306 // Read nominal temp and update it.
307 CCS::TempType tnom = tlist[i]->get_nominal ();
308 tnom += delta;
309 try {
310 tlist[i]->set_nominal (tnom);
312 catch (const CCS::Thermostat::BadTemp & bt) {
313 // If the update failed because the temperature
314 // is out of range, we add the thermostat's info
315 // to the errors sequence.
316 CORBA::ULong len = ec.errors.length ();
317 ec.errors.length (len + 1);
318 ec.errors[len].tmstat_ref = tlist[i];
319 ec.errors[len].info = bt.details;
323 // If we encountered errors in the above loop,
324 // we will have added elements to the errors sequence.
325 if (ec.errors.length () != 0)
326 throw ec;
329 // IDL find operation
331 void
332 Controller_impl::
333 find (CCS::Controller::SearchSeq & slist)
335 // Loop over input list and look up each device.
336 CORBA::ULong listlen = slist.length ();
337 for (CORBA::ULong i = 0; i < listlen; i++) {
338 AssetMap::iterator where; // Iterator for asset map
339 int num_found = 0; // Num matched per iteration
341 // Assume we will not find a matching device.
342 slist[i].device = CCS::Thermometer::_nil ();
344 // Work out whether we are searching by asset,
345 // model, or location.
346 CCS::Controller::SearchCriterion sc = slist[i].key._d ();
347 if (sc == CCS::Controller::ASSET) {
348 // Search for matching asset number.
349 where = m_assets.find (slist[i].key.asset_num ());
350 if (where != m_assets.end ())
351 slist[i].device = where->second->_this ();
352 } else {
353 // Search for model or location string.
354 const char * search_str;
355 if (sc == CCS::Controller::LOCATION)
356 search_str = slist[i].key.loc ();
357 else
358 search_str = slist[i].key.model_desc ();
360 // Find first matching device (if any).
361 where = std::find_if (
362 m_assets.begin (), m_assets.end (),
363 StrFinder (sc, search_str)
366 // While there are matches...
367 while (where != m_assets.end ()) {
368 if (num_found == 0) {
369 // First match overwrites reference
370 // in search record.
371 slist[i].device = where->second->_this ();
372 } else {
373 // Each further match appends a new
374 // element to the search sequence.
375 CORBA::ULong len = slist.length ();
376 slist.length (len + 1);
377 slist[len].key = slist[i].key;
378 slist[len].device = where->second->_this ();
380 num_found++;
382 // Find next matching device with this key.
383 where = std::find_if (
384 ++where, m_assets.end (),
385 StrFinder (sc, search_str)
390 std::cerr << "end" << std::endl;
393 //----------------------------------------------------------------
396 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
398 try {
399 // Initialize orb
400 CORBA::ORB_var orb = CORBA::ORB_init (argc, argv);
402 // Get reference to Root POA.
403 CORBA::Object_var obj
404 = orb->resolve_initial_references ("RootPOA");
405 PortableServer::POA_var poa
406 = PortableServer::POA::_narrow (obj.in ());
408 // Activate POA manager
409 PortableServer::POAManager_var mgr
410 = poa->the_POAManager ();
411 mgr->activate ();
413 // Create a controller and set static m_ctrl member
414 // for thermostats and thermometers.
415 Controller_impl ctrl_servant;
416 Thermometer_impl::m_ctrl = &ctrl_servant;
418 // Write controller stringified reference to stdout
419 CCS::Controller_var ctrl = ctrl_servant._this ();
420 CORBA::String_var str = orb->object_to_string (ctrl.in ());
421 std::cout << str.in () << std::endl << std::endl;
423 // Create a few devices. (Thermometers have odd asset
424 // numbers, thermostats have even asset numbers.)
425 Thermometer_impl thermo1 (2029, "Deep Thought");
426 Thermometer_impl thermo2 (8053, "HAL");
427 Thermometer_impl thermo3 (1027, "ENIAC");
429 Thermostat_impl tmstat1 (3032, "Colossus", 68);
430 Thermostat_impl tmstat2 (4026, "ENIAC", 60);
431 Thermostat_impl tmstat3 (4088, "ENIAC", 50);
432 Thermostat_impl tmstat4 (8042, "HAL", 40);
434 // Accept requests
435 orb->run ();
437 catch (const CORBA::Exception & e) {
438 std::cerr << "Uncaught CORBA exception: "
439 << e
440 << std::endl;
441 return 1;
443 catch (...) {
444 assert (0); // Unexpected exception, dump core
446 return 0;