// balxml_typesprintutil.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_BALXML_TYPESPRINTUTIL #define INCLUDED_BALXML_TYPESPRINTUTIL #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide a utility for printing types using XML formatting. // //@CLASSES: // balxml::TypesPrintUtil: utility for printing using XML formatting // //@SEE_ALSO: http://www.w3.org/TR/xmlschema-2/ // //@DESCRIPTION: The 'balxml::TypesPrintUtil' 'struct' provided by this // component contains the following functions: // //: 'print': //: Print an object using the supplied formatting mode. //: //: 'printBase64': //: Print an object using 'bdlat_FormattingMode::e_BASE64'. //: //: 'printDecimal': //: Print an object using 'bdlat_FormattingMode::e_DEC'. //: //: 'printDefault': //: Print an object using 'bdlat_FormattingMode::e_DEFAULT'. //: //: 'printHex': //: Print an object using 'bdlat_FormattingMode::e_HEX'. //: //: 'printList': //: Print an object using 'bdlat_FormattingMode::e_IS_LIST'. //: //: 'printText': //: Print an object using 'bdlat_FormattingMode::e_TEXT'. // // The output is generated according to each type's lexical representation as // described in the XML Schema Specification, which is available at // 'http://www.w3.org/TR/xmlschema-2/'. The text input is parsed and output // according to the XML-1.0 with UTF-8 encoding, which prevents control // characters (accepted by UTF-8) but otherwise accepts valid characters as // described in the Unicode Standard 4.0, which is available at // 'http://www.unicode.org/versions/Unicode4.0.0/' (well-formed UTF-8 byte // sequences are described in Chapter 3, Section 3.9 and Table 3.5). // // The following C++ Type / Formatting Mode combinations are supported by this // component: //.. // C++ Type Formatting Mode // -------- --------------- // bool DEFAULT, DEC, TEXT // char DEFAULT, DEC, TEXT // unsigned char DEFAULT, DEC // [unsigned] short DEFAULT, DEC // [unsigned] int DEFAULT, DEC // [unsigned] long DEFAULT, DEC // bsls::Types::[Uint64|Int64] DEFAULT, DEC // float DEFAULT, DEC // double DEFAULT, DEC // bdldfp::Decimal64 DEFAULT, DEC // bsl::string DEFAULT, TEXT, BASE64, HEX // bdlt::Date DEFAULT // bdlt::DateTz DEFAULT // bdlt::Datetime DEFAULT // bdlt::DateTimeTz DEFAULT // bdlt::Time DEFAULT // bdlt::TimeTz DEFAULT // bdlb::Variant2<DateTz, Date> DEFAULT // bdlb::Variant2<TimeTz, Time> DEFAULT // Variant2<DatetimeTz, Datetime> DEFAULT // bsl::vector<char> DEFAULT, BASE64, HEX, TEXT, IS_LIST //.. // In addition to the types listed above, this component also recognizes the // following 'bdlat' type categories: //.. // 'bdlat' Type Category Formatting Mode // --------------------- --------------- // Enumeration DEFAULT, TEXT, DECIMAL // CustomizedType Base type's formatting modes // Array IS_LIST //.. // When 'bdlat_FormattingMode::e_DEFAULT' is used, the actual formatting mode // selected is based on the following mapping: //.. // C++ Type Default Formatting Mode // -------- ----------------------- // bool DEC or TEXT // [unsigned] char DEC // [unsigned] short DEC // [unsigned] int DEC // [unsigned] long DEC // bsls::Types::[Uint64|Int64] DEC // bsl::string TEXT // bsl::vector<char> BASE64 // // 'bdlat' Type Category Default Formatting Mode // --------------------- ----------------------- // Enumeration TEXT //.. // ///Behavior of 'printText' on Non-Valid Strings ///-------------------------------------------- // The output of 'printText' will always be valid XML 1.0 with UTF-8 encoding. // When attempting to print text data that contains non-valid UTF-8 characters // or non-printable control characters using 'printText', this component prints // the valid characters up to and excluding the first invalid character. See // the second example in the 'Usage' section for an illustration. // ///Usage ///----- // The following snippets of code illustrates how to print an // 'bsl::vector<char>' object in Base64 format: //.. // #include <balxml_typesprintutil.h> // // #include <cassert> // #include <sstream> // #include <vector> // // using namespace BloombergLP; // // void usageExample1() // { // bsl::ostringstream ss; // // bsl::vector<char> vec; // vec.push_back('a'); // vec.push_back('b'); // vec.push_back('c'); // vec.push_back('d'); // // const char EXPECTED_RESULT[] = "YWJjZA=="; // // balxml::TypesPrintUtil::printBase64(ss, vec); // assert(EXPECTED_RESULT == ss.str()); // } //.. // The following snippet of shows what can be expected when printing valid or // invalid data via 'printText': //.. // void usageExample2() // { // bsl::ostringstream ss; // // const char VALID_STR[] = "Hello \t 'World'"; //.. // Note that all characters in the range '0x01' to '0x7F' are valid first bytes // (including printable ASCII, TAB '0x09', or LF '0x0a', but excluding control // characters other than TAB and LF) and that ampersand ('&' or '0x26'), // less-than ('<' or '0x3c'), greater-than ('>' or '0x3e'), apostrophe // ('0x27'), and quote ('"') will be printed as '&', '<', '>', // ''' and '"' respectively. Hence the expected output for the above // string 'VALID_STR' is: //.. // const char EXPECTED_RESULT[] = "Hello \t 'World'"; //.. // We can test that 'printText' will successfully print the string: //.. // balxml::TypesPrintUtil::printText(ss, VALID_STR); // assert(ss.good()); // assert(EXPECTED_RESULT == ss.str()); //.. // In addition, when invalid data is printed, the stream is set to a bad state // which is the proper means for the user to detect an error, as shown in the // following code snippet: //.. // ss.str(""); // const char INVALID_STR[] = "Hello \300\t 'World'"; // balxml::TypesPrintUtil::printText(ss, INVALID_STR); // assert(ss.fail()); // assert("Hello " == ss.str()); // } //.. #include <balscm_version.h> #include <balxml_encoderoptions.h> #include <bdlat_arrayfunctions.h> #include <bdlat_arrayutil.h> #include <bdlat_customizedtypefunctions.h> #include <bdlat_enumfunctions.h> #include <bdlat_formattingmode.h> #include <bdlat_nullablevalueutil.h> #include <bdlat_typecategory.h> #include <bdldfp_decimal.h> #include <bdlt_date.h> #include <bdlt_datetime.h> #include <bdlt_datetimetz.h> #include <bdlt_datetz.h> #include <bdlt_iso8601util.h> #include <bdlt_time.h> #include <bdlt_timetz.h> #include <bslmf_enableif.h> #include <bslmf_isclass.h> #include <bslmf_isconvertible.h> #include <bsls_assert.h> #include <bsls_types.h> #include <bdlb_float.h> #include <bsl_iomanip.h> #include <bsl_istream.h> #include <bsl_ios.h> #include <bsl_ostream.h> #include <bsl_string.h> #include <bsl_vector.h> namespace BloombergLP { namespace balxml { // ===================== // struct TypesPrintUtil // ===================== struct TypesPrintUtil { // This 'struct' contains functions for printing objects to output streams // using various formatting modes. // CLASS METHODS template <class TYPE> static bsl::ostream& print(bsl::ostream& stream, const TYPE& object, int formattingMode, const EncoderOptions *encoderOptions = 0); // Format the specified 'object' to the specified output 'stream' using // the specified 'formattingMode' and the optionally specified // 'encoderOptions' and return a reference to 'stream'. The behavior // is undefined unless the parameterized 'TYPE' and the // 'formattingMode' combination is supported (supported combinations // are listed in the component-level documentation). template <class TYPE> static bsl::ostream& printBase64(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions = 0); // Format the specified 'object' to the specified output 'stream' using // the 'bdlat_FormattingMode::e_BASE64' formatting mode and the // optionally specified 'encoderOptions'. Return a reference to // 'stream'. template <class TYPE> static bsl::ostream& printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions = 0); // Format the specified 'object' to the specified output 'stream' using // the 'bdlat_FormattingMode::e_DEC' formatting mode and the // optionally specified 'encoderOptions'. Return a reference to // 'stream'. template <class TYPE> static bsl::ostream& printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions = 0); // Format the specified 'object' to the specified output 'stream' using // the 'bdlat_FormattingMode::e_DEFAULT' formatting mode and the // optionally specified 'encoderOptions'. Return a reference to // 'stream'. template <class TYPE> static bsl::ostream& printHex(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions = 0); // Format the specified 'object' to the specified output 'stream' using // the 'bdlat_FormattingMode::e_HEX' formatting mode and the // optionally specified 'encoderOptions'. Return a reference to // 'stream'. template <class TYPE> static bsl::ostream& printList(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions = 0); // Format the specified 'object' to the specified output 'stream' using // the 'bdlat_FormattingMode::e_LIST' formatting mode and the // optionally specified 'encoderOptions'. Return a reference to // 'stream'. template <class TYPE> static bsl::ostream& printText(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions = 0); // Format the specified 'object' to the specified output 'stream' using // the 'bdlat_FormattingMode::e_TEXT' formatting mode and the // optionally specified 'encoderOptions'. Return a reference to // 'stream'. The string representation of 'object' must be a valid // UTF-8 string and may not contain any control characters other than // TAB, NL, and CR (i.e., no binary data) unless // 'encoderOptions->allowControlCharacters()' is 'true', in which // control characters will be encoded as is. Upon detecting an invalid // byte, the output stops and the 'failbit' is be set on the output // 'stream'. In the case of an invalid byte in a multi-byte // character, the output stops after the previous character and no // byte in this character is output. }; // ========================= // struct TypesPrintUtil_Imp // ========================= struct TypesPrintUtil_Imp { // This 'struct' contains functions that are used in the implementation of // this component. // TYPES typedef bdlb::Variant2<bdlt::Date, bdlt::DateTz> DateOrDateTz; // 'DateOrDateTz' is a convenient alias for // 'bdlb::Variant2<Date, DateTz>'. typedef bdlb::Variant2<bdlt::Time, bdlt::TimeTz> TimeOrTimeTz; // 'TimeOrTimeTz' is a convenient alias for // 'bdlb::Variant2<Time, TimeTz>'. typedef bdlb::Variant2<bdlt::Datetime, bdlt::DatetimeTz> DatetimeOrDatetimeTz; // 'DatetimeOrDatetimeTz' is a convenient alias for // 'bdlb::Variant2<Datetime, DatetimeTz>'. // CLASS METHODS template <class TYPE> static bsl::ostream& printDateAndTime( bsl::ostream& stream, const TYPE& value, const EncoderOptions *encoderOptions); // Encode the specified 'value' into XML using ISO 8601 format and // output the result to the specified 'stream' using the specified // 'encoderOptions'. // BASE64 FUNCTIONS template <class TYPE> static bsl::ostream& printBase64( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType); template <class TYPE, class ANY_CATEGORY> static bsl::ostream& printBase64(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, ANY_CATEGORY); static bsl::ostream& printBase64( bsl::ostream& stream, const bsl::string_view& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); template <class TYPE> static typename bsl::enable_if< bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type printBase64(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printBase64(bsl::ostream& stream, const bsl::vector<char>& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Array); // DECIMAL FUNCTIONS template <class TYPE> static bsl::ostream& printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Enumeration); template <class TYPE> static bsl::ostream& printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::CustomizedType); template <class TYPE> static bsl::ostream& printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType); template <class TYPE, class ANY_CATEGORY> static bsl::ostream& printDecimal(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, ANY_CATEGORY); static bsl::ostream& printDecimal( bsl::ostream& stream, const bool& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const char& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const short& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const int& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const long& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const bsls::Types::Int64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const unsigned char& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const unsigned short& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const unsigned int& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const unsigned long& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const bsls::Types::Uint64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const float& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const double& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDecimal( bsl::ostream& stream, const bdldfp::Decimal64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); // DEFAULT FUNCTIONS template <class TYPE> static bsl::ostream& printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Enumeration); template <class TYPE> static bsl::ostream& printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::CustomizedType); template <class TYPE> static bsl::ostream& printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType); template <class TYPE> static bsl::ostream& printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::NullableValue); template <class TYPE, class ANY_CATEGORY> static bsl::ostream& printDefault(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, ANY_CATEGORY); static bsl::ostream& printDefault( bsl::ostream& stream, const bool& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const char& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const short& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const int& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const long& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bsls::Types::Int64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const unsigned char& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const unsigned short& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const unsigned int& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const unsigned long& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bsls::Types::Uint64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const float& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const double& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bdldfp::Decimal64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const char *object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bsl::string_view& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); template <class TYPE> static typename bsl::enable_if< bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type printDefault(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bdlt::Date& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bdlt::DateTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bdlt::Datetime& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bdlt::DatetimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bdlt::Time& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bdlt::TimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const DateOrDateTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const TimeOrTimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const DatetimeOrDatetimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printDefault( bsl::ostream& stream, const bsl::vector<char>& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Array); // HEX FUNCTIONS template <class TYPE> static bsl::ostream& printHex( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType); template <class TYPE, class ANY_CATEGORY> static bsl::ostream& printHex(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, ANY_CATEGORY); static bsl::ostream& printHex(bsl::ostream& stream, const bsl::string_view& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); template <class TYPE> static typename bsl::enable_if< bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type printHex(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printHex(bsl::ostream& stream, const bsl::vector<char>& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Array); // LIST FUNCTIONS template <class TYPE> static bsl::ostream& printList(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Array); template <class TYPE> static bsl::ostream& printList( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType); template <class TYPE, class ANY_CATEGORY> static bsl::ostream& printList(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, ANY_CATEGORY); // TEXT FUNCTIONS template <class TYPE> static bsl::ostream& printText( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Enumeration); template <class TYPE> static bsl::ostream& printText( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::CustomizedType); template <class TYPE> static bsl::ostream& printText( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType); template <class TYPE, class ANY_CATEGORY> static bsl::ostream& printText(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, ANY_CATEGORY); static bsl::ostream& printText(bsl::ostream& stream, const bool& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printText(bsl::ostream& stream, const char& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printText(bsl::ostream& stream, const char *object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printText(bsl::ostream& stream, const bsl::string_view& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); template <class TYPE> static typename bsl::enable_if< bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type printText(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple); static bsl::ostream& printText(bsl::ostream& stream, const bsl::vector<char>& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Array); }; // ============================================================================ // PROXY CLASSES // ============================================================================ // =================================== // class TypesPrintUtilImp_PrintBase64 // =================================== class TypesPrintUtilImp_PrintBase64 { // Component-private struct. Do not use. // DATA bsl::ostream *d_stream_p; const EncoderOptions *d_encoderOptions_p; public: // CREATORS TypesPrintUtilImp_PrintBase64(bsl::ostream *stream, const EncoderOptions *encoderOptions) : d_stream_p(stream) , d_encoderOptions_p(encoderOptions) { } // ACCESSORS template <class TYPE, class ANY_CATEGORY> int operator()(const TYPE& object, ANY_CATEGORY category) const { TypesPrintUtil_Imp::printBase64(*d_stream_p, object, d_encoderOptions_p, category); return static_cast<bool>(*d_stream_p) ? 0 : -1; } template <class TYPE> int operator()(const TYPE&, bslmf::Nil) const { BSLS_ASSERT_SAFE(0); return -1; } }; // ==================================== // class TypesPrintUtilImp_PrintDecimal // ==================================== class TypesPrintUtilImp_PrintDecimal { // Component-private class. Do not use. // DATA bsl::ostream *d_stream_p; const EncoderOptions *d_encoderOptions_p; public: // CREATORS TypesPrintUtilImp_PrintDecimal(bsl::ostream *stream, const EncoderOptions *encoderOptions) : d_stream_p(stream) , d_encoderOptions_p(encoderOptions) { } // ACCESSORS template <class TYPE, class ANY_CATEGORY> int operator()(const TYPE& object, ANY_CATEGORY category) const { TypesPrintUtil_Imp::printDecimal(*d_stream_p, object, d_encoderOptions_p, category); return static_cast<bool>(*d_stream_p) ? 0 : -1; } template <class TYPE> int operator()(const TYPE&, bslmf::Nil) const { BSLS_ASSERT_SAFE(0); return -1; } }; // ==================================== // class TypesPrintUtilImp_PrintDefault // ==================================== class TypesPrintUtilImp_PrintDefault { // Component-private class. Do not use. // DATA bsl::ostream *d_stream_p; const EncoderOptions *d_encoderOptions_p; public: // CREATORS TypesPrintUtilImp_PrintDefault(bsl::ostream *stream, const EncoderOptions *encoderOptions) : d_stream_p(stream) , d_encoderOptions_p(encoderOptions) { } // ACCESSORS template <class TYPE, class ANY_CATEGORY> int operator()(const TYPE& object, ANY_CATEGORY category) const { TypesPrintUtil_Imp::printDefault(*d_stream_p, object, d_encoderOptions_p, category); return static_cast<bool>(*d_stream_p) ? 0 : -1; } template <class TYPE> int operator()(const TYPE&, bslmf::Nil) const { BSLS_ASSERT_SAFE(0); return -1; } }; // ================================ // class TypesPrintUtilImp_PrintHex // ================================ class TypesPrintUtilImp_PrintHex { // Component-private class. Do not use. // DATA bsl::ostream *d_stream_p; const EncoderOptions *d_encoderOptions_p; public: // CREATORS TypesPrintUtilImp_PrintHex(bsl::ostream *stream, const EncoderOptions *encoderOptions) : d_stream_p(stream) , d_encoderOptions_p(encoderOptions) { } // ACCESSORS template <class TYPE, class ANY_CATEGORY> int operator()(const TYPE& object, ANY_CATEGORY category) const { TypesPrintUtil_Imp::printHex(*d_stream_p, object, d_encoderOptions_p, category); return static_cast<bool>(*d_stream_p) ? 0 : -1; } template <class TYPE> int operator()(const TYPE&, bslmf::Nil) const { BSLS_ASSERT_SAFE(0); return -1; } }; // ================================= // class TypesPrintUtilImp_PrintList // ================================= class TypesPrintUtilImp_PrintList { // Component-private class. Do not use. // DATA bsl::ostream *d_stream_p; const EncoderOptions *d_encoderOptions_p; public: // CREATORS TypesPrintUtilImp_PrintList(bsl::ostream *stream, const EncoderOptions *encoderOptions) : d_stream_p(stream) , d_encoderOptions_p(encoderOptions) { } // ACCESSORS template <class TYPE, class ANY_CATEGORY> int operator()(const TYPE& object, ANY_CATEGORY category) const { TypesPrintUtil_Imp::printList(*d_stream_p, object, d_encoderOptions_p, category); return static_cast<bool>(*d_stream_p) ? 0 : -1; } template <class TYPE> int operator()(const TYPE&, bslmf::Nil) const { BSLS_ASSERT_SAFE(0); return -1; } }; // =============================================== // class TypesPrintUtilImp_PrintListElementDefault // =============================================== class TypesPrintUtilImp_PrintListElementDefault { // Component-private class. Do not use. // DATA bool d_doesNextElemNeedDelimiter; bsl::ostream *d_stream_p; const EncoderOptions *d_encoderOptions_p; public: // CREATORS TypesPrintUtilImp_PrintListElementDefault( bsl::ostream *stream, const EncoderOptions *encoderOptions) : d_doesNextElemNeedDelimiter(false) , d_stream_p(stream) , d_encoderOptions_p(encoderOptions) { } // MANIPULATORS template <class TYPE> int operator()(const TYPE& object, bdlat_TypeCategory::NullableValue) { if (bdlat_NullableValueFunctions::isNull(object)) { return static_cast<bool>(*d_stream_p) ? 0 : -1; // RETURN } if (d_doesNextElemNeedDelimiter) { *d_stream_p << " "; } d_doesNextElemNeedDelimiter = true; TypesPrintUtilImp_PrintDefault printDefault(d_stream_p, d_encoderOptions_p); return bdlat::NullableValueUtil::accessValueByCategory(object, printDefault); } template <class TYPE, class OTHER_CATEGORY> int operator()(const TYPE& object, OTHER_CATEGORY category) { if (d_doesNextElemNeedDelimiter) { *d_stream_p << " "; } d_doesNextElemNeedDelimiter = true; TypesPrintUtil_Imp::printDefault(*d_stream_p, object, d_encoderOptions_p, category); return static_cast<bool>(*d_stream_p) ? 0 : -1; } template <class TYPE> int operator()(const TYPE&, bslmf::Nil) { BSLS_ASSERT_SAFE(0); return -1; } }; // ================================= // class TypesPrintUtilImp_PrintText // ================================= class TypesPrintUtilImp_PrintText { // Component-private class. Do not use. // DATA bsl::ostream *d_stream_p; const EncoderOptions *d_encoderOptions_p; public: // CREATORS TypesPrintUtilImp_PrintText(bsl::ostream *stream, const EncoderOptions *encoderOptions) : d_stream_p(stream) , d_encoderOptions_p(encoderOptions) { } // ACCESSORS template <class TYPE, class ANY_CATEGORY> int operator()(const TYPE& object, ANY_CATEGORY category) const { TypesPrintUtil_Imp::printText(*d_stream_p, object, d_encoderOptions_p, category); return static_cast<bool>(*d_stream_p) ? 0 : -1; } template <class TYPE> int operator()(const TYPE&, bslmf::Nil) const { BSLS_ASSERT_SAFE(0); return -1; } }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // --------------------- // struct TypesPrintUtil // --------------------- template <class TYPE> bsl::ostream& TypesPrintUtil::print(bsl::ostream& stream, const TYPE& object, int formattingMode, const EncoderOptions *encoderOptions) { typedef typename bdlat_TypeCategory::Select<TYPE>::Type Tag; if (formattingMode & bdlat_FormattingMode::e_LIST) { return TypesPrintUtil::printList(stream, object, encoderOptions); } switch (formattingMode & bdlat_FormattingMode::e_TYPE_MASK) { case bdlat_FormattingMode::e_BASE64: { return TypesPrintUtil_Imp::printBase64( stream, object, encoderOptions, Tag()); } break; case bdlat_FormattingMode::e_DEC: { return TypesPrintUtil_Imp::printDecimal( stream, object, encoderOptions, Tag()); } break; case bdlat_FormattingMode::e_DEFAULT: { return TypesPrintUtil_Imp::printDefault( stream, object, encoderOptions, Tag()); } break; case bdlat_FormattingMode::e_HEX: { return TypesPrintUtil_Imp::printHex( stream, object, encoderOptions, Tag()); } break; case bdlat_FormattingMode::e_TEXT: { return TypesPrintUtil_Imp::printText( stream, object, encoderOptions, Tag()); } break; default: { BSLS_ASSERT_SAFE(!"Unsupported operation!"); stream.setstate(bsl::ios_base::failbit); return stream; // RETURN } break; } return stream; } template <class TYPE> inline bsl::ostream& TypesPrintUtil::printBase64(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions) { typedef typename bdlat_TypeCategory::Select<TYPE>::Type Tag; return TypesPrintUtil_Imp::printBase64( stream, object, encoderOptions, Tag()); } template <class TYPE> inline bsl::ostream& TypesPrintUtil::printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions) { typedef typename bdlat_TypeCategory::Select<TYPE>::Type Tag; return TypesPrintUtil_Imp::printDecimal( stream, object, encoderOptions, Tag()); } template <class TYPE> inline bsl::ostream& TypesPrintUtil::printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions) { typedef typename bdlat_TypeCategory::Select<TYPE>::Type Tag; return TypesPrintUtil_Imp::printDefault( stream, object, encoderOptions, Tag()); } template <class TYPE> inline bsl::ostream& TypesPrintUtil::printHex(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions) { typedef typename bdlat_TypeCategory::Select<TYPE>::Type Tag; return TypesPrintUtil_Imp::printHex( stream, object, encoderOptions, Tag()); } template <class TYPE> inline bsl::ostream& TypesPrintUtil::printList(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions) { typedef typename bdlat_TypeCategory::Select<TYPE>::Type Tag; return TypesPrintUtil_Imp::printList( stream, object, encoderOptions, Tag()); } template <class TYPE> inline bsl::ostream& TypesPrintUtil::printText(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions) { typedef typename bdlat_TypeCategory::Select<TYPE>::Type Tag; return TypesPrintUtil_Imp::printText( stream, object, encoderOptions, Tag()); } // ------------------------- // struct TypesPrintUtil_Imp // ------------------------- // BASE64 FUNCTIONS template <typename TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printBase64( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType) { const TypesPrintUtilImp_PrintBase64 printBase64Cb(&stream, encoderOptions); bdlat_TypeCategoryUtil::accessByCategory(object, printBase64Cb); return stream; } template <typename TYPE> inline typename bsl::enable_if<bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type TypesPrintUtil_Imp::printBase64(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printBase64(stream, static_cast<bsl::string_view>(object), encoderOptions, bdlat_TypeCategory::Simple()); } template <class TYPE, class ANY_CATEGORY> inline bsl::ostream& TypesPrintUtil_Imp::printBase64(bsl::ostream& stream, const TYPE&, const EncoderOptions *, ANY_CATEGORY) { BSLS_ASSERT_SAFE(!"Unsupported operation!"); stream.setstate(bsl::ios_base::failbit); // Note: 'printBase64' for 'bsl::string' and 'bsl::vector<char>' is inside // the CPP file. return stream; } // DECIMAL FUNCTIONS template <typename TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType) { const TypesPrintUtilImp_PrintDecimal printDecimalCb(&stream, encoderOptions); bdlat_TypeCategoryUtil::accessByCategory(object, printDecimalCb); return stream; } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Enumeration) { int intValue; bdlat_EnumFunctions::toInt(&intValue, object); return TypesPrintUtil::printDecimal(stream, intValue, encoderOptions); } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::CustomizedType) { return TypesPrintUtil::printDecimal( stream, bdlat_CustomizedTypeFunctions::convertToBaseType(object), encoderOptions); } template <class TYPE, class ANY_CATEGORY> inline bsl::ostream& TypesPrintUtil_Imp::printDecimal(bsl::ostream& stream, const TYPE&, const EncoderOptions *, ANY_CATEGORY) { BSLS_ASSERT_SAFE(!"Unsupported operation!"); stream.setstate(bsl::ios_base::failbit); return stream; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const bool& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << (object ? 1 : 0); } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const char& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { signed char temp(object); // Note that 'char' is unsigned on IBM. return stream << int(temp); } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const short& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const int& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const long& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const bsls::Types::Int64& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const unsigned char& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { unsigned short us = object; return stream << us; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const unsigned short& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const unsigned int& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const unsigned long& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } inline bsl::ostream& TypesPrintUtil_Imp::printDecimal( bsl::ostream& stream, const bsls::Types::Uint64& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << object; } // DEFAULT FUNCTIONS template <typename TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType) { const TypesPrintUtilImp_PrintDefault printDefaultCb(&stream, encoderOptions); bdlat_TypeCategoryUtil::accessByCategory(object, printDefaultCb); return stream; } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Enumeration) { bsl::string stringVal; bdlat_EnumFunctions::toString(&stringVal, object); return TypesPrintUtil::printText(stream, stringVal, encoderOptions); } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::CustomizedType) { return TypesPrintUtil::printDefault( stream, bdlat_CustomizedTypeFunctions::convertToBaseType(object), encoderOptions); } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::NullableValue) { if (bdlat_NullableValueFunctions::isNull(object)) { return stream; // RETURN } TypesPrintUtilImp_PrintDefault printDefault(&stream, encoderOptions); bdlat::NullableValueUtil::accessValueByCategory(object, printDefault); return stream; } template <class TYPE, class ANY_CATEGORY> inline bsl::ostream& TypesPrintUtil_Imp::printDefault(bsl::ostream& stream, const TYPE&, const EncoderOptions *, ANY_CATEGORY) { BSLS_ASSERT_SAFE(!"Unsupported operation!"); stream.setstate(bsl::ios_base::failbit); return stream; } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bool& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printText(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const char& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const short& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const int& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const long& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bsls::Types::Int64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const unsigned char& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const unsigned short& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const unsigned int& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const unsigned long& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bsls::Types::Uint64& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDecimal(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const char *object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printText(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bsl::string_view& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printText(stream, object, encoderOptions, bdlat_TypeCategory::Simple()); } template <class TYPE> typename bsl::enable_if<bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type TypesPrintUtil_Imp::printDefault(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDefault(stream, static_cast<const bsl::string_view&>(object), encoderOptions, bdlat_TypeCategory::Simple()); } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printDateAndTime( bsl::ostream& stream, const TYPE& value, const EncoderOptions *encoderOptions) { bdlt::Iso8601UtilConfiguration config; if (encoderOptions) { config.setFractionalSecondPrecision( encoderOptions->datetimeFractionalSecondPrecision()); config.setUseZAbbreviationForUtc( encoderOptions->useZAbbreviationForUtc()); } else { config.setFractionalSecondPrecision(6); config.setUseZAbbreviationForUtc(false); } return bdlt::Iso8601Util::generate(stream, value, config); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bdlt::Date& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bdlt::DateTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bdlt::Datetime& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bdlt::DatetimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bdlt::Time& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bdlt::TimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const DateOrDateTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const TimeOrTimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const DatetimeOrDatetimeTz& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printDateAndTime(stream, object, encoderOptions); } inline bsl::ostream& TypesPrintUtil_Imp::printDefault( bsl::ostream& stream, const bsl::vector<char>& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Array) { return printBase64(stream, object, encoderOptions, bdlat_TypeCategory::Array()); } // HEX FUNCTIONS template <typename TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printHex( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType) { const TypesPrintUtilImp_PrintHex printHexCb(&stream, encoderOptions); bdlat_TypeCategoryUtil::accessByCategory(object, printHexCb); return stream; } template <class TYPE, class ANY_CATEGORY> inline bsl::ostream& TypesPrintUtil_Imp::printHex(bsl::ostream& stream, const TYPE&, const EncoderOptions *, ANY_CATEGORY) { BSLS_ASSERT_SAFE(!"Unsupported operation!"); stream.setstate(bsl::ios_base::failbit); // Note: 'printHex' for 'bsl::string' and 'bsl::vector<char>' is inside the // CPP file. return stream; } template <class TYPE> inline typename bsl::enable_if<bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type TypesPrintUtil_Imp::printHex(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printHex(stream, static_cast<const bsl::string_view&>(object), encoderOptions, bdlat_TypeCategory::Simple()); } // LIST FUNCTIONS template <typename TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printList( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType) { const TypesPrintUtilImp_PrintList printListCb(&stream, encoderOptions); bdlat_TypeCategoryUtil::accessByCategory(object, printListCb); return stream; } template <class TYPE> bsl::ostream& TypesPrintUtil_Imp::printList( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Array) { const bsl::size_t size = bdlat_ArrayFunctions::size(object); if (0 == size) { return stream; // RETURN } TypesPrintUtilImp_PrintListElementDefault printElement(&stream, encoderOptions); bdlat::ArrayUtil::accessElementByCategory(object, printElement, 0); for (bsl::size_t idx = 1; idx != size; ++idx) { bdlat::ArrayUtil::accessElementByCategory( object, printElement, static_cast<int>(idx)); } return stream; } template <class TYPE, class ANY_CATEGORY> inline bsl::ostream& TypesPrintUtil_Imp::printList(bsl::ostream& stream, const TYPE&, const EncoderOptions *, ANY_CATEGORY) { BSLS_ASSERT_SAFE(!"Unsupported operation!"); stream.setstate(bsl::ios_base::failbit); return stream; } // TEXT FUNCTIONS template <typename TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printText( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::DynamicType) { const TypesPrintUtilImp_PrintText printTextCb(&stream, encoderOptions); bdlat_TypeCategoryUtil::accessByCategory(object, printTextCb); return stream; } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printText( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Enumeration) { bsl::string stringVal; bdlat_EnumFunctions::toString(&stringVal, object); return TypesPrintUtil::printText(stream, stringVal, encoderOptions); } template <class TYPE> inline bsl::ostream& TypesPrintUtil_Imp::printText( bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::CustomizedType) { return TypesPrintUtil::printText( stream, bdlat_CustomizedTypeFunctions::convertToBaseType(object), encoderOptions); } template <class TYPE, class ANY_CATEGORY> inline bsl::ostream& TypesPrintUtil_Imp::printText(bsl::ostream& stream, const TYPE&, const EncoderOptions *, ANY_CATEGORY) { BSLS_ASSERT_SAFE(!"Unsupported operation!"); stream.setstate(bsl::ios_base::failbit); return stream; } inline bsl::ostream& TypesPrintUtil_Imp::printText(bsl::ostream& stream, const bool& object, const EncoderOptions *, bdlat_TypeCategory::Simple) { return stream << (object ? "true" : "false"); } template <class TYPE> typename bsl::enable_if<bsl::is_class<TYPE>::value && bsl::is_convertible<TYPE, bsl::string_view>::value, bsl::ostream&>::type TypesPrintUtil_Imp::printText(bsl::ostream& stream, const TYPE& object, const EncoderOptions *encoderOptions, bdlat_TypeCategory::Simple) { return printText(stream, static_cast<const bsl::string_view&>(object), encoderOptions, bdlat_TypeCategory::Simple()); } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2017 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 ----------------------------------