]> git.tdb.fi Git - libs/core.git/blob - source/codec.h
Rework the codec API completely to remove the internal buffering
[libs/core.git] / source / codec.h
1 /* $Id$
2
3 This file is part of libmspstrings
4 Copyright © 2006-2007 Mikko Rasa
5 Distributed under the LGPL
6 */
7
8 #ifndef MSP_STRINGS_CODEC_H_
9 #define MSP_STRINGS_CODEC_H_
10
11 #include <string>
12 #include <msp/core/error.h>
13
14 namespace Msp {
15 namespace Codecs {
16
17 typedef int UnicodeChar;
18
19 typedef std::basic_string<UnicodeChar> ustring;
20
21 enum ErrorMode
22 {
23         THROW_ON_ERROR,
24         IGNORE_ERRORS,
25         TRANSLITERATE
26 };
27
28 /**
29 An exception thrown for all kinds of problems encountered while encoding or
30 decoding strings.
31 */
32 class CodecError: public Exception
33 {
34 public:
35         CodecError(const std::string &w_): Exception(w_) { }
36 };
37
38 /**
39 Base class for string codecs.  Use one of the derived classes or the function
40 create_codec to create a specific codec.
41
42 For the purposes of this class, an ustring is considered to contain
43 Unicode characters and an std::string is considered to be an encoded sequence
44 of bytes.  A codec is able to determine if an encoded string could be decoded
45 with it.
46 */
47 class Codec
48 {
49 public:
50         /**
51         Base class for string encoder.  Each codec class should contain an Encoder
52         class derived from this.
53         */
54         class Encoder
55         {
56         public:
57                 virtual ~Encoder() { }
58
59                 virtual void encode_char(UnicodeChar ch, std::string &buf) =0;
60                 virtual void encode(const ustring &str, std::string &buf);
61                 virtual void sync(std::string &buf) { (void)buf; }
62                 virtual void reset() { }
63         protected:
64                 ErrorMode err_mode;
65
66                 Encoder(ErrorMode em): err_mode(em) { }
67                 void error(UnicodeChar, std::string &, const std::string &);
68                 virtual void transliterate(UnicodeChar, std::string &) { }
69         };
70
71         /**
72         Base class for string decoder.  Each codec class should contain an Decoder
73         class derived from this.
74         */
75         class Decoder
76         {
77         public:
78                 virtual ~Decoder() { }
79
80                 /**
81                 Decodes a single character from a string.  The iterator is advanced to
82                 the next character.  For stateful codecs, -1 may be returned if a state
83                 change sequence was decoded but no character followed it.  In case a
84                 decoding error occurs, behavior depends on the error mode specified for
85                 the decoder:
86
87                 For THROW_ON_ERROR, an exception is thrown and the iterator is left at
88                 the erroneous character.
89
90                 For IGNORE_ERRORS, -1 is returned and the iterator is advanced.
91
92                 For TRANSLITERATE, 0xFFFE is returned and the iterator is advanced.
93                 */
94                 virtual UnicodeChar decode_char(const std::string &str, std::string::const_iterator &i) =0;
95
96                 virtual void decode(const std::string &str, ustring &buf);
97                 virtual void reset() { }
98         protected:
99                 ErrorMode err_mode;
100
101                 Decoder(ErrorMode em): err_mode(em) { }
102                 UnicodeChar error(const std::string &);
103         };
104
105         virtual ~Codec() { }
106
107         /**
108         Creates an encoder for this codec.
109         */
110         virtual Encoder *create_encoder(ErrorMode err_mode=THROW_ON_ERROR) const =0;
111
112         /**
113         Creates a decoder for this codec.
114         */
115         virtual Decoder *create_decoder(ErrorMode err_mode=THROW_ON_ERROR) const =0;
116
117         /**
118         Determines whether the given string can be successfully decoded with this
119         codec.  Note that this function returning true does not guarantee that the
120         string was actually encoded with this codec.  In particular, many 8-bit
121         encodings are indistinguishable.
122         */
123         virtual bool detect(const std::string &) const;
124 protected:
125         Codec() { }
126 };
127
128 typedef Codec::Encoder Encoder;
129 typedef Codec::Decoder Decoder;
130
131 /**
132 Convenience function that decodes a string using the given codec.
133 */
134 template<class C>
135 ustring decode(const std::string &s)
136 {
137         typename C::Decoder dec;
138         ustring result;
139         dec.decode(s, result);
140         return result;
141 }
142
143 template<class C>
144 std::string encode(const ustring &s)
145 {
146         typename C::Encoder enc;
147         std::string result;
148         enc.encode(s, result);
149         enc.sync(result);
150         return result;
151 }
152
153 template<class F, class T>
154 std::string transcode(const std::string &s)
155 {
156         typename F::Decoder from;
157         typename T::Encoder to;
158         ustring temp;
159         from.decode(s, temp);
160         std::string result;
161         to.encode(temp, result);
162         to.sync(result);
163         return result;
164 }
165
166 /**
167 Creates a codec for an encoding by name.  The caller is responsible for
168 deleting the codec when it's no longer needed.
169 */
170 Codec *create_codec(const std::string &);
171
172 } // namespace Codecs
173 } // namespace Msp
174
175 #endif