1 /*
2 
3   character conversion (<-> unicode encodings)
4 
5   copyright (c) 2006 squell <squell@alumina.nl>
6 
7   use, modification, copying and distribution of this software is permitted
8   under the conditions described in the file 'COPYING'.
9 
10   Usage: see charconv.h
11 
12   Uses partial specialization to encode various characteristics.
13 
14   Issues: For some reason, Borland C++ doesn't like this
15 
16     charset::conv<char>("Hello").str<charset::ucs2>();
17 
18 */
19 
20 #ifndef __ZF_CHARCONV_UNICODE_HPP
21 #define __ZF_CHARCONV_UNICODE_HPP
22 
23 #include "charconv.h"
24 
25 namespace charset {
26 
27     enum byte_order { marked, little_endian, big_endian };
28 
29     template<byte_order = marked> class unicode;
30 
31     typedef unicode<marked>        utf16;
32     typedef unicode<little_endian> utf16le;
33     typedef unicode<big_endian>    utf16be;
34 
35     class conv_wide : public conv<> {
36     protected:
37         template<class T>
conv_wide(const T & s)38           conv_wide(const T& s) : conv<>(s) { }
conv_wide()39         conv_wide() { }
~conv_wide()40        ~conv_wide() { }
41         static conv<>::data decode(const char*, std::size_t, byte_order);
42         static std::string  encode(const void*, std::size_t, byte_order);
ucslen(const char * p)43         static std::size_t  ucslen(const char* p)
44         {
45             for(std::size_t len = 0; ; len += 2)
46                 if( (p[len]|p[len+1]) == 0 )
47                     return len;
48         }
49     };
50 
51     template<byte_order Order>
52       class conv< unicode<Order> > : public conv_wide {
53     public:
conv(const std::string & s)54         conv(const std::string& s)         : conv_wide(decode(s.data(), s.size(),Order)) { }
conv(const char * p,std::size_t l)55         conv(const char* p, std::size_t l) : conv_wide(decode(p,l,Order)) { }
conv(const char * p)56         conv(const char* p)                : conv_wide(decode(p,ucslen(p),Order)) { }
conv(const conv<> & other)57         conv(const conv<>& other)          : conv_wide(other) { }
conv(void)58         conv(void)                         : conv_wide() { }
59 
string()60         operator std::string() const
61         { return encode(internal.data(), internal.size()/cellsize, Order); }
62 
str()63         std::string str() const     { return *this; }
64 
65         template<class E>
66           std::basic_string<typename conv<E>::char_type>
str()67                    str()   const    { return conv<>::str<E>(); }
68 
69         typedef char char_type;
70     };
71 
72 }
73 
74 #endif
75 
76