Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:02:08

0001 // Boost uuid_io.hpp header file  ----------------------------------------------//
0002 
0003 // Copyright 2009 Andy Tompkins.
0004 // Distributed under the Boost Software License, Version 1.0. (See
0005 // accompanying file LICENSE_1_0.txt or copy at
0006 // https://www.boost.org/LICENSE_1_0.txt)
0007 
0008 // Revision History
0009 //  20 Mar 2009 - Initial Revision
0010 //  28 Nov 2009 - disabled deprecated warnings for MSVC
0011 
0012 #ifndef BOOST_UUID_IO_HPP
0013 #define BOOST_UUID_IO_HPP
0014 
0015 #include <boost/uuid/uuid.hpp>
0016 #include <ios>
0017 #include <ostream>
0018 #include <istream>
0019 #include <boost/io/ios_state.hpp>
0020 #include <locale>
0021 #include <algorithm>
0022 
0023 #if defined(_MSC_VER)
0024 #pragma warning(push) // Save warning settings.
0025 #pragma warning(disable : 4996) // Disable deprecated std::ctype<char>::widen, std::copy
0026 #endif
0027 
0028 namespace boost {
0029 namespace uuids {
0030 
0031 template <typename ch, typename char_traits>
0032     std::basic_ostream<ch, char_traits>& operator<<(std::basic_ostream<ch, char_traits> &os, uuid const& u)
0033 {
0034     io::ios_flags_saver flags_saver(os);
0035     io::basic_ios_fill_saver<ch, char_traits> fill_saver(os);
0036 
0037     const typename std::basic_ostream<ch, char_traits>::sentry ok(os);
0038     if (ok) {
0039         const std::streamsize width = os.width(0);
0040         const std::streamsize uuid_width = 36;
0041         const std::ios_base::fmtflags flags = os.flags();
0042         const typename std::basic_ios<ch, char_traits>::char_type fill = os.fill();
0043         if (flags & (std::ios_base::right | std::ios_base::internal)) {
0044             for (std::streamsize i=uuid_width; i<width; i++) {
0045                 os << fill;
0046             }
0047         }
0048 
0049         os << std::hex << std::right;
0050         os.fill(os.widen('0'));
0051 
0052         std::size_t i=0;
0053         for (uuid::const_iterator i_data = u.begin(); i_data!=u.end(); ++i_data, ++i) {
0054             os.width(2);
0055             os << static_cast<unsigned int>(*i_data);
0056             if (i == 3 || i == 5 || i == 7 || i == 9) {
0057                 os << os.widen('-');
0058             }
0059         }
0060 
0061         if (flags & std::ios_base::left) {
0062             for (std::streamsize s=uuid_width; s<width; s++) {
0063                 os << fill;
0064             }
0065         }
0066 
0067         os.width(0); //used the width so reset it
0068     }
0069     return os;
0070 }
0071 
0072 template <typename ch, typename char_traits>
0073     std::basic_istream<ch, char_traits>& operator>>(std::basic_istream<ch, char_traits> &is, uuid &u)
0074 {
0075     const typename std::basic_istream<ch, char_traits>::sentry ok(is);
0076     if (ok) {
0077         unsigned char data[16];
0078 
0079         typedef std::ctype<ch> ctype_t;
0080         ctype_t const& ctype = std::use_facet<ctype_t>(is.getloc());
0081 
0082         ch xdigits[16];
0083         {
0084             char szdigits[] = "0123456789ABCDEF";
0085             ctype.widen(szdigits, szdigits+16, xdigits);
0086         }
0087         ch*const xdigits_end = xdigits+16;
0088 
0089         ch c;
0090         for (std::size_t i=0; i<u.size() && is; ++i) {
0091             is >> c;
0092             c = ctype.toupper(c);
0093 
0094             ch* f = std::find(xdigits, xdigits_end, c);
0095             if (f == xdigits_end) {
0096                 is.setstate(std::ios_base::failbit);
0097                 break;
0098             }
0099 
0100             unsigned char byte = static_cast<unsigned char>(std::distance(&xdigits[0], f));
0101 
0102             is >> c;
0103             c = ctype.toupper(c);
0104             f = std::find(xdigits, xdigits_end, c);
0105             if (f == xdigits_end) {
0106                 is.setstate(std::ios_base::failbit);
0107                 break;
0108             }
0109 
0110             byte <<= 4;
0111             byte |= static_cast<unsigned char>(std::distance(&xdigits[0], f));
0112 
0113             data[i] = byte;
0114 
0115             if (is) {
0116                 if (i == 3 || i == 5 || i == 7 || i == 9) {
0117                     is >> c;
0118                     if (c != is.widen('-')) is.setstate(std::ios_base::failbit);
0119                 }
0120             }
0121         }
0122 
0123         if (is) {
0124             std::copy(data, data+16, u.begin());
0125         }
0126     }
0127     return is;
0128 }
0129 
0130 namespace detail {
0131 inline char to_char(size_t i) {
0132     if (i <= 9) {
0133         return static_cast<char>('0' + i);
0134     } else {
0135         return static_cast<char>('a' + (i-10));
0136     }
0137 }
0138 
0139 inline wchar_t to_wchar(size_t i) {
0140     if (i <= 9) {
0141         return static_cast<wchar_t>(L'0' + i);
0142     } else {
0143         return static_cast<wchar_t>(L'a' + (i-10));
0144     }
0145 }
0146 
0147 } // namespace detail
0148 
0149 template<class OutputIterator>
0150 OutputIterator to_chars(uuid const& u, OutputIterator out)
0151 {
0152     std::size_t i=0;
0153     for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
0154         const size_t hi = ((*it_data) >> 4) & 0x0F;
0155         *out++ = detail::to_char(hi);
0156 
0157         const size_t lo = (*it_data) & 0x0F;
0158         *out++ = detail::to_char(lo);
0159 
0160         if (i == 3 || i == 5 || i == 7 || i == 9) {
0161             *out++ = '-';
0162         }
0163     }
0164     return out;
0165 }
0166 
0167 inline bool to_chars(uuid const& u, char* first, char* last)
0168 {
0169     if (last - first < 36) {
0170         return false;
0171     }
0172     to_chars(u, first);
0173     return true;
0174 }
0175 
0176 inline std::string to_string(uuid const& u)
0177 {
0178     std::string result(36, char());
0179     // string::data() returns const char* before C++17
0180     to_chars(u, &result[0]);
0181     return result;
0182 }
0183 
0184 #ifndef BOOST_NO_STD_WSTRING
0185 inline std::wstring to_wstring(uuid const& u)
0186 {
0187     std::wstring result;
0188     result.reserve(36);
0189 
0190     std::size_t i=0;
0191     for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) {
0192         const size_t hi = ((*it_data) >> 4) & 0x0F;
0193         result += detail::to_wchar(hi);
0194 
0195         const size_t lo = (*it_data) & 0x0F;
0196         result += detail::to_wchar(lo);
0197 
0198         if (i == 3 || i == 5 || i == 7 || i == 9) {
0199             result += L'-';
0200         }
0201     }
0202     return result;
0203 }
0204 
0205 #endif
0206 
0207 }} //namespace boost::uuids
0208 
0209 #if defined(_MSC_VER)
0210 #pragma warning(pop) // Restore warnings to previous state.
0211 #endif
0212 
0213 #endif // BOOST_UUID_IO_HPP