release
[tango-nonfree.git] / lib / cpp / client / DevicePipe.h
blob701a474771389870bf7b2819468e4af1df30491b
1 //===================================================================================================================
2 //
3 // DevicePipe.h - include file for TANGO device api class DevicePipe
4 //
5 //
6 // Copyright (C) : 2014,2015
7 // European Synchrotron Radiation Facility
8 // BP 220, Grenoble 38043
9 // FRANCE
11 // This file is part of Tango.
13 // Tango is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
14 // License as published by the Free Software Foundation, either version 3 of the License, or
15 // (at your option) any later version.
17 // Tango is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
18 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
21 // You should have received a copy of the GNU Lesser General Public License along with Tango.
22 // If not, see <http://www.gnu.org/licenses/>.
24 // $Revision: 29869 $
26 //===================================================================================================================
28 #ifndef _DEVICEPIPE_H
29 #define _DEVICEPIPE_H
31 /**
32 * Fundamental type for extracting data from a device pipe blob
34 * This is the fundamental type for extracting data from a device pipe blob
36 * $Author: taurel $
37 * $Revision: 29869 $
39 * @headerfile tango.h
40 * @ingroup Client
43 template <typename T>
44 struct DataElement
46 /**
47 * Create a DataElement object.
49 * Create a DataElement object for device pipe blob extraction
51 * @param [in] name The data element name
52 * @param [in] value The data element value
54 DataElement(const string &name,T value);
55 /**
56 * Create a DataElement object.
58 * Create a DataElement object for device pipe blob extraction
60 * @param [in] name The data element name
62 DataElement(const string &name);
63 /**
64 * Create a DataElement object.
66 * Create a DataElement object for device pipe blob extraction. Usefull for extraction into TANGO CORBA
67 * sequence. See DevicePipeBlob extraction method
69 * @param [in] value The data element value
71 DataElement(T value);
73 DataElement();
75 string name; ///< The data element name
76 T value; ///< The data element value
79 template <typename T>
80 DataElement<T>::DataElement(const string &_na,T _val):name(_na),value(_val)
84 template <typename T>
85 DataElement<T>::DataElement(const string &_na):name(_na)
89 template <typename T>
90 DataElement<T>::DataElement(T _val):value(_val)
94 template <typename T>
95 DataElement<T>::DataElement()
99 /**
100 * A device pipe blob
102 * A device pipe blob. A blob is used to pack data to be sent through device pipe
104 * $Author: taurel $
105 * $Revision: 29869 $
107 * @headerfile tango.h
108 * @ingroup Client
111 class DevicePipeBlob
113 public:
114 ///@privatesection
116 enum except_flags
118 isempty_flag,
119 wrongtype_flag,
120 notenoughde_flag,
121 blobdenamenotset_flag,
122 mixing_flag,
123 numFlags
126 ///@publicsection
127 /**@name Constructors */
128 //@{
130 * Create a DevicePipeBlob object.
132 * Default constructor.
135 DevicePipeBlob();
137 * Create a DevicePipeBlob object with name
139 * Create one instance of the DevicePipeBlob class and set its name
141 * @param [in] blob_name The blob name
143 DevicePipeBlob(const string &blob_name);
144 //@}
146 /**@name Get/Set methods */
147 //@{
149 * Set blob name
151 * Set the blob name
153 * @param [in] blob_name The blob name
155 void set_name(const string &blob_name) {name=blob_name;}
157 * Get blob name
159 * Get the blob name
161 * @return The blob name
163 const string &get_name() {return name;}
164 //@}
167 /**@name Inserting data into a DevicePipeBlob
169 //@{
171 * Insert data into a data blob
173 * According to the data to be inserted into the blob data element, several kinds of insetor methods have been
174 * implemented. You can insert data from:
175 * @li Scalar data type
176 * @li vector
177 * @li TANGO CORBA sequence types (by reference)
178 * @li TANGO CORBA sequence types (by pointer)
179 * @li DataElement<T> with T being scalar data type
180 * @li DataElement<T> with T being vector
181 * @li DataElement<T> with T being TANGO CORBA sequence type (by reference)
182 * @li DataElement<T> with T being TANGO CORBA sequence type (by pointer)
184 * When inserting data using a DataElement<T> instance, the data element name is also set.
185 * <B>For insertion from TANGO CORBA sequence type pointer, the insertion method consumes the
186 * memory allocated to store the data and it will be freed by the Tango layer.</B>
188 * Insert operators for the following scalar C++ types (and DataElement<T>)
189 * @li bool
190 * @li short
191 * @li DevLong
192 * @li DevLong64
193 * @li float
194 * @li double
195 * @li unsigned char
196 * @li unsigned short
197 * @li DevULong
198 * @li DevULong64
199 * @li DevString
200 * @li string
201 * @li DevState
202 * @li DevEncoded
204 * Insert operators for the following C++ vector types (and DataElement<T>)
205 * @li vector<bool>
206 * @li vector<short>
207 * @li vector<DevLong>
208 * @li vector<DevLong64>
209 * @li vector<float>
210 * @li vector<double>
211 * @li vector<unsigned char>
212 * @li vector<unsigned short>
213 * @li vector<DevULong>
214 * @li vector<DevULong64>
215 * @li vector<DevSstring>
216 * @li vector<string>
217 * @li vector<DevState>
219 * Insert operators for the following CORBA sequence types (and DataElement<T>):
220 * @li DevVarBooleanArray &
221 * @li DevVarShortArray &
222 * @li DevVarLongArray &
223 * @li DevVarLong64Array &
224 * @li DevVarFloatArray &
225 * @li DevVarDoubleArray &
226 * @li DevVarUCharArray &
227 * @li DevVarUShortArray &
228 * @li DevVarULongArray &
229 * @li DevVarULong64Array &
230 * @li DevVarStringArray &
231 * @li DevVarStateArray &
233 * Insert operators for the following CORBA sequence types <B>with memory consumption</B> (and DataElement<T>):
234 * @li DevVarBooleanArray *
235 * @li DevVarShortArray *
236 * @li DevVarLongArray *
237 * @li DevVarLong64Array *
238 * @li DevVarFloatArray *
239 * @li DevVarDoubleArray *
240 * @li DevVarUCharArray *
241 * @li DevVarUShortArray *
242 * @li DevVarULongArray *
243 * @li DevVarULong64Array *
244 * @li DevVarStringArray *
245 * @li DevVarStateArray *
247 * Here is an example of inserting data into a DevicePipeBlob instance. We insert
248 * 3 data element into the pipe blob with a DevLong, a vector of doubles and finally an array of 100 unsigned short
249 * @code
250 * DevicePipeBlob dpb("MyBlob");
252 * vector<string> de_names = {"FirstDE","SecondDE","ThirdDE"};
253 * dpb.set_data_elt_names(de_names);
255 * DevLong dl = 666;
256 * vector<double> v_db = {1.11,2.22};
257 * unsigned short *array = new unsigned short [100]; // The array is populated by a way or another
259 * DevVarUShortArray *dvush = create_DevVarUShortArray(array,100);
261 * try
263 * dpb << dl << v_db << dvush;
265 * catch (DevFailed &e)
267 * cout << "DevicePipeBlob insertion failed" << endl;
268 * ....
271 * @endcode
272 * The same example of inserting data into a DevicePipeBlob instance when we want to set the data element name.
273 * @code
274 * DevicePipeBlob dpb("MyBlob");
276 * DataElement<DevLong> de_dl("FirstDE",666);
278 * vector<double> v_db = {1.11,2.22};
279 * DataElement<vector<double> > de_v_db("SecondDE",v_db);
281 * unsigned short *array = new unsigned short [100]; // The array is populated by a way or another
282 * DevVarUShortArray *dvush = create_DevVarUShortArray(array,100);
283 * DataElement<DevVarUShortArray *> de_dvush("ThirdDE",array);
285 * try
287 * dpb << de_dl << de_v_db << de_dvush;
289 * catch (DevFailed &e)
291 * cout << "DevicePipeBlob insertion failed" << endl;
292 * ....
295 * ...
296 * @endcode
297 * It is also possible to do the insertion in a third way
298 * @code
299 * DevicePipeBlob dpb("MyBlob");
301 * vector<string> de_names{"FirstDE","SecondDE","ThirdDE"};
302 * dpb.set_data_elt_names(de_names);
304 * DevLong dl = 666;
305 * vector<double> v_db = {1.11,2.22};
306 * unsigned short *array = new unsigned short [100]; // The array is populated by a way or another
308 * DevVarUShortArray *dvush = create_DevVarUShortArray(array,100);
310 * dpb["FirstDE"] << dl;
311 * dpb["SecondDE"] << v_db;
312 * dpb["ThirdDE"] << dvush;
314 * @endcode
316 * @param [in] datum The data to be inserted into the DevicePipeBlob
317 * @exception WrongData if requested
319 DevicePipeBlob & operator << (short &datum);
321 * Set blob data element number
323 * Set the blob data element number
325 * @param [in] nb The blob data element number
327 void set_data_elt_nb(size_t nb);
329 * Set blob data element number and names
331 * Set the blob data element number and names. The data element number is the number of names in the input
332 * parameter.
334 * @param [in] names The blob data element names
336 void set_data_elt_names(vector<string> &names);
337 //@}
339 /**@name Extracting data from a DevicePipeBlob
341 //@{
343 * Extract data from a data blob
345 * According to the data inside blob data element, several kinds of extractor methods have been implemented. You
346 * can extract data into:
347 * @li Scalar data type
348 * @li vector
349 * @li TANGO CORBA sequence types
350 * @li DataElement<T> with T being scalar data type
351 * @li DataElement<T> with T being vector
352 * @li DataElement<T> with T being TANGO CORBA sequence type
354 * When extracting data using a DataElement<T> instance, the data element name is also returned.
355 * <B>For extraction into C++ vector, data are copied into the vector. It is not the case for extraction into TANGO
356 * CORBA sequence type. For extraction into TANGO CORBA sequence types, the extraction method consumes the
357 * memory allocated to store the data and it is the caller responsibility to delete this memory.</B>
359 * Extract operators for the following scalar C++ types (and DataElement<T>)
360 * @li bool
361 * @li short
362 * @li DevLong
363 * @li DevLong64
364 * @li float
365 * @li double
366 * @li unsigned char
367 * @li unsigned short
368 * @li DevULong
369 * @li DevULong64
370 * @li string
371 * @li DevState
372 * @li DevEncoded
374 * Extract operators for the following C++ vector types (and DataElement<T>)
375 * @li vector<bool>
376 * @li vector<short>
377 * @li vector<DevLong>
378 * @li vector<DevLong64>
379 * @li vector<float>
380 * @li vector<double>
381 * @li vector<unsigned char>
382 * @li vector<unsigned short>
383 * @li vector<DevULong>
384 * @li vector<DevULong64>
385 * @li vector<string>
386 * @li vector<DevState>
388 * Extract operators for the following CORBA sequence types <B>with memory consumption</B> (and DataElement<T>):
389 * @li DevVarBooleanArray *
390 * @li DevVarShortArray *
391 * @li DevVarLongArray *
392 * @li DevVarLong64Array *
393 * @li DevVarFloatArray *
394 * @li DevVarDoubleArray *
395 * @li DevVarUCharArray *
396 * @li DevVarUShortArray *
397 * @li DevVarULongArray *
398 * @li DevVarULong64Array *
399 * @li DevVarStringArray *
400 * @li DevVarStateArray *
402 * Here is an example of extracting data from a DevicePipeBlob instance. We know that the DevicePipeBlob contains
403 * 3 data element with a DevLong, an array of doubles and finally an array of unsigned short
404 * @code
405 * DevicePipeBlob dpb = .....
407 * DevLong dl;
408 * vector<double> v_db;
409 * DevVarUShortArray *dvush = new DevVarUShortArray();
411 * try
413 * dpb >> dl >> v_db >> dvush;
415 * catch (DevFailed &e)
417 * cout << "DevicePipeBlob extraction failed" << endl;
418 * ....
421 * delete dvush;
422 * @endcode
423 * The same example of extracting data from a DevicePipeBlob instance when we want to retrieve the data element name.
424 * @code
425 * DevicePipeBlob dpb = .....
427 * DataElement<DevLong> de_dl;
428 * DataElement<vector<double> > de_v_db;
429 * DataElement<DevVarUShortArray *> de_dvush(new DevVarUShortArray());
431 * try
433 * dpb >> de_dl >> de_v_db >> de_dvush;
435 * catch (DevFailed &e)
437 * cout << "DevicePipeBlob extraction failed" << endl;
438 * ....
441 * cout << "Data element name = " << de_dl.name << " - Value = " << de_dl.value << endl;
442 * ...
443 * delete de_dvush.value;
444 * @endcode
445 * It is also possible to do the extraction in a generic way
446 * @code
447 * DevicePipeBlob dpb = .....
449 * size_t nb_de = dpb.get_data_elt_nb();
450 * for (size_t loop = 0;loop < nb;loop++)
452 * int data_type = dpb.get_data_elt_type(loop);
453 * string de_name = dpb.get_data_elt_name(loop);
454 * switch(data_type)
456 * case DEV_LONG:
458 * DevLong lg;
459 * dpb >> lg;
461 * break;
463 * case DEVVAR_DOUBLEARRAY:
465 * vector<double> v_db;
466 * dpb >> v_db;
468 * break;
469 * ....
471 * ...
473 * @endcode
474 * Note that instead of using DevLong and vector<double> data, the extraction can be done using DataElement<T>
475 * instances. In this case, the call to the get_data_elt_name() method becomes useless.
477 * @param [out] datum The blob data
478 * @exception WrongData if requested
480 DevicePipeBlob & operator >> (short &datum);
482 * Get blob data element number
484 * Get the blob data element number
486 * @return The blob data element number
488 size_t get_data_elt_nb();
490 * Get blob data elements name
492 * Get the blob data elements name
494 * @return The blob data elements name
496 vector<string> get_data_elt_names();
498 * Get blob data element name
500 * Get the blob data element name for a single data element
502 * @param [in] ind The data element index within the blob
503 * @return The blob data element name
505 string get_data_elt_name(size_t ind);
507 * Get blob data element value type
509 * Get the blob data element value type for a single data element
511 * @param [in] ind The data element index within the blob
512 * @return The blob data element value type
514 int get_data_elt_type(size_t ind);
515 //@}
517 /**@name Exception and error related methods methods
519 //@{
521 * Set exception flag
523 * It's a method which allows the user to switch on/off exception throwing when trying to extract data from a
524 * DevicePipeBlob object. The following flags are supported :
525 * @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDataElement) if user
526 * tries to extract data from one empty blob data element. By default, this flag
527 * is set
528 * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user
529 * tries to extract data with a type different than the type used for insertion. By default, this flag
530 * is set
531 * @li @b notenoughde_flag - throw a WrongData exception (reason = API_PipeWrongArg) if user
532 * tries to extract data from a DevicePipeBlob for a data element which does not exist. By default, this flag
533 * is set
534 * @li @b blobdenamenotset_flag - Throw a WrongData exception (reason = API_PipeNoDataElement) if user tries to
535 * insert data into the blob while the name or number of data element has not been set with methods
536 * set_data_elt_nb() or set_data_elt_names()
537 * @li @b mixing_flag - Throw a WrongData exception (reason = API_NotSupportedFeature) if user tries to mix
538 * insertion/extraction method (<< or >>) with operator[]
540 * @param [in] fl The exception flag
542 void exceptions(bitset<numFlags> fl) {exceptions_flags = fl;}
544 * Get exception flag
546 * Returns the whole exception flags.
547 * The following is an example of how to use these exceptions related methods
548 * @code
549 * DevicePipeBlob dpb;
551 * bitset<DevicePipeBlob::numFlags> bs = dpb.exceptions();
552 * cout << "bs = " << bs << endl;
554 * dpb.set_exceptions(DevicePipeBlob::wrongtype_flag);
555 * bs = dpb.exceptions();
557 * cout << "bs = " << bs << endl;
558 * @endcode
560 * @return The exception flag
562 bitset<numFlags> exceptions() {return exceptions_flags;}
564 * Reset one exception flag
566 * Resets one exception flag
568 * @param [in] fl The exception flag
570 void reset_exceptions(except_flags fl) {exceptions_flags.reset((size_t)fl);}
572 * Set one exception flag
574 * Sets one exception flag. See DevicePipeBlob::exceptions() for a usage example.
576 * @param [in] fl The exception flag
578 void set_exceptions(except_flags fl) {exceptions_flags.set((size_t)fl);}
580 * Check insertion/extraction success
582 * Allow the user to check if insertion/extraction into/from DevicePipeBlob instance was successfull. This
583 * method has to be used when exceptions are disabled.
585 * @return True if insertion/extraction has failed
587 bool has_failed();
589 * Get instance insertion/extraction state
591 * Allow the user to find out what was the reason of insertion/extraction into/from DevicePipeBlob failure. This
592 * method has to be used when exceptions are disabled.
593 * Here is an example of how methods has_failed() and state() could be used
594 * @code
595 * DevicePipeBlob dpb = ....
597 * bitset<DevicePipeBlob::numFlags> bs;
598 * bs.reset();
599 * dpb.exceptions(bs);
601 * DevLong dl;
602 * dpb >> dl;
604 * if (dpb.has_failed() == true)
606 * bitset<DevicePipeBlob::numFlags> bs_err = dpb.state();
607 * if (bs_err.test(DevicePipeBlob::isempty_flag) == true)
608 * .....
610 * @endcode
612 * @return The error bit set.
614 bitset<numFlags> state() {return ext_state;}
615 //@}
617 ///@privatesection
618 ~DevicePipeBlob();
619 DevicePipeBlob(const DevicePipeBlob &);
620 DevicePipeBlob & operator=(const DevicePipeBlob &);
621 #ifdef HAS_RVALUE
622 DevicePipeBlob(DevicePipeBlob &&);
623 DevicePipeBlob & operator=(DevicePipeBlob &&);
624 #endif
626 DevicePipeBlob & operator << (DevBoolean &);
627 // DevicePipeBlob & operator << (short &);
628 DevicePipeBlob & operator << (DevLong &);
629 DevicePipeBlob & operator << (DevLong64 &);
630 DevicePipeBlob & operator << (float &);
631 DevicePipeBlob & operator << (double &);
632 DevicePipeBlob & operator << (DevUChar &);
633 DevicePipeBlob & operator << (DevUShort &);
634 DevicePipeBlob & operator << (DevULong &);
635 DevicePipeBlob & operator << (DevULong64 &);
636 DevicePipeBlob & operator << (DevString &);
637 DevicePipeBlob & operator << (DevState &);
638 DevicePipeBlob & operator << (DevEncoded &);
639 DevicePipeBlob & operator << (const string &);
641 DevicePipeBlob & operator << (DevicePipeBlob &);
643 DevicePipeBlob & operator << (vector<DevBoolean> &);
644 DevicePipeBlob & operator << (vector<short> &);
645 DevicePipeBlob & operator << (vector<DevLong> &);
646 DevicePipeBlob & operator << (vector<DevLong64> &);
647 DevicePipeBlob & operator << (vector<float> &);
648 DevicePipeBlob & operator << (vector<double> &);
649 DevicePipeBlob & operator << (vector<DevUChar> &);
650 DevicePipeBlob & operator << (vector<DevUShort> &);
651 DevicePipeBlob & operator << (vector<DevULong> &);
652 DevicePipeBlob & operator << (vector<DevULong64> &);
653 DevicePipeBlob & operator << (vector<DevString> &);
654 DevicePipeBlob & operator << (vector<DevState> &);
655 DevicePipeBlob & operator << (vector<DevEncoded> &);
656 DevicePipeBlob & operator << (vector<string> &);
658 DevicePipeBlob & operator << (DevVarBooleanArray &);
659 DevicePipeBlob & operator << (DevVarShortArray &);
660 DevicePipeBlob & operator << (DevVarLongArray &);
661 DevicePipeBlob & operator << (DevVarLong64Array &);
662 DevicePipeBlob & operator << (DevVarFloatArray &);
663 DevicePipeBlob & operator << (DevVarDoubleArray &);
664 DevicePipeBlob & operator << (DevVarUCharArray &);
665 DevicePipeBlob & operator << (DevVarUShortArray &);
666 DevicePipeBlob & operator << (DevVarULongArray &);
667 DevicePipeBlob & operator << (DevVarULong64Array &);
668 DevicePipeBlob & operator << (DevVarStringArray &);
669 DevicePipeBlob & operator << (DevVarStateArray &);
670 DevicePipeBlob & operator << (DevVarEncodedArray &);
672 DevicePipeBlob & operator << (DevVarBooleanArray *);
673 DevicePipeBlob & operator << (DevVarShortArray *);
674 DevicePipeBlob & operator << (DevVarLongArray *);
675 DevicePipeBlob & operator << (DevVarLong64Array *);
676 DevicePipeBlob & operator << (DevVarFloatArray *);
677 DevicePipeBlob & operator << (DevVarDoubleArray *);
678 DevicePipeBlob & operator << (DevVarUCharArray *);
679 DevicePipeBlob & operator << (DevVarUShortArray *);
680 DevicePipeBlob & operator << (DevVarULongArray *);
681 DevicePipeBlob & operator << (DevVarULong64Array *);
682 DevicePipeBlob & operator << (DevVarStringArray *);
683 DevicePipeBlob & operator << (DevVarStateArray *);
684 DevicePipeBlob & operator << (DevVarEncodedArray *);
686 //-------------------------------------------------------------------------------------------------
688 DevicePipeBlob & operator >> (DevBoolean &);
689 // DevicePipeBlob & operator >> (short &);
690 DevicePipeBlob & operator >> (DevLong &);
691 DevicePipeBlob & operator >> (DevLong64 &);
692 DevicePipeBlob & operator >> (float &);
693 DevicePipeBlob & operator >> (double &);
694 DevicePipeBlob & operator >> (DevUChar &);
695 DevicePipeBlob & operator >> (DevUShort &);
696 DevicePipeBlob & operator >> (DevULong &);
697 DevicePipeBlob & operator >> (DevULong64 &);
698 DevicePipeBlob & operator >> (DevString &);
699 DevicePipeBlob & operator >> (DevState &);
700 DevicePipeBlob & operator >> (DevEncoded &);
701 DevicePipeBlob & operator >> (string &);
703 DevicePipeBlob & operator >> (DevicePipeBlob &);
705 DevicePipeBlob & operator >> (vector<DevBoolean> &);
706 DevicePipeBlob & operator >> (vector<short> &);
707 DevicePipeBlob & operator >> (vector<DevLong> &);
708 DevicePipeBlob & operator >> (vector<DevLong64> &);
709 DevicePipeBlob & operator >> (vector<float> &);
710 DevicePipeBlob & operator >> (vector<double> &);
711 DevicePipeBlob & operator >> (vector<DevUChar> &);
712 DevicePipeBlob & operator >> (vector<DevUShort> &);
713 DevicePipeBlob & operator >> (vector<DevULong> &);
714 DevicePipeBlob & operator >> (vector<DevULong64> &);
715 DevicePipeBlob & operator >> (vector<string> &);
716 DevicePipeBlob & operator >> (vector<DevState> &);
717 // DevicePipeBlob & operator >> (vector<DevEncoded> &);
719 DevicePipeBlob & operator >> (DevVarBooleanArray *);
720 DevicePipeBlob & operator >> (DevVarShortArray *);
721 DevicePipeBlob & operator >> (DevVarLongArray *);
722 DevicePipeBlob & operator >> (DevVarLong64Array *);
723 DevicePipeBlob & operator >> (DevVarFloatArray *);
724 DevicePipeBlob & operator >> (DevVarDoubleArray *);
725 DevicePipeBlob & operator >> (DevVarUCharArray *);
726 DevicePipeBlob & operator >> (DevVarUShortArray *);
727 DevicePipeBlob & operator >> (DevVarULongArray *);
728 DevicePipeBlob & operator >> (DevVarULong64Array *);
729 DevicePipeBlob & operator >> (DevVarStringArray *);
730 DevicePipeBlob & operator >> (DevVarStateArray *);
731 DevicePipeBlob & operator >> (DevVarEncodedArray *);
733 DevicePipeBlob &operator[](const string &);
735 const char *get_current_delt_name() {return (*extract_elt_array)[extract_ctr].name.in();}
736 void set_current_delt_name(const string &);
738 size_t get_extract_ind_from_name(const string &);
739 size_t get_insert_ind_from_name(const string &);
741 void reset_insert_ctr() {insert_ctr=0;}
742 DevVarPipeDataEltArray *get_insert_data() {return insert_elt_array;}
743 const DevVarPipeDataEltArray *get_extract_data() {return extract_elt_array;}
745 void set_extract_data(const DevVarPipeDataEltArray *_ptr) {extract_elt_array=_ptr;}
746 void reset_insert_data_ptr() {insert_elt_array=Tango_nullptr;}
748 void reset_extract_ctr() {extract_ctr=0;}
749 void set_extract_delete(bool _b) {extract_delete=_b;}
751 void print(ostream &,int,bool);
753 protected:
754 ///@privatesection
755 void throw_type_except(const string &,const string &);
756 void throw_too_many(const string &,bool);
757 void throw_is_empty(const string &);
758 void throw_name_not_set(const string &);
759 void throw_mixing(const string &);
761 private:
762 string name; // The blob name
763 bitset<numFlags> exceptions_flags; // Exception flag
764 bitset<numFlags> ext_state; // Extraction state
765 bool failed; // Failed flag
767 DevVarPipeDataEltArray *insert_elt_array; // Ptr for data to be inserted (client write/Server read)
768 int insert_ctr; // Ctr for inserting data elt
769 int insert_ind;
771 const DevVarPipeDataEltArray *extract_elt_array; // Ptr for data to be extracted (client read/Server write)
772 int extract_ctr; // Ctr for extracting data elt
773 bool extract_delete; // Flag to force extract ptr delete
774 int extract_ind;
776 class DevicePipeBlobExt
778 public:
779 DevicePipeBlobExt() {};
782 #ifdef HAS_UNIQUE_PTR
783 unique_ptr<DevicePipeBlobExt> ext;
784 #else
785 DevicePipeBlobExt *ext; // Class extension
786 #endif
790 /****************************************************************************************
792 * The DevicePipe class *
793 * -------------------- *
795 ***************************************************************************************/
799 * Fundamental type for sending/receiving data from device pipes
801 * This is the fundamental type for sending/receiving data to/from device pipe.
803 * $Author: taurel $
804 * $Revision: 29869 $
806 * @headerfile tango.h
807 * @ingroup Client
810 class DevicePipe
813 public :
815 ///@publicsection
816 /**@name Constructors */
817 //@{
819 * Create a DevicePipe object.
821 * Default constructor. The instance is empty
824 DevicePipe();
826 * Create a DevicePipe object with name
828 * Create one instance of the DevicePipe class and set its name
830 * @param [in] pipe_name The pipe name
832 DevicePipe(const string &pipe_name);
834 * Create a DevicePipe object with name and root blob name.
836 * Create one instance of the DevicePipe class and set its name and its root blob name
838 * @param [in] pipe_name The pipe name
839 * @param [in] root_blob_name The root blob name
841 DevicePipe(const string &pipe_name,const string &root_blob_name);
842 //@}
844 /**@name Get/Set methods */
845 //@{
847 * Set pipe name
849 * Set the device pipe name
851 * @param [in] pipe_name The pipe name
853 void set_name(const string &pipe_name) {name=pipe_name;}
855 * Get pipe name
857 * Set the device pipe name
859 * @return The pipe name
861 const string &get_name() {return name;}
864 * Set root blob name
866 * Set the root blob name
868 * @param [in] root_blob_name The root blob name
870 void set_root_blob_name(const string &root_blob_name) {the_root_blob.set_name(root_blob_name);}
872 * Get root blob name
874 * Get the root blob name
876 * @return The root blob name
878 const string &get_root_blob_name() {return the_root_blob.get_name();}
879 //@}
881 /**@name Inserting data into a DevicePipe
883 //@{
884 #ifdef GEN_DOC
886 * Insert data into a device pipe
888 * Inserting data into a DevicePipe instance is simlar to inserting data into a DevicePipeBlob class instance.
889 * See doc of DevicePipeBlob class insertion methods (DevicePipeBlob::operator<<) to get a complete documentation on
890 * how to insert data into a DevicePipe
892 * @param [in] datum The data to be inserted into the DevicePipe
893 * @exception WrongData if requested
895 DevicePipe & operator << (short &datum);
896 #endif
898 * Set blob data element number
900 * Set the blob data element number
902 * @param [in] nb The blob data element number
904 void set_data_elt_nb(size_t nb) {the_root_blob.set_data_elt_nb(nb);}
906 * Set blob data element number and names
908 * Set the blob data element number and names. The data element number is the number of names in the input
909 * parameter.
911 * @param [in] names The blob data element names
913 void set_data_elt_names(vector<string> &names) {the_root_blob.set_data_elt_names(names);}
914 //@}
916 /**@name Extracting data from a DevicePipe
918 //@{
919 #ifdef GEN_DOC
921 * Extract data from a device pipe
923 * Extracting data from a DevicePipe instance is simlar to extracting data from a DevicePipeBlob class instance.
924 * See doc of DevicePipeBlob class extraction methods (DevicePipeBlob::operator>>) to get a complete documentation on
925 * how to extract data from a DevicePipe
927 * @param [in] datum The pipe data
928 * @exception WrongData if requested
930 DevicePipe & operator >> (short &datum);
931 #endif
933 * Get root blob data element number
935 * Get the root blob data element number
937 * @return The root blob data element number
939 size_t get_data_elt_nb() {return the_root_blob.get_data_elt_nb();}
941 * Get root blob data elements name
943 * Get the root blob data elements name
945 * @return The root blob data elements name
947 vector<string> get_data_elt_names() {return the_root_blob.get_data_elt_names();}
949 * Get root blob data element name
951 * Get root blob data element name for a single data element
953 * @param [in] ind The data element index within the root blob
954 * @return The root blob data element name
956 string get_data_elt_name(size_t ind) {return the_root_blob.get_data_elt_name(ind);}
958 * Get root blob data element value type
960 * Get root blob data element value type for a single data element
962 * @param [in] ind The data element index within the root blob
963 * @return The root blob data element value type
965 int get_data_elt_type(size_t ind) {return the_root_blob.get_data_elt_type(ind);}
966 //@}
969 /**@name Exception and error related methods methods
971 //@{
973 * Set exception flag
975 * It's a method which allows the user to switch on/off exception throwing when trying to insert/extract data from a
976 * DevicePipe object. The following flags are supported :
977 * @li @b isempty_flag - throw a WrongData exception (reason = API_EmptyDataElement) if user
978 * tries to extract data from one empty pipe data element. By default, this flag
979 * is set
980 * @li @b wrongtype_flag - throw a WrongData exception (reason = API_IncompatibleArgumentType) if user
981 * tries to extract data with a type different than the type used for insertion. By default, this flag
982 * is set
983 * @li @b notenoughde_flag - throw a WrongData exception (reason = API_PipeWrongArg) if user
984 * tries to extract data from a DevicePipe for a data element which does not exist. By default, this flag
985 * is set
986 * @li @b blobdenamenotset_flag - Throw a WrongData exception (reason = API_PipeNoDataElement) if user tries to
987 * insert data into the blob while the name or number of data element has not been set with methods
988 * set_data_elt_nb() or set_data_elt_names()
989 * @li @b mixing_flag - Throw a WrongData exception (reason = API_NotSupportedFeature) if user tries to mix
990 * insertion/extraction method (<< or >>) with operator[]
992 * @param [in] fl The exception flag
994 void exceptions(bitset<DevicePipeBlob::numFlags> fl) {the_root_blob.exceptions(fl);}
996 * Get exception flag
998 * Returns the whole exception flags.
999 * The following is an example of how to use these exceptions related methods
1000 * @code
1001 * DevicePipe dp;
1003 * bitset<DevicePipeBlob::numFlags> bs = dp.exceptions();
1004 * cout << "bs = " << bs << endl;
1006 * dp.set_exceptions(DevicePipeBlob::wrongtype_flag);
1007 * bs = dp.exceptions();
1009 * cout << "bs = " << bs << endl;
1010 * @endcode
1012 * @return The exception flag
1014 bitset<DevicePipeBlob::numFlags> exceptions() {return the_root_blob.exceptions();}
1016 * Reset one exception flag
1018 * Resets one exception flag
1020 * @param [in] fl The exception flag
1022 void reset_exceptions(DevicePipeBlob::except_flags fl) {the_root_blob.reset_exceptions(fl);}
1024 * Set one exception flag
1026 * Sets one exception flag. See DevicePipe::exceptions() for a usage example.
1028 * @param [in] fl The exception flag
1030 void set_exceptions(DevicePipeBlob::except_flags fl) {the_root_blob.set_exceptions(fl);}
1032 * Check insertion/extraction success
1034 * Allow the user to check if insertion/extraction into/from DevicePipe instance was successfull. This
1035 * method has to be used when exceptions are disabled.
1037 * @return True if insertion/extraction has failed
1039 bool has_failed() {return the_root_blob.has_failed();}
1041 * Get instance insertion/extraction state
1043 * Allow the user to find out what was the reason of insertion/extraction into/from DevicePipe failure. This
1044 * method has to be used when exceptions are disabled.
1045 * Here is an example of how methods has_failed() and state() could be used
1046 * @code
1047 * DevicePipe dpb = ....
1049 * bitset<DevicePipeBlob::numFlags> bs;
1050 * bs.reset();
1051 * dpb.exceptions(bs);
1053 * DevLong dl;
1054 * dpb >> dl;
1056 * if (dpb.has_failed() == true)
1058 * bitset<DevicePipeBlob::numFlags> bs_err = dpb.state();
1059 * if (dpb.test(DevicePipeBlob::isempty_flag) == true)
1060 * .....
1062 * @endcode
1064 * @return The error bit set.
1066 bitset<DevicePipeBlob::numFlags> state() {return the_root_blob.state();}
1067 //@}
1070 * Print a DevicePipe instance
1072 * Is an utility function to easily print the contents of a DevicePipe object. This function knows all types
1073 * which could be inserted in a DevicePipe object and print them accordingly. A special string is printed if
1074 * the DevicePipe object is empty
1075 * @code
1076 * DeviceProxy *dev = new DeviceProxy(“...”);
1077 * DevicePipe out;
1079 * out = dev->read_pipe(“MyPipe”);
1080 * cout << “Pipe content: ” << out << endl;
1081 * @endcode
1083 * @param [in] str The printing stream
1084 * @param [in] dd The instance to be printed
1086 friend ostream &operator<<(ostream &str,DevicePipe &dd);
1088 public :
1089 ///@privatesection
1090 DevicePipe(const DevicePipe &);
1091 DevicePipe & operator=(const DevicePipe &);
1092 #ifdef HAS_RVALUE
1093 DevicePipe(DevicePipe &&);
1094 DevicePipe & operator=(DevicePipe &&);
1095 #endif
1096 ~DevicePipe();
1098 void set_time(TimeVal &_ti) {time=_ti;}
1099 DevicePipeBlob &get_root_blob() {return the_root_blob;}
1101 DevicePipe &operator[](const string &);
1103 private:
1104 DevicePipeBlob the_root_blob; // Root blob
1105 string name; // Pipe name
1106 TimeVal time; // When pipe has been read
1108 class DevicePipeExt
1110 public:
1111 DevicePipeExt() {};
1114 #ifdef HAS_UNIQUE_PTR
1115 unique_ptr<DevicePipeExt> ext;
1116 #else
1117 DevicePipeExt *ext; // Class extension
1118 #endif
1121 /****************************************************************************************
1123 * Some DevicePipe, DevicePipeBlob and DataElement helper functions *
1124 * ---------------------------------------------------------------- *
1126 ***************************************************************************************/
1128 DevicePipe &operator>>(DevicePipe &_dp,char *&datum);
1131 // For DataElement printing
1134 template <typename T>
1135 ostream &operator<<(ostream &,DataElement<T> &);
1137 template <typename T>
1138 ostream &operator<<(ostream &,DataElement<vector<T> > &);
1140 template <typename T>
1141 ostream &operator<<(ostream &,DataElement<T *> &);
1144 // For DevicePipe insertion
1147 template <typename T>
1148 DevicePipe &operator<<(DevicePipe &,T &);
1150 template <typename T>
1151 DevicePipe &operator<<(DevicePipe &,T *);
1153 template <typename T>
1154 DevicePipe &operator<<(DevicePipe &, DataElement<T> &);
1157 // For DevicePipe extraction
1160 template <typename T>
1161 DevicePipe &operator>>(DevicePipe &,T &);
1163 template <typename T>
1164 DevicePipe &operator>>(DevicePipe &,T *);
1166 template <typename T>
1167 DevicePipe &operator>>(DevicePipe &, DataElement<T> &);
1170 // For DevicePipeBlob insertion
1173 template <typename T>
1174 DevicePipeBlob &operator<<(DevicePipeBlob &,T &);
1176 template <typename T>
1177 DevicePipeBlob &operator<<(DevicePipeBlob &,T *);
1179 template <typename T>
1180 DevicePipeBlob &operator<<(DevicePipeBlob &,DataElement<T> &);
1183 // For DevicePipeBlob extraction
1186 template <typename T>
1187 DevicePipeBlob &operator>>(DevicePipeBlob &,T &);
1189 template <typename T>
1190 DevicePipeBlob &operator>>(DevicePipeBlob &,T *);
1192 template <typename T>
1193 DevicePipeBlob &operator>>(DevicePipeBlob &, DataElement<T> &);
1197 /****************************************************************************************
1199 * Some macros (shame on me, but I am too lazy) *
1200 * ------------------------------------------- *
1202 ***************************************************************************************/
1205 // A is the required value for the IDL enum descriminator
1206 // B is the IDL enum method to get data
1207 // C is data type name
1210 #define EXTRACT_BASIC_TYPE(A,B,C) \
1211 failed = false; \
1212 ext_state.reset(); \
1214 if (extract_elt_array == Tango_nullptr) \
1215 ext_state.set(isempty_flag); \
1216 else if (extract_ctr > (int)extract_elt_array->length() - 1) \
1217 ext_state.set(notenoughde_flag); \
1218 else if (extract_ctr == -1 && extract_ind == -1) \
1219 ext_state.set(mixing_flag); \
1220 else \
1222 int ind; \
1223 if (extract_ind != -1) \
1224 ind = extract_ind; \
1225 else \
1226 ind = extract_ctr; \
1227 const AttrValUnion *uni_ptr = &((*extract_elt_array)[ind].value); \
1228 AttributeDataType adt = uni_ptr->_d(); \
1229 if (adt != A) \
1231 if (adt == ATT_NO_DATA) \
1233 if ((*extract_elt_array)[ind].inner_blob.length() == 0) \
1234 ext_state.set(isempty_flag); \
1235 else \
1236 ext_state.set(wrongtype_flag); \
1238 else \
1239 ext_state.set(wrongtype_flag); \
1241 else \
1243 datum = (uni_ptr->B())[0]; \
1244 if (extract_ind != -1) \
1245 extract_ind = -1; \
1246 else \
1247 extract_ctr++; \
1251 if (ext_state.any() == true) \
1252 failed = true; \
1254 if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) \
1255 throw_is_empty("operator>>"); \
1257 if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \
1258 throw_too_many("operator>>",true); \
1260 if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \
1261 throw_mixing("operator>>"); \
1263 if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) \
1264 throw_type_except(C,"operator>>");
1268 // A is the required value for the IDL enum descriminator
1269 // B is the IDL enum method to get data
1270 // C is the CORBA sequence type name
1271 // D is data type name
1274 #define EXTRACT_VECTOR_TYPE(A,B,C,D) \
1275 failed = false; \
1276 ext_state.reset(); \
1278 if (extract_elt_array == Tango_nullptr) \
1279 ext_state.set(isempty_flag); \
1280 else if (extract_ctr > (int)extract_elt_array->length() - 1) \
1281 ext_state.set(notenoughde_flag); \
1282 else if (extract_ctr == -1 && extract_ind == -1) \
1283 ext_state.set(mixing_flag); \
1284 else \
1286 int ind; \
1287 if (extract_ind != -1) \
1288 ind = extract_ind; \
1289 else \
1290 ind = extract_ctr; \
1291 const AttrValUnion *uni_ptr = &((*extract_elt_array)[ind].value); \
1292 AttributeDataType adt = uni_ptr->_d(); \
1293 if (adt != A) \
1295 if (adt == ATT_NO_DATA) \
1297 if ((*extract_elt_array)[ind].inner_blob.length() == 0) \
1298 ext_state.set(isempty_flag); \
1299 else \
1300 ext_state.set(wrongtype_flag); \
1302 else \
1303 ext_state.set(wrongtype_flag); \
1305 else \
1307 const C &dvsa = uni_ptr->B(); \
1308 datum << dvsa; \
1309 if (extract_ind != -1) \
1310 extract_ind = -1; \
1311 else \
1312 extract_ctr++; \
1316 if (ext_state.any() == true) \
1317 failed = true; \
1319 if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) \
1320 throw_is_empty("operator>>"); \
1322 if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \
1323 throw_too_many("operator>>",true); \
1325 if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \
1326 throw_mixing("operator>>"); \
1328 if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) \
1329 throw_type_except(D,"operator>>");
1332 // A is the required value for the IDL enum descriminator
1333 // B is the IDL enum method to get data
1334 // C is the CORBA sequence type name
1335 // D is data type name
1338 #define EXTRACT_SEQ_PTR_TYPE(A,B,C,D) \
1339 failed = false; \
1340 ext_state.reset(); \
1342 if (extract_elt_array == Tango_nullptr) \
1343 ext_state.set(isempty_flag); \
1344 else if (extract_ctr > (int)extract_elt_array->length() - 1) \
1345 ext_state.set(notenoughde_flag); \
1346 else if (extract_ctr == -1 && extract_ind == -1) \
1347 ext_state.set(mixing_flag); \
1348 else \
1350 int ind; \
1351 if (extract_ind != -1) \
1352 ind = extract_ind; \
1353 else \
1354 ind = extract_ctr; \
1355 const AttrValUnion *uni_ptr = &((*extract_elt_array)[ind].value); \
1356 AttributeDataType adt = uni_ptr->_d(); \
1357 if (adt != A) \
1359 if (adt == ATT_NO_DATA) \
1361 if ((*extract_elt_array)[ind].inner_blob.length() == 0) \
1362 ext_state.set(isempty_flag); \
1363 else \
1364 ext_state.set(wrongtype_flag); \
1366 else \
1367 ext_state.set(wrongtype_flag); \
1369 else \
1371 C &dvsa = const_cast<C &>(uni_ptr->B()); \
1372 CORBA::Long max,len; \
1373 max = dvsa.maximum(); \
1374 len = dvsa.length(); \
1375 datum->replace(max,len,dvsa.get_buffer((CORBA::Boolean)true),true); \
1376 if (extract_ind != -1) \
1377 extract_ind = -1; \
1378 else \
1379 extract_ctr++; \
1383 if (ext_state.any() == true) \
1384 failed = true; \
1386 if (ext_state.test(isempty_flag) == true && exceptions_flags.test(isempty_flag) == true) \
1387 throw_is_empty("operator>>"); \
1389 if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \
1390 throw_too_many("operator>>",true); \
1392 if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \
1393 throw_mixing("operator>>"); \
1395 if (ext_state.test(wrongtype_flag) == true && exceptions_flags.test(wrongtype_flag) == true) \
1396 throw_type_except(D,"operator>>");
1400 // A is the sequence CORBA name
1401 // B is the IDL enum method to set data
1404 #define INSERT_BASIC_TYPE(A,B) \
1405 failed = false; \
1406 ext_state.reset(); \
1408 if (insert_elt_array == Tango_nullptr) \
1409 ext_state.set(blobdenamenotset_flag); \
1410 else if (insert_ctr == -1 && insert_ind == -1) \
1411 ext_state.set(mixing_flag); \
1412 else \
1414 size_t nb_insert = insert_elt_array->length(); \
1415 if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \
1416 ext_state.set(notenoughde_flag); \
1417 else \
1419 A dvsa; \
1420 dvsa.length(1); \
1421 dvsa[0] = datum; \
1423 if (insert_ind != -1) \
1425 (*insert_elt_array)[insert_ind].value.B(dvsa); \
1426 (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(SCALAR_PIPE); \
1427 insert_ind = -1; \
1429 else \
1431 (*insert_elt_array)[insert_ctr].value.B(dvsa); \
1432 (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(SCALAR_PIPE); \
1433 insert_ctr++; \
1438 if (ext_state.any() == true) \
1439 failed = true; \
1441 if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \
1442 throw_name_not_set("operator<<"); \
1444 if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \
1445 throw_mixing("operator>>"); \
1447 if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \
1448 throw_too_many("operator<<",false);
1452 // A is the sequence CORBA name
1453 // B is the IDL enum method to set data
1456 #define INSERT_VECTOR_TYPE(A,B) \
1457 failed = false; \
1458 ext_state.reset(); \
1460 if (insert_elt_array == Tango_nullptr) \
1461 ext_state.set(blobdenamenotset_flag); \
1462 else if (insert_ctr == -1 && insert_ind == -1) \
1463 ext_state.set(mixing_flag); \
1464 else \
1466 size_t nb_insert = insert_elt_array->length(); \
1467 if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \
1468 ext_state.set(notenoughde_flag); \
1469 else \
1471 A dvsa; \
1472 if (insert_ind != -1) \
1474 (*insert_elt_array)[insert_ind].value.B(dvsa); \
1475 A &dvsb = (*insert_elt_array)[insert_ind].value.B(); \
1476 dvsb.replace(datum.size(),datum.size(),&datum[0],false); \
1477 (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \
1478 insert_ind = -1; \
1480 else \
1482 (*insert_elt_array)[insert_ctr].value.B(dvsa); \
1483 A &dvsb = (*insert_elt_array)[insert_ctr].value.B(); \
1484 dvsb.replace(datum.size(),datum.size(),&datum[0],false); \
1485 (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \
1486 insert_ctr++; \
1491 if (ext_state.any() == true) \
1492 failed = true; \
1494 if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \
1495 throw_name_not_set("operator<<"); \
1497 if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \
1498 throw_mixing("operator>>"); \
1500 if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \
1501 throw_too_many("operator<<",false);
1506 // A is the sequence CORBA name
1507 // B is the IDL enum method to set data
1510 #define INSERT_SEQ_TYPE(A,B) \
1511 failed = false; \
1512 ext_state.reset(); \
1514 if (insert_elt_array == Tango_nullptr) \
1515 ext_state.set(blobdenamenotset_flag); \
1516 else if (insert_ctr == -1 && insert_ind == -1) \
1517 ext_state.set(mixing_flag); \
1518 else \
1520 size_t nb_insert = insert_elt_array->length(); \
1521 if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \
1522 ext_state.set(notenoughde_flag); \
1523 else \
1525 CORBA::Long max,len; \
1526 max = datum.maximum(); \
1527 len = datum.length(); \
1528 A dvsa; \
1529 if (insert_ind != -1) \
1531 (*insert_elt_array)[insert_ind].value.B(dvsa); \
1532 A &dvsb = (*insert_elt_array)[insert_ind].value.B(); \
1533 dvsb.replace(max,len,datum.get_buffer(),false); \
1534 (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \
1535 insert_ind = -1; \
1537 else \
1539 (*insert_elt_array)[insert_ctr].value.B(dvsa); \
1540 A &dvsb = (*insert_elt_array)[insert_ctr].value.B(); \
1541 dvsb.replace(max,len,datum.get_buffer(),false); \
1542 (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \
1543 insert_ctr++; \
1548 if (ext_state.any() == true) \
1549 failed = true; \
1551 if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \
1552 throw_name_not_set("operator<<"); \
1554 if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \
1555 throw_mixing("operator>>"); \
1557 if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \
1558 throw_too_many("operator<<",false);
1563 // A is the sequence CORBA name
1564 // B is the IDL enum method to set data
1567 #define INSERT_SEQ_PTR_TYPE(A,B) \
1568 failed = false; \
1569 ext_state.reset(); \
1571 if (insert_elt_array == Tango_nullptr) \
1572 ext_state.set(blobdenamenotset_flag); \
1573 else if (insert_ctr == -1 && insert_ind == -1) \
1574 ext_state.set(mixing_flag); \
1575 else \
1577 size_t nb_insert = insert_elt_array->length(); \
1578 if (nb_insert == 0 || insert_ctr > (int)nb_insert - 1) \
1579 ext_state.set(notenoughde_flag); \
1580 else \
1582 A dvsa; \
1583 CORBA::Long max,len; \
1584 max = datum->maximum(); \
1585 len = datum->length(); \
1586 bool rel = datum->release(); \
1587 if (rel == false) \
1589 datum->replace(max,len,datum->get_buffer(),true); \
1591 if (insert_ind != -1) \
1593 (*insert_elt_array)[insert_ind].value.B(dvsa); \
1594 A &dvsb = (*insert_elt_array)[insert_ind].value.B(); \
1595 dvsb.replace(max,len,datum->get_buffer((CORBA::Boolean)true),true); \
1596 (*insert_elt_array)[insert_ind].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \
1597 insert_ind = -1; \
1599 else \
1601 (*insert_elt_array)[insert_ctr].value.B(dvsa); \
1602 A &dvsb = (*insert_elt_array)[insert_ctr].value.B(); \
1603 dvsb.replace(max,len,datum->get_buffer((CORBA::Boolean)true),true); \
1604 (*insert_elt_array)[insert_ctr].inner_blob_name = CORBA::string_dup(ARRAY_PIPE); \
1605 insert_ctr++; \
1608 delete datum; \
1612 if (ext_state.any() == true) \
1613 failed = true; \
1615 if (ext_state.test(blobdenamenotset_flag) == true && exceptions_flags.test(blobdenamenotset_flag) == true) \
1616 throw_name_not_set("operator<<"); \
1618 if (ext_state.test(mixing_flag) == true && exceptions_flags.test(mixing_flag) == true) \
1619 throw_mixing("operator>>"); \
1621 if (ext_state.test(notenoughde_flag) == true && exceptions_flags.test(notenoughde_flag) == true) \
1622 throw_too_many("operator<<",false);
1625 #endif /* _DEVICEPIPE_H */