// file : xsd/cxx/xml/string.txx // copyright : Copyright (c) 2005-2011 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #ifndef XSD_CXX_XML_STRING_TXX #define XSD_CXX_XML_STRING_TXX #endif // XSD_CXX_XML_STRING_TXX #if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR) #ifndef XSD_CXX_XML_STRING_TXX_WCHAR #define XSD_CXX_XML_STRING_TXX_WCHAR #include namespace xsd { namespace cxx { namespace xml { namespace bits { // wchar_transcoder (specialization for 2-byte wchar_t) // template std::basic_string wchar_transcoder:: to (const XMLCh* s, std::size_t length) { std::basic_string r; r.reserve (length + 1); r.resize (length); W* rs (const_cast (r.c_str ())); for (std::size_t i (0); i < length; ++s, ++i) { rs[i] = *s; } return r; } template XMLCh* wchar_transcoder:: from (const W* s, std::size_t length) { #ifdef XSD_CXX11 std::unique_ptr r ( #else auto_array r ( #endif new XMLCh[length + 1]); XMLCh* ir (r.get ()); for (std::size_t i (0); i < length; ++ir, ++i) { *ir = static_cast (s[i]); } *ir = XMLCh (0); return r.release (); } // wchar_transcoder (specialization for 4-byte wchar_t) // template std::basic_string wchar_transcoder:: to (const XMLCh* s, std::size_t length) { const XMLCh* end (s + length); // Find what the resulting buffer size will be. // std::size_t rl (0); for (const XMLCh* p (s); p < end; ++p) { rl++; if ((*p >= 0xD800) && (*p <= 0xDBFF)) { // Make sure we have one more char and it has a valid // value for the second char in a surrogate pair. // if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF))) throw invalid_utf16_string (); } } std::basic_string r; r.reserve (rl + 1); r.resize (rl); W* rs (const_cast (r.c_str ())); std::size_t i (0); for (const XMLCh* p (s); p < end; ++p) { XMLCh x (*p); if (x < 0xD800 || x > 0xDBFF) rs[i++] = W (x); else rs[i++] = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000; } return r; } template XMLCh* wchar_transcoder:: from (const W* s, std::size_t length) { // Find what the resulting buffer size will be. // std::size_t rl (0); for (const W* p (s); p < s + length; ++p) { rl += (*p & 0xFFFF0000) ? 2 : 1; } #ifdef XSD_CXX11 std::unique_ptr r ( #else auto_array r ( #endif new XMLCh[rl + 1]); XMLCh* ir (r.get ()); for (const W* p (s); p < s + length; ++p) { W w (*p); if (w & 0xFFFF0000) { // Surrogate pair. // *ir++ = static_cast (((w - 0x10000) >> 10) + 0xD800); *ir++ = static_cast ((w & 0x3FF) + 0xDC00); } else *ir++ = static_cast (w); } *ir = XMLCh (0); return r.release (); } } } } } #endif // XSD_CXX_XML_STRING_TXX_WCHAR #endif // XSD_USE_WCHAR