Chris@16: // Boost uuid_io.hpp header file ----------------------------------------------// Chris@16: Chris@16: // Copyright 2009 Andy Tompkins. Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // Revision History Chris@16: // 20 Mar 2009 - Initial Revision Chris@16: // 28 Nov 2009 - disabled deprecated warnings for MSVC Chris@16: Chris@16: #ifndef BOOST_UUID_IO_HPP Chris@16: #define BOOST_UUID_IO_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma warning(push) // Save warning settings. Chris@16: #pragma warning(disable : 4996) // Disable deprecated std::ctype::widen, std::copy Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: namespace uuids { Chris@16: Chris@16: template Chris@16: std::basic_ostream& operator<<(std::basic_ostream &os, uuid const& u) Chris@16: { Chris@16: io::ios_flags_saver flags_saver(os); Chris@16: io::basic_ios_fill_saver fill_saver(os); Chris@16: Chris@16: const typename std::basic_ostream::sentry ok(os); Chris@16: if (ok) { Chris@16: const std::streamsize width = os.width(0); Chris@16: const std::streamsize uuid_width = 36; Chris@16: const std::ios_base::fmtflags flags = os.flags(); Chris@16: const typename std::basic_ios::char_type fill = os.fill(); Chris@16: if (flags & (std::ios_base::right | std::ios_base::internal)) { Chris@16: for (std::streamsize i=uuid_width; i(*i_data); Chris@16: if (i == 3 || i == 5 || i == 7 || i == 9) { Chris@16: os << os.widen('-'); Chris@16: } Chris@16: } Chris@16: Chris@16: if (flags & std::ios_base::left) { Chris@101: for (std::streamsize s=uuid_width; s Chris@16: std::basic_istream& operator>>(std::basic_istream &is, uuid &u) Chris@16: { Chris@16: const typename std::basic_istream::sentry ok(is); Chris@16: if (ok) { Chris@16: unsigned char data[16]; Chris@16: Chris@16: typedef std::ctype ctype_t; Chris@16: ctype_t const& ctype = std::use_facet(is.getloc()); Chris@16: Chris@16: ch xdigits[16]; Chris@16: { Chris@16: char szdigits[] = "0123456789ABCDEF"; Chris@16: ctype.widen(szdigits, szdigits+16, xdigits); Chris@16: } Chris@16: ch*const xdigits_end = xdigits+16; Chris@16: Chris@16: ch c; Chris@16: for (std::size_t i=0; i> c; Chris@16: c = ctype.toupper(c); Chris@16: Chris@16: ch* f = std::find(xdigits, xdigits_end, c); Chris@16: if (f == xdigits_end) { Chris@16: is.setstate(std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: Chris@16: unsigned char byte = static_cast(std::distance(&xdigits[0], f)); Chris@16: Chris@16: is >> c; Chris@16: c = ctype.toupper(c); Chris@16: f = std::find(xdigits, xdigits_end, c); Chris@16: if (f == xdigits_end) { Chris@16: is.setstate(std::ios_base::failbit); Chris@16: break; Chris@16: } Chris@16: Chris@16: byte <<= 4; Chris@16: byte |= static_cast(std::distance(&xdigits[0], f)); Chris@16: Chris@16: data[i] = byte; Chris@16: Chris@16: if (is) { Chris@16: if (i == 3 || i == 5 || i == 7 || i == 9) { Chris@16: is >> c; Chris@16: if (c != is.widen('-')) is.setstate(std::ios_base::failbit); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: if (is) { Chris@16: std::copy(data, data+16, u.begin()); Chris@16: } Chris@16: } Chris@16: return is; Chris@16: } Chris@16: Chris@16: namespace detail { Chris@16: inline char to_char(size_t i) { Chris@16: if (i <= 9) { Chris@16: return static_cast('0' + i); Chris@16: } else { Chris@16: return static_cast('a' + (i-10)); Chris@16: } Chris@16: } Chris@16: Chris@16: inline wchar_t to_wchar(size_t i) { Chris@16: if (i <= 9) { Chris@16: return static_cast(L'0' + i); Chris@16: } else { Chris@16: return static_cast(L'a' + (i-10)); Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace detail Chris@16: Chris@16: inline std::string to_string(uuid const& u) Chris@16: { Chris@16: std::string result; Chris@16: result.reserve(36); Chris@16: Chris@16: std::size_t i=0; Chris@16: for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) { Chris@16: const size_t hi = ((*it_data) >> 4) & 0x0F; Chris@16: result += detail::to_char(hi); Chris@16: Chris@16: const size_t lo = (*it_data) & 0x0F; Chris@16: result += detail::to_char(lo); Chris@16: Chris@16: if (i == 3 || i == 5 || i == 7 || i == 9) { Chris@16: result += '-'; Chris@16: } Chris@16: } Chris@16: return result; Chris@16: } Chris@16: Chris@16: #ifndef BOOST_NO_STD_WSTRING Chris@16: inline std::wstring to_wstring(uuid const& u) Chris@16: { Chris@16: std::wstring result; Chris@16: result.reserve(36); Chris@16: Chris@16: std::size_t i=0; Chris@16: for (uuid::const_iterator it_data = u.begin(); it_data!=u.end(); ++it_data, ++i) { Chris@16: const size_t hi = ((*it_data) >> 4) & 0x0F; Chris@16: result += detail::to_wchar(hi); Chris@16: Chris@16: const size_t lo = (*it_data) & 0x0F; Chris@16: result += detail::to_wchar(lo); Chris@16: Chris@16: if (i == 3 || i == 5 || i == 7 || i == 9) { Chris@16: result += L'-'; Chris@16: } Chris@16: } Chris@16: return result; Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: }} //namespace boost::uuids Chris@16: Chris@16: #if defined(_MSC_VER) Chris@16: #pragma warning(pop) // Restore warnings to previous state. Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_UUID_IO_HPP