lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
wcharcvt.h
00001 /*****************************************************/
00002 /* lean IO                      (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_IO_WCHARCVT
00006 #define LEAN_IO_WCHARCVT
00007 
00008 #include <locale>
00009 #include "../lean.h"
00010 #include "endianness.h"
00011 
00012 namespace lean
00013 {
00014 namespace io
00015 {
00016 
00018 class wcharcvt : public std::codecvt<wchar_t, char, mbstate_t>
00019 {
00020 public:
00022     explicit wcharcvt(size_t refs = 0)
00023         : codecvt(refs) { }
00024 
00025 protected:
00027     virtual result do_out(mbstate_t&,
00028         const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
00029         char* to, char* to_end, char*& to_next) const
00030     {
00031         byteswap_big(from, from_end, reinterpret_cast<wchar_t*>(to));
00032         from_next = from_end;
00033         to_next = to + (reinterpret_cast<const char*>(from_end) - reinterpret_cast<const char*>(from));
00034 
00035         return ok;
00036     }
00037 
00039     virtual result do_in(mbstate_t&,
00040         const char* from, const char* from_end, const char*& from_next,
00041         wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const
00042     {
00043         LEAN_STATIC_ASSERT_MSG_ALT(
00044             (sizeof(wchar_t) & (sizeof(wchar_t) - 1)) == 0,
00045             "Sizeof(wchar_t) is no power of two.",
00046             Sizeof_wchar_t_is_no_power_of_two);
00047 
00048         from_next = from + ((from_end - from) & ~(sizeof(wchar_t) - 1));
00049 
00050         byteswap_big(reinterpret_cast<const wchar_t*>(from), reinterpret_cast<const wchar_t*>(from_next), to);
00051         to_next = to + (reinterpret_cast<const wchar_t*>(from_next) - reinterpret_cast<const wchar_t*>(from));
00052 
00053         return (from_next != from_end) ? partial : ok;
00054     }
00055 
00057     virtual result do_unshift(mbstate_t&, char* to, char*, char*& to_next) const
00058     {
00059         to_next = to;
00060         return noconv;
00061     }
00062 
00064     virtual int do_length(mbstate_t&, const char* from, const char* end, size_t max) const
00065     {
00066         LEAN_STATIC_ASSERT_MSG_ALT(
00067             (sizeof(wchar_t) & (sizeof(wchar_t) - 1)) == 0,
00068             "Sizeof(wchar_t) is no power of two.",
00069             Sizeof_wchar_t_is_no_power_of_two);
00070 
00071         return static_cast<int>(
00072             min(static_cast<size_t>(end - from), max * sizeof(wchar_t)) & ~(sizeof(wchar_t) - 1) );
00073     }
00074 
00076     virtual int do_max_length() const throw()
00077     {
00078         return sizeof(wchar_t);
00079     }
00080 
00082     virtual bool do_always_noconv() const throw()
00083     {
00084         return false;
00085     }
00086 
00088     virtual int do_encoding() const throw()
00089     {
00090         return sizeof(wchar_t);
00091     }
00092 };
00093 
00094 } // namespace
00095 
00096 using io::wcharcvt;
00097 
00098 } // namespace
00099 
00100 #endif