Range_Checking_T.h

Go to the documentation of this file.
00001 #ifndef guard_range_checking_hpp
00002 #define guard_range_checking_hpp
00003 /**
00004  * @file
00005  *
00006  * @brief Details can be found in the documentation for
00007  * TAO::details::generic_sequence
00008  *
00009  * Range_Checking_T.h,v 1.3 2006/04/20 12:40:09 jwillemsen Exp
00010  *
00011  * @author Carlos O'Ryan
00012  */
00013 
00014 #include "tao/Basic_Types.h"
00015 
00016 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00017 
00018 namespace TAO
00019 {
00020 namespace details
00021 {
00022 
00023 /**
00024  * @struct range_checking
00025  *
00026  * @brief Configurable traits to tradeoff safety vs. performance in
00027  *        the implementation of TAO sequences.
00028  *
00029  * The CORBA specification grants certain latitude to implementors by
00030  * not defining the behavior of sequences under certain conditions.
00031  * Probably the most clear example is the operator[] access, where the
00032  * application <b>must</b> set the length to a high enough value
00033  * before using the operator[].
00034  *
00035  * Implementors that cater to high-performance applications tend to
00036  * exploit this latitude to the extreme, basically reasoning that
00037  * correct applications will behave normally, while incorrect
00038  * applications will crash, but those crashes will be detected during
00039  * development/testing.
00040  *
00041  * Realizing that this may be a bad tradeoff some implementors offer
00042  * compile-time hooks to control the behavior of sequences when used
00043  * improperly, some implementors may go as far as using run-time
00044  * hooks.
00045  *
00046  * The implementation of sequences calls the following template class
00047  * in points where the application may trigger undefined behavior.
00048  * The application developer can use partial (or full) template
00049  * specialization to introduce her own code at these critical points.
00050  *
00051  * Some examples may help, suppose you want to change your application
00052  * so for all sequence types the operator[] raises an exception if the
00053  * index is out of range.  Then you would provide the following
00054  * (partial) template specialization:
00055  *
00056  * <PRE>
00057  * template<typename T>
00058  * struct range_checking<T,true> {
00059  *   void check(CORBA::ULong index, CORBA::ULong length) {
00060  *     if (index < length)
00061  *       return;
00062  *     throw std::range_error("CORBA sequence range error");
00063  *   };
00064  * ...
00065  * ..
00066  * };
00067  * </PRE>
00068  *
00069  * This specialization must be introduced before any sequence code is
00070  * seen, therefore, the application would also need to define the
00071  * following macro in their $ACE_ROOT/ace/config.h file:
00072  *
00073  * - #define TAO_USER_DEFINED_SEQUENCE_SAFETY_TRAITS_INCLUDE "<filename here>"
00074  *
00075  * Likewise, if the application only wanted to check the range for a
00076  * special type, say some structure MyStruct, then they would provide
00077  * a full specialization.  Just for giggles, we will also introduce
00078  * run-time controls to this example:
00079  *
00080  * <PRE>
00081  * template<>
00082  * struct safety_traits<tao::details::value_traits<MyStruct>,true> {
00083  *   bool enable_range_checking;
00084  *   void check_range(CORBA::ULong index, CORBA::ULong length) {
00085  *     if (!enable_range_checking || index < length)
00086  *       return;
00087  *     throw std::range_error("CORBA sequence range error");
00088  *   };
00089  * ...
00090  * ..
00091  * };
00092  * </PRE>
00093  *
00094  *
00095  *
00096  * @todo There is no control on a per-sequence type basis, only on a
00097  *       per-underlying type basis, for example, the following two IDL
00098  *       sequences would get the same behavior:
00099  *       // IDL
00100  *       typedef sequence<MyStruct> MyStructSequence;
00101  *       typedef sequence<MyStruct> MyStructList;
00102  *
00103  * @todo There is no way to control behavior on a per-sequence basis,
00104  *       i.e. to have some sequences of longs checked while others are
00105  *       not.  This is easy to fix, simply:
00106  *       - make all members of safety_traits non-static
00107  *       - have each sequence contain their own instance of
00108  *         safety_traits
00109  *       - grant users read/write access to the safety_traits of each
00110  *         sequence
00111  *       but there are footprint consequences to that approach.  Until
00112  *       there is more demand to justify the cost, I will not
00113  *       implement such a change.
00114  */
00115 template<typename T, bool dummy>
00116 struct range_checking
00117 {
00118   typedef T value_type;
00119 
00120   inline static void check(
00121       CORBA::ULong /* index */,
00122       CORBA::ULong /* length */,
00123       CORBA::ULong /* maximum */,
00124       char const * /* function_name */)
00125   {
00126     // Applications and tests can specialize this function to define
00127     // their own behavior
00128   }
00129 
00130   inline static void check_length(
00131       CORBA::ULong & /* new_length */,
00132       CORBA::ULong /* maximum */)
00133   {
00134     /*
00135     if (maximum < new_length)
00136       new_length = maximum;
00137     */
00138   }
00139 };
00140 
00141 } // namespace details
00142 } // namespace TAO
00143 
00144 TAO_END_VERSIONED_NAMESPACE_DECL
00145 
00146 #if defined(TAO_USER_DEFINED_SEQUENCE_RANGE_CHECKING_INCLUDE)
00147 #  include TAO_USER_DEFINED_SEQUENCE_RANGE_CHECKING_INCLUDE
00148 #endif // TAO_USER_DEFINED_SEQUENCE_RANGE_CHECKING_INCLUDE
00149 
00150 #endif // guard_range_checking_hpp

Generated on Thu Nov 9 11:54:21 2006 for TAO by doxygen 1.3.6