]> git.tdb.fi Git - libs/core.git/blob - source/codec.h
Corrected style errors
[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.  An exception is thrown if
95                 this is not the case.
96                 */
97                 virtual void sync() { }
98
99                 const std::wstring &get() const { return buffer_; }
100                 unsigned size() const { return buffer_.size(); }
101                 void flush() { buffer_.clear(); }
102                 virtual ~Decoder() { }
103         protected:
104                 Decoder() { }
105                 void append(wchar_t c) { buffer_+=c; }
106                 void append(const std::wstring &s) { buffer_+=s; }
107         private:
108                 std::wstring buffer_;
109         };
110
111         virtual Encoder *create_encoder() const =0;
112         virtual Decoder *create_decoder() const =0;
113         virtual bool    detect(const std::string &) const;
114         virtual ~StringCodec() { }
115 protected:
116         StringCodec() { }
117 };
118
119 /**
120 Convenience function that decodes a string using the given codec.
121 */
122 template<class C>
123 std::wstring decode(const std::string &s)
124 {
125         typename C::Decoder dec;
126         dec.decode(s);
127         dec.sync();
128         return dec.get();
129 }
130
131 template<class C>
132 std::string encode(const std::wstring &s)
133 {
134         typename C::Encoder enc;
135         enc.encode(s);
136         enc.sync();
137         return enc.get();
138 }
139
140 template<class F, class T>
141 std::string transcode(const std::string &s)
142 {
143         typename F::Decoder from;
144         typename T::Encoder to;
145         from.decode(s);
146         from.sync();
147         to.encode(from.get());
148         to.sync();
149         return to.get();
150 }
151
152 StringCodec *create_codec(const std::string &);
153
154 } // namespace Msp
155
156 #endif