]> git.tdb.fi Git - libs/core.git/blob - source/codec.h
Added reset function for StringCodec::Decoder
[libs/core.git] / source / codec.h
1 #ifndef MSP_STRINGS_CODEC_H_
2 #define MSP_STRINGS_CODEC_H_
3
4 #include <string>
5 #include <msp/error.h>
6
7 namespace Msp {
8
9 /**
10 An exception thrown for all kinds of problems encountered while encoding or
11 decoding strings.
12 */
13 class CodecError: public Exception
14 {
15 public:
16         CodecError(const std::string &w_): Exception(w_) { }
17 };
18
19 /**
20 Base class for string codecs.  Use one of the derived classes or the function
21 create_codec to create a specific codec.
22
23 For the purposes of this class, an std::wstring is considered to contain
24 Unicode characters and an std::string is considered to be an encoded sequence
25 of bytes.  A codec is able to determine if an encoded string could be decoded
26 with it.
27 */
28 class StringCodec
29 {
30 public:
31         /**
32         Base class for string encoder.  Each codec class should contain an Encoder
33         class derived from this.
34         */
35         class Encoder
36         {
37         public:
38                 /**
39                 Encodes a single character.  Derived classes should use the append
40                 function to put the result into the internal buffer.
41                 */
42                 virtual void encode_char(wchar_t) =0;
43
44                 /**
45                 Encodes a string.
46                 */
47                 virtual void encode(const std::wstring &s)
48                 { for(std::wstring::const_iterator i=s.begin(); i!=s.end(); ++i) encode_char(*i); }
49
50                 /**
51                 Brings the encoder back to its initial state.  This allows the encoded
52                 sequence to be extracted or flushed without loss of integrity.
53                 */
54                 virtual void sync() { }
55
56                 /**
57                 Returns a reference to the encoded sequence.  Call sync() first to make
58                 sure it's a valid encoded string by itself.
59                 */
60                 const std::string &get() const { return buffer_; }
61
62                 /**
63                 Returns the number of bytes in the output buffer.
64                 */
65                 unsigned size() const { return buffer_.size(); }
66
67                 /**
68                 Clears the encoded sequence.  Encoder state is left intact.
69                 */
70                 void flush() { buffer_.clear(); }
71
72                 virtual ~Encoder() { }
73         protected:
74                 Encoder() { }
75                 void append(char c) { buffer_+=c; }
76                 void append(const char *s, unsigned l) { buffer_.append(s, l); }
77                 void append(const std::string &s) { buffer_+=s; }
78         private:
79                 std::string buffer_;
80         };
81
82         /**
83         Base class for string decoder.  Each codec class should contain an Decoder
84         class derived from this.
85         */
86         class Decoder
87         {
88         public:
89                 virtual void decode_char(const std::string &, std::string::const_iterator &) =0;
90                 virtual void decode(const std::string &s)
91                 { for(std::string::const_iterator i=s.begin(); i!=s.end(); ) decode_char(s, i); }
92
93                 /**
94                 Ensures that all input has been processed.  If this is not the case any
95                 buffers are cleared and an exception is thrown,
96                 */
97                 virtual void sync() { }
98
99                 /**
100                 Resets the decoder, clearing a possibly erroneus state.  Does not flush
101                 the internal buffer.
102                 */
103                 virtual void reset() { }
104
105                 const std::wstring &get() const { return buffer_; }
106                 unsigned size() const { return buffer_.size(); }
107                 void flush() { buffer_.clear(); }
108                 virtual ~Decoder() { }
109         protected:
110                 Decoder() { }
111                 void append(wchar_t c) { buffer_+=c; }
112                 void append(const std::wstring &s) { buffer_+=s; }
113         private:
114                 std::wstring buffer_;
115         };
116
117         virtual Encoder *create_encoder() const =0;
118         virtual Decoder *create_decoder() const =0;
119         virtual bool    detect(const std::string &) const;
120         virtual ~StringCodec() { }
121 protected:
122         StringCodec() { }
123 };
124
125 /**
126 Convenience function that decodes a string using the given codec.
127 */
128 template<class C>
129 std::wstring decode(const std::string &s)
130 {
131         typename C::Decoder dec;
132         dec.decode(s);
133         dec.sync();
134         return dec.get();
135 }
136
137 template<class C>
138 std::string encode(const std::wstring &s)
139 {
140         typename C::Encoder enc;
141         enc.encode(s);
142         enc.sync();
143         return enc.get();
144 }
145
146 template<class F, class T>
147 std::string transcode(const std::string &s)
148 {
149         typename F::Decoder from;
150         typename T::Encoder to;
151         from.decode(s);
152         from.sync();
153         to.encode(from.get());
154         to.sync();
155         return to.get();
156 }
157
158 StringCodec *create_codec(const std::string &);
159
160 } // namespace Msp
161
162 #endif