// balber_beruniversaltagnumber.h -*-C++-*- // ---------------------------------------------------------------------------- // NOTICE // // This component is not up to date with current BDE coding standards, and // should not be used as an example for new development. // ---------------------------------------------------------------------------- #ifndef INCLUDED_BALBER_BERUNIVERSALTAGNUMBER #define INCLUDED_BALBER_BERUNIVERSALTAGNUMBER #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Enumerate the set of BER universal tag numbers. // //@CLASSES: // balber::BerUniversalTagNumber: namespace universal tag number enumeration // //@SEE_ALSO: balber_berencoder, balber_berdecoder // http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf // //@DESCRIPTION: This component provides a namespace for the 'enum' type // 'balber::BerUniversalTagNumber::Value'. 'Value' enumerates the set of BER // universal tag numbers used by the BER encoder and decoder. The universal // tag numbers are defined in the X.680 standard, in section 8. // // In addition, this component supports functions that convert the 'Value' // enumerations to a well-defined ASCII representation. // // This component also provides a function that returns the universal tag // number for an object with formatting mode, according to the following table: //.. // C++ Type Formatting Mode Universal Tag Number // -------- --------------- -------------------- // bool DEFAULT e_BER_BOOL // DEC e_BER_BOOL // TEXT e_BER_BOOL // char DEFAULT e_BER_INT // DEC e_BER_INT // TEXT e_BER_UTF8_STRING // unsigned char DEFAULT e_BER_INT // DEC e_BER_INT // [unsigned] short DEFAULT e_BER_INT // DEC e_BER_INT // [unsigned] int DEFAULT e_BER_INT // DEC e_BER_INT // [unsigned] long DEFAULT e_BER_INT // DEC e_BER_INT // bsls::Types::[Uint64|Int64] DEFAULT e_BER_INT // DEC e_BER_INT // float DEFAULT e_BER_REAL // double DEFAULT e_BER_REAL // bdldfp::Decimal64 DEFAULT e_BER_OCTET_STRING // bsl::string DEFAULT e_BER_UTF8_STRING // TEXT e_BER_UTF8_STRING // BASE64 e_BER_OCTET_STRING // HEX e_BER_OCTET_STRING // bdlt::Date DEFAULT e_BER_VISIBLE_STRING // bdlt::DateTz DEFAULT e_BER_VISIBLE_STRING // bdlt::Datetime DEFAULT e_BER_VISIBLE_STRING // bdlt::DateTimeTz DEFAULT e_BER_VISIBLE_STRING // bdlt::Time DEFAULT e_BER_VISIBLE_STRING // bdlt::TimeTz DEFAULT e_BER_VISIBLE_STRING // bsl::vector<char> DEFAULT e_BER_OCTET_STRING // BASE64 e_BER_OCTET_STRING // HEX e_BER_OCTET_STRING // TEXT e_BER_UTF8_STRING //.. // If the object is not one of these types, then the universal tag number is // selected based on the object's type category, as follows: //.. // Category Universal Tag Number // -------- -------------------- // CustomizedType Use universal tag number of the base type. // Enumeration 'e_BER_ENUMERATION' when formatting mode is either // 'DEFAULT', 'DEC', or 'TEXT'. // Sequence 'e_BER_SEQUENCE' when formatting mode is 'DEFAULT'. // Choice 'e_BER_SEQUENCE' when formatting mode is 'DEFAULT'. // Array 'e_BER_SEQUENCE' when formatting mode is 'DEFAULT'. //.. // The behavior is undefined if the object does not fall into one the above // categories or formatting modes. // ///Usage ///----- // This section illustrates intended use of this component. // ///Exercise 1: Basic Syntax /// - - - - - - - - - - - - // The following snippets of code provide a simple illustration of // 'balber::BerUniversalTagNumber' operation. // // First, create a variable 'tagNumber' of type // 'balber::BerUniversalTagNumber::Value' and initialize it to the value // 'balber::BerUniversalTagNumber::e_BER_INT': //.. // balber::BerUniversalTagNumber::Value tagNumber // = balber::BerUniversalTagNumber::e_BER_INT; //.. // Next, store its representation in a variable 'rep' of type 'const char *': //.. // const char *rep = balber::BerUniversalTagNumber::toString(tagNumber); // assert(0 == strcmp(rep, "INT")); //.. // Finally, print the value of 'tagNumber' to 'bsl::cout': //.. // bsl::cout << tagNumber << bsl::endl; //.. // This statement produces the following output on 'bsl::cout': //.. // INT //.. #include <balscm_version.h> #include <balber_berencoderoptions.h> #include <bdlat_customizedtypefunctions.h> #include <bdlat_formattingmode.h> #include <bdlat_nullablevaluefunctions.h> #include <bdlat_typecategory.h> #include <bdldfp_decimal.h> #include <bdlb_variant.h> #include <bdlt_date.h> #include <bdlt_datetz.h> #include <bdlt_datetime.h> #include <bdlt_datetimetz.h> #include <bdlt_time.h> #include <bdlt_timetz.h> #include <bslmf_assert.h> #include <bslmf_issame.h> #include <bsls_assert.h> #include <bsls_types.h> #include <bsl_ostream.h> #include <bsl_string.h> #include <bsl_vector.h> namespace BloombergLP { namespace balber { // ============================ // struct BerUniversalTagNumber // ============================ struct BerUniversalTagNumber { // This 'struct' contains an enumeration of the universal tag numbers for // BER encoding. // TYPES enum Value { e_BER_INVALID = -1 // Universal tag numbers as per X.680 section 8 , e_BER_BOOL = 0x01 // ( 1) Boolean type , e_BER_INT = 0x02 // ( 2) Integer type , e_BER_OCTET_STRING = 0x04 // ( 4) Octet string type , e_BER_REAL = 0x09 // ( 9) Real type , e_BER_ENUMERATION = 0x0A // (10) Enumerated type , e_BER_UTF8_STRING = 0x0C // (12) UTF8 string type , e_BER_SEQUENCE = 0x10 // (16) Sequence and Sequence-of types , e_BER_VISIBLE_STRING = 0x1A // (26) VisibleString type (7-bit ASCII) #ifndef BDE_OMIT_INTERNAL_DEPRECATED , BDEM_BER_INVALID = e_BER_INVALID , BDEM_BER_BOOL = e_BER_BOOL , BDEM_BER_INT = e_BER_INT , BDEM_BER_OCTET_STRING = e_BER_OCTET_STRING , BDEM_BER_REAL = e_BER_REAL , BDEM_BER_ENUMERATION = e_BER_ENUMERATION , BDEM_BER_UTF8_STRING = e_BER_UTF8_STRING , BDEM_BER_SEQUENCE = e_BER_SEQUENCE , BDEM_BER_VISIBLE_STRING = e_BER_VISIBLE_STRING #endif // BDE_OMIT_INTERNAL_DEPRECATED }; // CONSTANTS enum { k_LENGTH = 8 // the number of enumerations in the 'Value' enumeration #ifndef BDE_OMIT_INTERNAL_DEPRECATED , BDEM_LENGTH = k_LENGTH , NUM_ENUMERATORS = k_LENGTH #endif // BDE_OMIT_INTERNAL_DEPRECATED }; // CLASS METHODS static const char *toString(Value value); // Return the string representation exactly matching the enumerator // name corresponding to the specified enumeration 'value'. static int fromString(Value *result, const char *string, int stringLength); // Load into the specified 'result' the enumerator matching the // specified 'string' of the specified 'stringLength'. Return 0 on // success, and a non-zero value with no effect on 'result' otherwise // (i.e., 'string' does not match any enumerator). static int fromInt(Value *result, int number); // Load into the specified 'result' the enumerator matching the // specified 'number'. Return 0 on success, and a non-zero value with // no effect on 'result' otherwise (i.e., 'number' does not match any // enumerator). static bsl::ostream& print(bsl::ostream& stream, Value value); // Write to the specified 'stream' the string representation of the // specified enumeration 'value'. Return a reference to the modifiable // 'stream'. template <typename TYPE> static Value select(const TYPE& object, int formattingMode, int *alternateTag); // Return the universal tag number for the specified 'object' using the // specified 'formattingMode', and load into the specified // 'alternateTag' any alternative tag numbers corresponding to // 'object'. The behavior is undefined if the type category of // 'object' and the 'formattingMode' does not permit a universal tag // number (see {DESCRIPTION} for allowed type categories and formatting // modes). Note that if an alternate tag number does not exist for // 'object' then 'alternateTag' is not modified. template <typename TYPE> static Value select(const TYPE& object, int formattingMode, const BerEncoderOptions *options); // Return the universal tag number for the specified 'object' with the // specified 'formattingMode' using the specified 'options'. The // behavior is undefined if the type category of 'object' and the // 'formattingMode' do not permit a universal tag number (see // {DESCRIPTION} for allowed type categories and formatting modes). }; // FREE OPERATORS inline bsl::ostream& operator<<(bsl::ostream& stream, BerUniversalTagNumber::Value rhs); // Format the specified 'rhs' to the specified output 'stream' and return a // reference providing modifiable access to 'stream'. // =============================== // class BerUniversalTagNumber_Sel // =============================== template <class TYPE, class CATEGORY> class BerUniversalTagNumber_Sel { // Component-private class. Do not use. This class contains // implementation details of this component. // ///Implementation Note ///------------------- // The suffix of this class, "Sel", is a contraction of "Selector", which // is meant to associate with the action of selecting a particular overload // from an overload set. // // This component uses specializations of this class to guide overload // resolution for functions that need to select between one of several // overloads based on the specified 'TYPE' and 'CATEGORY' information. // Note that 'CATEGORY' is expected to be one of the "category" types that // are members of 'bdlat_TypeCategory'. public: // CREATORS BerUniversalTagNumber_Sel() // Create a 'BerUniversalTagNumber_Sel' object. Note that objects of // this type are stateless. { } //! BerUniversalTagNumber_Sel( //! const BerUniversalTagNumber_Sel& original) = default; // Create a new 'BerUniversalTagNumber_Sel' object having a copy of the // value of the specified 'original' object. Note that objects of this // type are stateless and their value is a notional concept only. // MANIPULATORS //! BerUniversalTagNumber_Sel& operator=( //! const BerUniversalTagNumber_Sel& original) = default; // Assign the value of the specified 'original' object to this object. // Note that objects of this type are stateless and their value is a // notional concept only. }; // ================================ // struct BerUniversalTagNumber_Imp // ================================ class BerUniversalTagNumber_Imp { // Component-private class. Do not use. This class contains // implementation details for this component. // PRIVATE TYPES typedef bdlat_FormattingMode FMode; typedef BerUniversalTagNumber::Value TagVal; // These type definitions are shorthand used throughout the members of // this class. typedef bdlat_TypeCategory::Array ArrayCat; typedef bdlat_TypeCategory::Choice ChoiceCat; typedef bdlat_TypeCategory::CustomizedType CustomizedTypeCat; typedef bdlat_TypeCategory::DynamicType DynamicTypeCat; typedef bdlat_TypeCategory::Enumeration EnumerationCat; typedef bdlat_TypeCategory::NullableValue NullableValueCat; typedef bdlat_TypeCategory::Sequence SequenceCat; typedef bdlat_TypeCategory::Simple SimpleCat; // These type definitions are shorthand aliases for 'bdlat' category // types. The "Cat" suffix stands for "Category". The shorthand is // useful, essentially, for permitting rows in tables of function // overloads and dependent type definitions to fit on one line. Doing // so improves the legibility of this class immensely. typedef bsl::string String; typedef bsls::Types::Int64 Int64; typedef bsls::Types::Uint64 Uint64; typedef bdldfp::Decimal64 Decimal64; typedef bdlt::Date Date; typedef bdlt::DateTz DateTz; typedef bdlt::Datetime Datetime; typedef bdlt::DatetimeTz DatetimeTz; typedef bdlt::Time Time; typedef bdlt::TimeTz TimeTz; // Similar to the aliases for the 'bdlat' category types above, these // type definitions are shorthand aliases for object types in the // 'Simple' 'bdlat' type category, used to improve the legibility of // this class. typedef bsl::vector<char> CharVector; // 'CharVector' is the one such alias in the 'Array' 'bdlat' category, // not the 'Simple' category. typedef BerUniversalTagNumber_Sel<bool , SimpleCat> BoolSel; typedef BerUniversalTagNumber_Sel<char , SimpleCat> CharSel; typedef BerUniversalTagNumber_Sel<signed char , SimpleCat> ScharSel; typedef BerUniversalTagNumber_Sel<unsigned char , SimpleCat> UcharSel; typedef BerUniversalTagNumber_Sel<short , SimpleCat> ShortSel; typedef BerUniversalTagNumber_Sel<unsigned short, SimpleCat> UshortSel; typedef BerUniversalTagNumber_Sel<int , SimpleCat> IntSel; typedef BerUniversalTagNumber_Sel<unsigned int , SimpleCat> UintSel; typedef BerUniversalTagNumber_Sel<long , SimpleCat> LongSel; typedef BerUniversalTagNumber_Sel<unsigned long , SimpleCat> UlongSel; typedef BerUniversalTagNumber_Sel<Int64 , SimpleCat> Int64Sel; typedef BerUniversalTagNumber_Sel<Uint64 , SimpleCat> Uint64Sel; typedef BerUniversalTagNumber_Sel<float , SimpleCat> FloatSel; typedef BerUniversalTagNumber_Sel<double , SimpleCat> DoubleSel; typedef BerUniversalTagNumber_Sel<Decimal64 , SimpleCat> Decimal64Sel; typedef BerUniversalTagNumber_Sel<String , SimpleCat> StringSel; typedef BerUniversalTagNumber_Sel<Date , SimpleCat> DateSel; typedef BerUniversalTagNumber_Sel<DateTz , SimpleCat> DateTzSel; typedef BerUniversalTagNumber_Sel<Datetime , SimpleCat> DatetimeSel; typedef BerUniversalTagNumber_Sel<DatetimeTz , SimpleCat> DatetimeTzSel; typedef BerUniversalTagNumber_Sel<Time , SimpleCat> TimeSel; typedef BerUniversalTagNumber_Sel<TimeTz , SimpleCat> TimeTzSel; // These type definitions are shorthand aliases for types having the // 'bdlat' 'Simple' category, whose objects can be created and used as // arguments to 'select' in order to select a particular overload. // Note that these "tag" types denote both an underlying type and its // 'bdlat' category. typedef BerUniversalTagNumber_Sel<CharVector , ArrayCat > CharVectorSel; // 'CharVectorSel' is the one such alias that has a 'CATEGORY' that // denotes the 'bdlat' 'Array' category, not the 'Simple' category. // DATA int d_formattingMode; const BerEncoderOptions *d_options_p; // options (held, not owned) int d_alternateTag; // alternate tag // PRIVATE MANIPULATORS TagVal selectForDateAndTimeTypes(); // Return the universal tag number for date and time types and load // into the internal 'alternateTag' data member the any alternative tag // numbers corresponding to those types. public: BerUniversalTagNumber_Imp(int fm, const BerEncoderOptions *options = 0) : d_formattingMode(fm) , d_options_p(options) , d_alternateTag(-1) { } // ** By Type ** TagVal select(const BoolSel& selector); TagVal select(const CharSel& selector); TagVal select(const ScharSel& selector); TagVal select(const UcharSel& selector); TagVal select(const ShortSel& selector); TagVal select(const UshortSel& selector); TagVal select(const IntSel& selector); TagVal select(const UintSel& selector); TagVal select(const LongSel& selector); TagVal select(const UlongSel& selector); TagVal select(const Int64Sel& selector); TagVal select(const Uint64Sel& selector); TagVal select(const FloatSel& selector); TagVal select(const DoubleSel& selector); TagVal select(const Decimal64Sel& selector); TagVal select(const StringSel& selector); TagVal select(const DateSel& selector); TagVal select(const DateTzSel& selector); TagVal select(const DatetimeSel& selector); TagVal select(const DatetimeTzSel& selector); TagVal select(const TimeSel& selector); TagVal select(const TimeTzSel& selector); template <typename TYPE, typename TYPETZ> TagVal select( const BerUniversalTagNumber_Sel<bdlb::Variant2<TYPE, TYPETZ>, SimpleCat>& selector); TagVal select(const CharVectorSel& selector); // Return the universal tag number for an object having the 'TYPE' and // 'bdlat' 'CATEGORY' of the type of the specified 'selector', and load // into the 'alternateTag' attribute of this object any alternate tag // numbers corresponding to 'TYPE' and 'CATEGORY'. Note that if an // alternate tag number for the 'TYPE' and 'CATEGORY' does not exist, // then the 'alternateTag' attribute of this object is not modified. // ** By Category ** template <typename TYPE> TagVal select( const BerUniversalTagNumber_Sel<TYPE, ArrayCat >& selector); template <typename TYPE> TagVal select( const BerUniversalTagNumber_Sel<TYPE, ChoiceCat >& selector); template <typename TYPE> TagVal select( const BerUniversalTagNumber_Sel<TYPE, CustomizedTypeCat>& selector); template <typename TYPE> TagVal select( const BerUniversalTagNumber_Sel<TYPE, DynamicTypeCat >& selector); template <typename TYPE> TagVal select( const BerUniversalTagNumber_Sel<TYPE, EnumerationCat >& selector); template <typename TYPE> TagVal select( const BerUniversalTagNumber_Sel<TYPE, NullableValueCat >& selector); template <typename TYPE> TagVal select( const BerUniversalTagNumber_Sel<TYPE, SequenceCat >& selector); template <typename TYPE, typename ANY_CATEGORY> TagVal select( const BerUniversalTagNumber_Sel<TYPE, ANY_CATEGORY >& selector); // Return the universal tag number for an object having the 'TYPE' and // 'bdlat' 'CATEGORY' of the type of the specified 'selector', and load // into the 'alternateTag' attribute of this object any alternate tag // numbers corresponding to 'TYPE' and 'CATEGORY'. Note that if an // alternate tag number for the 'TYPE' and 'CATEGORY' does not exist, // then the 'alternateTag' attribute of this object is not modified. // FUNCTOR OPERATORS template <typename TYPE> inline TagVal operator()(const TYPE&, bslmf::Nil) { BSLS_ASSERT(0 && "Invalid type category"); return BerUniversalTagNumber::e_BER_INVALID; } template <typename TYPE, typename ANY_CATEGORY> inline TagVal operator()(const TYPE&, ANY_CATEGORY) { typedef BerUniversalTagNumber_Sel<TYPE, ANY_CATEGORY> Selector; return BerUniversalTagNumber_Imp::select(Selector()); } int alternateTag() { return d_alternateTag; } }; } // close package namespace // ============================================================================ // INLINE FUNCTION DEFINITIONS // ============================================================================ // ------------------------------------ // struct balber::BerUniversalTagNumber // ------------------------------------ namespace balber { // CLASS METHODS inline int BerUniversalTagNumber::fromInt(BerUniversalTagNumber::Value *result, int number) { enum { k_SUCCESS = 0, k_NOT_FOUND = 1 }; switch (number) { case e_BER_BOOL: case e_BER_INT: case e_BER_OCTET_STRING: case e_BER_REAL: case e_BER_ENUMERATION: case e_BER_UTF8_STRING: case e_BER_SEQUENCE: case e_BER_VISIBLE_STRING: *result = static_cast<BerUniversalTagNumber::Value>(number); return k_SUCCESS; // RETURN default: return k_NOT_FOUND; // RETURN } } inline bsl::ostream& BerUniversalTagNumber::print(bsl::ostream& stream, BerUniversalTagNumber::Value value) { return stream << toString(value); } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber::select(const TYPE& object, int formattingMode, const BerEncoderOptions *options) { BerUniversalTagNumber_Imp imp(formattingMode, options); int retVal = bdlat_TypeCategoryUtil::accessByCategory(object, imp); return (BerUniversalTagNumber::Value) retVal; } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber::select(const TYPE& object, int formattingMode, int *alternateTag) { BerUniversalTagNumber_Imp imp(formattingMode); int retVal = bdlat_TypeCategoryUtil::accessByCategory(object, imp); const int tag = imp.alternateTag(); if (-1 != tag) { *alternateTag = tag; } return (BerUniversalTagNumber::Value) retVal; } } // close package namespace // FREE OPERATORS inline bsl::ostream& balber::operator<<(bsl::ostream& stream, BerUniversalTagNumber::Value rhs) { return BerUniversalTagNumber::print(stream, rhs); } namespace balber { // -------------------------------- // struct BerUniversalTagNumber_Imp // -------------------------------- // PRIVATE MANIPULATORS inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::selectForDateAndTimeTypes() { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK)); if (d_options_p) { return d_options_p->encodeDateAndTimeTypesAsBinary() ? BerUniversalTagNumber::e_BER_OCTET_STRING : BerUniversalTagNumber::e_BER_VISIBLE_STRING; } else { d_alternateTag = BerUniversalTagNumber::e_BER_OCTET_STRING; return BerUniversalTagNumber::e_BER_VISIBLE_STRING; } } // ** By Type ** inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const BoolSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_TEXT == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_BOOL; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const CharSel&) { if (FMode::e_TEXT == (d_formattingMode & FMode::e_TYPE_MASK)) { return BerUniversalTagNumber::e_BER_UTF8_STRING; } BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const ScharSel&) { if (FMode::e_TEXT == (d_formattingMode & FMode::e_TYPE_MASK)) { return BerUniversalTagNumber::e_BER_UTF8_STRING; } BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const UcharSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const ShortSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const UshortSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const IntSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const UintSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const LongSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const UlongSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const Int64Sel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const Uint64Sel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_INT; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const FloatSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_REAL; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const DoubleSel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_REAL; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const Decimal64Sel&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_OCTET_STRING; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const StringSel&) { if (FMode::e_BASE64 == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_HEX == (d_formattingMode & FMode::e_TYPE_MASK)) { return BerUniversalTagNumber::e_BER_OCTET_STRING; } BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_TEXT == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_UTF8_STRING; } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const DateSel&) { return selectForDateAndTimeTypes(); } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const DateTzSel&) { return selectForDateAndTimeTypes(); } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const DatetimeSel&) { return selectForDateAndTimeTypes(); } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const DatetimeTzSel&) { return selectForDateAndTimeTypes(); } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const TimeSel&) { return selectForDateAndTimeTypes(); } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const TimeTzSel&) { return selectForDateAndTimeTypes(); } template <typename TYPE, typename TYPETZ> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<bdlb::Variant2<TYPE, TYPETZ>, SimpleCat>&) { BSLMF_ASSERT((bslmf::IsSame<bdlt::Date, TYPE >::VALUE && bslmf::IsSame<bdlt::DateTz, TYPETZ>::VALUE) || (bslmf::IsSame<bdlt::Time, TYPE >::VALUE && bslmf::IsSame<bdlt::TimeTz, TYPETZ>::VALUE) || (bslmf::IsSame<bdlt::Datetime, TYPE >::VALUE && bslmf::IsSame<bdlt::DatetimeTz, TYPETZ>::VALUE)); return selectForDateAndTimeTypes(); } inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select(const CharVectorSel&) { if (FMode::e_TEXT == (d_formattingMode & FMode::e_TYPE_MASK)) { return BerUniversalTagNumber::e_BER_UTF8_STRING; } BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_BASE64 == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_HEX == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_OCTET_STRING; } // ** By Category ** template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, CustomizedTypeCat>&) ///Implementation Note ///------------------- // The BER universal tag number of the specified customized type 'TYPE' is // defined to be the BER universal tag number of the base type of 'TYPE'. { typedef typename bdlat_CustomizedTypeFunctions::BaseType<TYPE>::Type BaseType; // To compute the universal tag number of the specified 'TYPE', first // compute the 'BaseType' of 'TYPE'. typedef typename bdlat_TypeCategory::Select<BaseType>::Type BaseTypeCategory; // Then, determine the 'bdlat' type category of the 'BaseType', // 'BaseTypeCategory'. typedef BerUniversalTagNumber_Sel<BaseType, BaseTypeCategory> BaseTypeSelector; // Next, construct a 'BerUniversalTagNumber_Sel' type specialized with // the computed 'BaseType' and 'BaseTypeCategory'. return this->select(BaseTypeSelector()); // Finally, return the result of computing the universal tag number of // the base type of 'TYPE' by using the 'BaseTypeSelector' to pick an // overload of 'select' that performs said computation. } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, DynamicTypeCat>&) ///Implementation Note ///------------------- // Universal tag numbers are used only in the encoding of top-level // objects. Objects having the 'DynamicType' 'bdlat' type category // at any point other than their top level do not have a well defined // universal tag number. For the purpose of this component, an object // is a top-level object if it is not a member of any other object. { BSLS_ASSERT_OPT(0 && "Sub-objects having the 'DynamicType' category are " "unsupported. Only top-level objects may have " "a dynamic category."); return BerUniversalTagNumber::e_BER_INVALID; } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, EnumerationCat>&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_DEC == (d_formattingMode & FMode::e_TYPE_MASK) || FMode::e_TEXT == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_ENUMERATION; } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, ArrayCat>&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_SEQUENCE; } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, SequenceCat>&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK)); return BerUniversalTagNumber::e_BER_SEQUENCE; } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, ChoiceCat>&) { BSLS_ASSERT_SAFE( FMode::e_DEFAULT == (d_formattingMode & FMode::e_TYPE_MASK)); // According to X.694 (clause 20.4), an XML choice element is encoded as a // sequence with 1 element. return BerUniversalTagNumber::e_BER_SEQUENCE; } template <typename TYPE> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, NullableValueCat>&) ///Implementation Note ///------------------- // The BER universal tag number of the specified nullable type 'TYPE' is // defined to be the BER universal tag number of the value type of 'TYPE' // unless 'TYPE' has a "nillable" formatting mode flag set, in which case // the tag number is the tag number for sequences. { if (d_formattingMode & FMode::e_NILLABLE) { return BerUniversalTagNumber::e_BER_SEQUENCE; } // If control flow gets here, then the 'TYPE' is nullable, but not // nillable. typedef typename bdlat_NullableValueFunctions::ValueType<TYPE>::Type ValueType; // To compute the universal tag number of the specified 'TYPE', first // compute the 'ValueType' of 'TYPE'. typedef typename bdlat_TypeCategory::Select<ValueType>::Type ValueTypeCategory; // Then, determine the 'bdlat' type category of 'ValueType', // 'ValueTypeCategory'. typedef BerUniversalTagNumber_Sel<ValueType, ValueTypeCategory> ValueTypeSelector; // Next, construct a 'BerUniversalTagNumber_Sel' type specialized with // the computed 'ValueType' and 'ValueTypeCategory'. return this->select(ValueTypeSelector()); // Finally, return the result of computing the universal tag number of // the value of 'TYPE' by using the 'ValueTypeSelector' to pick an // overload of 'select' that performs said computation. } template <typename TYPE, typename ANY_CATEGORY> inline BerUniversalTagNumber::Value BerUniversalTagNumber_Imp::select( const BerUniversalTagNumber_Sel<TYPE, ANY_CATEGORY>&) { BSLS_ASSERT(0 && "invalid type category"); return BerUniversalTagNumber::e_BER_INVALID; } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------