/usr/include/tango/pipe.h is in libtango-dev 9.2.5a+dfsg1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | //===================================================================================================================
//
// file : Pipe.h
//
// description : Include file for the Pipe class.
//
// project : TANGO
//
// author(s) : E.Taurel
//
// Copyright (C) : 2014,2015
// European Synchrotron Radiation Facility
// BP 220, Grenoble 38043
// FRANCE
//
// This file is part of Tango.
//
// Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along with Tango.
// If not, see <http://www.gnu.org/licenses/>.
//
// $Revision: 28947 $
//
//===================================================================================================================
#ifndef _PIPE_H
#define _PIPE_H
#include <tango.h>
#include <stdarg.h>
namespace Tango
{
#ifndef HAS_LAMBDA_FUNC
//
// Binary function objects to be used by the find_if algorithm.
// The find_if algo. want to have a predicate, this means that the return value must be a boolean (R is its name).
// The find_if algo. needs a unary predicate. This function object is a binary function object.
// It must be used with the bind2nd function adapter
//
template <typename A1,typename A2,typename R>
struct WantedPipe : public binary_function<A1,A2,R>
{
R operator() (A1 pipe_ptr, A2 name) const
{
if (::strlen(name) != pipe_ptr->get_lower_name().size())
return false;
string tmp_name(name);
transform(tmp_name.begin(),tmp_name.end(),tmp_name.begin(),::tolower);
return pipe_ptr->get_lower_name() == tmp_name;
}
};
#endif
/**
* This class is a class representing a pipe in the TANGO device server pattern. It is an abstract class.
* It is the root class for all pipe related classes.
*
* $Author: taurel $
* $Revision: 28947 $
*
* @headerfile tango.h
* @ingroup Server
*/
class Pipe
{
public:
/**@name Constructors
* Miscellaneous constructors */
//@{
/**
* Constructs a newly allocated Pipe object.
*
* The default constructor
*/
Pipe():ext(new PipeExt) {}
/**
* Constructs a newly allocated Pipe object from its
* name and its display level
*
* @param name The pipe name
* @param level The pipe display level
* @param pwt The pipe R/W type (default to READ)
*
*/
Pipe(const string &name,const Tango::DispLevel level,const PipeWriteType pwt=PIPE_READ);
//@}
/**@name Destructor
* Only one destructor is defined for this class */
//@{
/**
* The object desctructor.
*/
#ifdef HAS_UNIQUE_PTR
virtual ~Pipe() {}
#else
virtual ~Pipe() {delete ext;}
#endif
//@}
/**@name Miscellaneous methods */
//@{
//@}
/**@name Get/Set object members.
* These methods allows the external world to get/set Pipe instance
* data members
*/
//@{
/**
* Return the pipe name.
*
* @return The pipe name
*/
string &get_name() {return name;}
/**
* Set the pipe name.
*
* @param new_name The new pipe name
*/
void set_name(string &new_name) {name=new_name;}
/**
* Set default attribute properties
*
* @param prop The user default property class
*/
void set_default_properties(UserDefaultPipeProp &prop);
/**
* Return the pipe name in lower case letters.
*
* @return The pipe name
*/
string &get_lower_name() {return lower_name;}
/**
* Return the root data blob name.
*
* @return The data blob name
*/
const string &get_root_blob_name() {return the_blob.get_name();}
/**
* Set the root data blob name.
*
* @param [in] name The root data blob name
*/
void set_root_blob_name(const string &name) {the_blob.set_name(name);}
/**
* Return the pipe description.
*
* @return The pipe description
*/
string &get_desc() {return desc;}
/**
* Return the pipe label.
*
* @return The pipe label
*/
string &get_label() {return label;}
/**
* Return the pipe display level.
*
* @return The pipe display level
*/
Tango::DispLevel get_disp_level() {return disp_level;}
/**
* Get the pipe writable type (RO/RW).
*
* @return The pipe write type.
*/
Tango::PipeWriteType get_writable() {return writable;}
/**
* Set pipe serialization model
*
* This method allows the user to choose the pipe serialization model.
*
* @param [in] ser_model The new serialisation model. The serialization model must be
* one of PIPE_BY_KERNEL, PIPE_BY_USER or PIPE_NO_SYNC
*/
void set_pipe_serial_model(PipeSerialModel ser_model);
/**
* Get pipe serialization model
*
* Get the pipe serialization model
*
* @return The pipe serialization model
*/
PipeSerialModel get_pipe_serial_model() {return pipe_serial_model;}
/**
* Set pipe user mutex
*
* This method allows the user to give to the pipe object the pointer to
* the omni_mutex used to protect its buffer. The mutex has to be locked when passed
* to this method. The Tango kernel will unlock it when the data will be transferred
* to the client.
*
* @param [in] mut_ptr The user mutex pointer
*/
void set_user_pipe_mutex(omni_mutex *mut_ptr) {user_pipe_mutex = mut_ptr;}
//@}
/**@name Inserting data into a DevicePipe
*/
//@{
#ifdef GEN_DOC
/**
* Insert data into a device pipe
*
* Inserting data into a Pipe instance is simlar to inserting data into a DevicePipeBlob class instance.
* See doc of DevicePipeBlob class insertion methods (DevicePipeBlob::operator<<) to get a complete documentation on
* how to insert data into a Pipe object
*
* @param [in] datum The data to be inserted into the Pipe object
* @exception WrongData if requested
*/
Pipe & operator << (short &datum);
#endif
/**
* Set blob data element number
*
* Set the blob data element number
*
* @param [in] nb The blob data element number
*/
void set_data_elt_nb(size_t nb) {the_blob.set_data_elt_nb(nb);}
/**
* Set blob data element number and names
*
* Set the blob data element number and names. The data element number is the number of names in the input
* parameter.
*
* @param [in] names The blob data element names
*/
void set_data_elt_names(vector<string> &names) {the_blob.set_data_elt_names(names);}
/**
* Get blob data element number
*
* Get the blob data element number
*
* @return The blob data element number
*/
size_t get_data_elt_nb() {return the_blob.get_data_elt_nb();}
//@}
/**@name Exception and error related methods methods
*/
//@{
/**
* Set exception flag
*
* It's a method which allows the user to switch on/off exception throwing when trying to insert/extract data from a
* Pipe object. The following flags are supported :
* @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDataElement) if user
* tries to extract data from one empty blob data element. By default, this flag
* is set
* @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user
* tries to extract data with a type different than the type used for insertion. By default, this flag
* is set
* @li @b notenoughde_flag - throw a WrongData exception (reason = API_PipeWrongArg) if user
* tries to extract data from a DevicePipeBlob for a data element which does not exist. By default, this flag
* is set
* @li @b blobdenamenotset_flag - Throw a WrongData exception (reason = API_PipeNoDataElement) if user tries to
* insert data into the blob while the name or number of data element has not been set with methods
* set_data_elt_nb() or set_data_elt_names()
* @li @b mixing_flag - Throw a WrongData exception (reason = API_NotSupportedFeature) if user tries to mix
* insertion/extraction method (<< or >>) with operator[]
*
* @param [in] fl The exception flag
*/
void exceptions(bitset<DevicePipeBlob::numFlags> fl) {the_blob.exceptions(fl);}
/**
* Get exception flag
*
* Returns the whole exception flags.
* The following is an example of how to use these exceptions related methods
* @code
* Pipe pi;
*
* bitset<DevicePipeBlob::numFlags> bs = pi.exceptions();
* cout << "bs = " << bs << endl;
*
* pi.set_exceptions(DevicePipeBlob::wrongtype_flag);
* bs = pi.exceptions();
*
* cout << "bs = " << bs << endl;
* @endcode
*
* @return The exception flag
*/
bitset<DevicePipeBlob::numFlags> exceptions() {return the_blob.exceptions();}
/**
* Reset one exception flag
*
* Resets one exception flag
*
* @param [in] fl The exception flag
*/
void reset_exceptions(DevicePipeBlob::except_flags fl) {the_blob.reset_exceptions(fl);}
/**
* Set one exception flag
*
* Sets one exception flag. See DevicePipeBlob::exceptions() for a usage example.
*
* @param [in] fl The exception flag
*/
void set_exceptions(DevicePipeBlob::except_flags fl) {the_blob.set_exceptions(fl);}
/**
* Check insertion/extraction success
*
* Allow the user to check if insertion/extraction into/from Pipe instance was successfull. This
* method has to be used when exceptions are disabled.
*
* @return True if insertion/extraction has failed
*/
bool has_failed() {return the_blob.has_failed();}
/**
* Get instance insertion/extraction state
*
* Allow the user to find out what was the reason of insertion/extraction into/from Pipe failure. This
* method has to be used when exceptions are disabled.
* Here is an example of how methods has_failed() and state() could be used
* @code
* Pipe dpb = ....
*
* bitset<DevicePipeBlob::numFlags> bs;
* bs.reset();
* dpb.exceptions(bs);
*
* DevLong dl;
* dpb >> dl;
*
* if (dpb.has_failed() == true)
* {
* bitset<DevicePipeBlob::numFlags> bs_err = dpb.state();
* if (dpb.test(DevicePipeBlob::isempty_flag) == true)
* .....
* }
* @endcode
*
* @return The error bit set.
*/
bitset<DevicePipeBlob::numFlags> state() {return the_blob.state();}
//@}
/**@name set_value methods.
* Methods to set the value of the data blob to be transported by the pipe
*/
//@{
//@}
/// @privatesection
virtual bool is_allowed (DeviceImpl *dev,PipeReqType) {(void)dev;return true;}
virtual void read(DeviceImpl *) {}
Pipe &operator[](const string &);
bool get_value_flag() {return value_flag;}
void set_value_flag(bool val) {value_flag = val;}
void set_time();
Tango::TimeVal &get_when() {return when;}
void set_returned_data_ptr(DevPipeData *_p) {ret_data=_p;}
void set_label(const string &_lab) {label=_lab;}
void set_desc(const string &_desc) {desc=_desc;}
bool is_label_lib_default() {return label==name;}
bool is_desc_lib_default() {return desc==DescNotSpec;}
void set_upd_properties(const PipeConfig &,DeviceImpl *);
void set_properties(const Tango::PipeConfig &,DeviceImpl *,vector<Attribute::AttPropDb> &);
void upd_database(vector<Attribute::AttPropDb> &,string &);
vector<PipeProperty> &get_user_default_properties() {return user_def_prop;}
void set_one_str_prop(const char *,const CORBA::String_member &,string &,vector<Attribute::AttPropDb> &,vector<PipeProperty> &,vector<PipeProperty> &,const char *);
bool prop_in_list(const char *,string &,size_t,vector<PipeProperty> &);
DevicePipeBlob &get_blob() {return the_blob;}
omni_mutex *get_pipe_mutex() {return &pipe_mutex;}
omni_mutex *get_user_pipe_mutex() {return user_pipe_mutex;}
void fire_event(DeviceImpl *,DevFailed *);
#ifdef _TG_WINDOWS_
void fire_event(DeviceImpl *,DevicePipeBlob *,bool);
#else
void fire_event(DeviceImpl *_dev,DevicePipeBlob *_dat,bool bo) {struct timeval now;gettimeofday(&now,NULL);fire_event(_dev,_dat,now,bo);}
#endif
void fire_event(DeviceImpl *,DevicePipeBlob *,struct timeval &,bool);
void set_event_subscription(time_t _t) {event_subscription = _t;}
friend class EventSupplier;
friend class ZmqEventSupplier;
protected:
/**@name Class data members */
//@{
/**
* The pipe name
*/
string name;
/**
* The pipe name in lower case
*/
string lower_name;
/**
* The pipe description
*/
string desc;
/**
* The pipe label
*/
string label;
/**
* The pipe display level
*/
Tango::DispLevel disp_level;
/**
* The pipe R/W type
*/
Tango::PipeWriteType writable;
//@}
DevicePipeBlob the_blob;
private:
class PipeExt
{
public:
PipeExt() {}
};
#ifdef HAS_UNIQUE_PTR
unique_ptr<PipeExt> ext; // Class extension
#else
PipeExt *ext;
#endif
bool value_flag; // Flag set when pipe value is set
Tango::TimeVal when; // Date associated to the pipe
Tango::DevPipeData *ret_data; // Pointer for read data
vector<string> pe_out_names; // Data elements name
int rec_count; // Data elements ctr
PipeSerialModel pipe_serial_model; // Flag for attribute serialization model
omni_mutex pipe_mutex; // Mutex to protect the pipe shared data buffer
omni_mutex *user_pipe_mutex; // Ptr for user mutex in case he manages exclusion
time_t event_subscription; // Last time() a subscription was made
vector<PipeProperty> user_def_prop; // User default properties
};
template <typename T>
Pipe &operator<<(Pipe &,T &);
template <typename T>
Pipe &operator<<(Pipe &,T *);
template <typename T>
Pipe &operator<<(Pipe &, DataElement<T> &);
//
// Throw exception if pointer is null
//
#define PIPE_CHECK_PTR(A,B,C) \
if (A == NULL) \
{ \
stringstream o; \
o << "Data pointer for pipe " << B << ", data element " << C << " is NULL!"; \
Except::throw_exception(API_PipeOptProp,o.str(),"Pipe::set_value()"); \
} \
else \
(void)0
//
// Some inline methods
//
//+------------------------------------------------------------------------------------------------------------------
//
// method :
// Pipe::prop_in_list
//
// description :
// Search for a property in a list
// A similar method exists in Attribute class!!
//
// args:
// in :
// - prop_name : The property name
// - list_size : The size list
// - list : The list
// out :
// - prop_str : String initialized with prop. value (if found)
//
//------------------------------------------------------------------------------------------------------------------
inline bool Pipe::prop_in_list(const char *prop_name,string &prop_str,size_t list_size,vector<PipeProperty> &list)
{
bool ret = false;
if (list_size != 0)
{
size_t i;
for (i = 0;i < list_size;i++)
{
if (list[i].get_name() == prop_name)
break;
}
if (i != list_size)
{
prop_str = list[i].get_value();
ret = true;
}
}
return ret;
}
} // End of Tango namespace
#endif // _PIPE_H
|