File indexing completed on 2025-07-11 08:28:17
0001 #ifndef BOOST_UUID_UUID_IO_HPP_INCLUDED
0002 #define BOOST_UUID_UUID_IO_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/uuid/uuid.hpp>
0010 #include <boost/uuid/detail/to_chars.hpp>
0011 #include <boost/uuid/detail/static_assert.hpp>
0012 #include <boost/config.hpp>
0013 #include <iosfwd>
0014 #include <istream>
0015 #include <locale>
0016 #include <algorithm>
0017 #include <string>
0018 #include <cstddef>
0019
0020 #if defined(_MSC_VER)
0021 #pragma warning(push)
0022 #pragma warning(disable : 4996)
0023 #endif
0024
0025 namespace boost {
0026 namespace uuids {
0027
0028
0029
0030 template<class OutputIterator>
0031 OutputIterator to_chars( uuid const& u, OutputIterator out )
0032 {
0033 char tmp[ 36 ];
0034 detail::to_chars( u, tmp );
0035
0036 return std::copy_n( tmp, 36, out );
0037 }
0038
0039 template<class Ch>
0040 inline bool to_chars( uuid const& u, Ch* first, Ch* last ) noexcept
0041 {
0042 if( last - first < 36 )
0043 {
0044 return false;
0045 }
0046
0047 detail::to_chars( u, first );
0048 return true;
0049 }
0050
0051 template<class Ch, std::size_t N>
0052 inline Ch* to_chars( uuid const& u, Ch (&buffer)[ N ] ) noexcept
0053 {
0054 BOOST_UUID_STATIC_ASSERT( N >= 37 );
0055
0056 detail::to_chars( u, buffer + 0 );
0057 buffer[ 36 ] = 0;
0058
0059 return buffer + 36;
0060 }
0061
0062
0063 template<class Ch>
0064 BOOST_DEPRECATED( "Use Ch[37] instead of Ch[36] to allow for the null terminator" )
0065 inline Ch* to_chars( uuid const& u, Ch (&buffer)[ 36 ] ) noexcept
0066 {
0067 detail::to_chars( u, buffer + 0 );
0068 return buffer + 36;
0069 }
0070
0071
0072
0073 template<class Ch, class Traits>
0074 std::basic_ostream<Ch, Traits>& operator<<( std::basic_ostream<Ch, Traits>& os, uuid const& u )
0075 {
0076 char tmp[ 37 ];
0077 to_chars( u, tmp );
0078
0079 os << tmp;
0080 return os;
0081 }
0082
0083
0084
0085 template<class Ch, class Traits>
0086 std::basic_istream<Ch, Traits>& operator>>( std::basic_istream<Ch, Traits>& is, uuid& u )
0087 {
0088 Ch tmp[ 37 ] = {};
0089
0090 is.width( 37 );
0091
0092 if( is >> tmp )
0093 {
0094 u = {};
0095
0096 using ctype_t = std::ctype<Ch>;
0097 ctype_t const& ctype = std::use_facet<ctype_t>( is.getloc() );
0098
0099 Ch xdigits[ 17 ];
0100
0101 {
0102 char szdigits[] = "0123456789ABCDEF-";
0103 ctype.widen( szdigits, szdigits + 17, xdigits );
0104 }
0105
0106 Ch* const xdigits_end = xdigits + 16;
0107
0108 ctype.toupper( tmp, tmp + 36 );
0109
0110 int j = 0;
0111
0112 for( std::size_t i = 0; i < 16; ++i )
0113 {
0114 Ch* f = std::find( xdigits, xdigits_end, tmp[ j++ ] );
0115
0116 if( f == xdigits_end )
0117 {
0118 is.setstate( std::ios_base::failbit );
0119 return is;
0120 }
0121
0122 unsigned char byte = static_cast<unsigned char>( f - xdigits );
0123
0124 f = std::find( xdigits, xdigits_end, tmp[ j++ ] );
0125
0126 if( f == xdigits_end )
0127 {
0128 is.setstate( std::ios_base::failbit );
0129 return is;
0130 }
0131
0132 byte <<= 4;
0133 byte |= static_cast<unsigned char>( f - xdigits );
0134
0135 u.data()[ i ] = byte;
0136
0137 if( i == 3 || i == 5 || i == 7 || i == 9 )
0138 {
0139 if( tmp[ j++ ] != xdigits[ 16 ] )
0140 {
0141 is.setstate( std::ios_base::failbit );
0142 return is;
0143 }
0144 }
0145 }
0146 }
0147
0148 return is;
0149 }
0150
0151
0152
0153 inline std::string to_string( uuid const& u )
0154 {
0155 std::string result( 36, char() );
0156
0157
0158 detail::to_chars( u, &result[0] );
0159 return result;
0160 }
0161
0162 inline std::wstring to_wstring( uuid const& u )
0163 {
0164 std::wstring result( 36, wchar_t() );
0165
0166 detail::to_chars( u, &result[0] );
0167 return result;
0168 }
0169
0170 }}
0171
0172 #if defined(_MSC_VER)
0173 #pragma warning(pop)
0174 #endif
0175
0176 #endif