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