1 //
2 // VMime library (http://www.vmime.org)
3 // Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 3 of
8 // the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License along
16 // with this program; if not, write to the Free Software Foundation, Inc.,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // Linking this library statically or dynamically with other modules is making
20 // a combined work based on this library.  Thus, the terms and conditions of
21 // the GNU General Public License cover the whole combination.
22 //
23 
24 #ifndef VMIME_WORD_HPP_INCLUDED
25 #define VMIME_WORD_HPP_INCLUDED
26 
27 
28 #include "vmime/headerFieldValue.hpp"
29 #include "vmime/charset.hpp"
30 #include "vmime/charsetConverterOptions.hpp"
31 
32 
33 namespace vmime
34 {
35 
36 
37 /** A class that encapsulates an encoded-word (RFC-2047):
38   * some text encoded into one specified charset.
39   */
40 
41 class VMIME_EXPORT word : public headerFieldValue
42 {
43 	friend class text;
44 
45 public:
46 
47 	/** Construct an empty word.
48 	  * Charset is set to the current locale charset.
49 	  */
50 	word();
51 
52 	/** Construct a word by copying another word.
53 	  */
54 	word(const word& w);
55 
56 	/** Construct a word using a string buffer.
57 	  * Charset is set to the current locale charset.
58 	  */
59 	explicit word(const string& buffer);
60 
61 	/** Construct a word using a string buffer and a specified charset.
62 	  *
63 	  * @param buffer string buffer
64 	  * @param charset charset in which the string is encoded
65 	  */
66 	word(const string& buffer, const charset& charset);
67 
68 	/** Construct a word using a string buffer and a specified charset
69 	  * and language tag (RFC-1766).
70 	  *
71 	  * @param buffer string buffer
72 	  * @param charset charset in which the string is encoded
73 	  * @param lang language tag, in the format specified by RFC-1766
74 	  */
75 	word(const string& buffer, const charset& charset, const string& lang);
76 
77 	/** Return the raw data for this encoded word.
78 	  *
79 	  * @return raw data buffer
80 	  */
81 	const string& getBuffer() const;
82 
83 	/** Return the raw data for this encoded word.
84 	  *
85 	  * @return raw data buffer
86 	  */
87 	string& getBuffer();
88 
89 	/** Tests whether this word is empty.
90 	  *
91 	  * @return true if the buffer is empty, false otherwise
92 	  */
93 	bool isEmpty() const;
94 
95 	/** Set the raw data for this encoded word.
96 	  *
97 	  * @param buffer raw data buffer
98 	  */
99 	void setBuffer(const string& buffer);
100 
101 	/** Return the charset of this word.
102 	  *
103 	  * @return charset for this word
104 	  */
105 	const charset& getCharset() const;
106 
107 	/** Set the charset of this word.
108 	  *
109 	  * @param ch charset of this word
110 	  */
111 	void setCharset(const charset& ch);
112 
113 	/** Return the language used in this word (optional).
114 	  * If not specified, the value is empty.
115 	  *
116 	  * @return language tag for this word, in the format specified
117 	  * by RFC-1766
118 	  */
119 	const string getLanguage() const;
120 
121 	/** Set the language used in this word (optional).
122 	  *
123 	  * @param lang language tag, in the format specified by RFC-1766
124 	  */
125 	void setLanguage(const string& lang);
126 
127 	/** Returns whether two words actually represent the same text,
128 	  * regardless of their charset.
129 	  *
130 	  * @param other word to compare to
131 	  * @return true if the two words represent the same text, or false otherwise
132 	  */
133 	bool isEquivalent(const word& other) const;
134 
135 
136 	word& operator=(const word& w);
137 	word& operator=(const string& s);
138 
139 	bool operator==(const word& w) const;
140 	bool operator!=(const word& w) const;
141 
142 	/** Return the contained text converted to the specified charset.
143 	  *
144 	  * @param dest output charset
145 	  * @param opts options for charset conversion
146 	  * @return word converted to the specified charset
147 	  */
148 	const string getConvertedText(const charset& dest,
149 		const charsetConverterOptions& opts = charsetConverterOptions()) const;
150 
151 	/** Replace data in this word by data in other word.
152 	  *
153 	  * @param other other word to copy data from
154 	  */
155 	void copyFrom(const component& other);
156 
157 	/** Clone this word.
158 	  *
159 	  * @return a copy of this word
160 	  */
161 	shared_ptr <component> clone() const;
162 
163 
164 #ifndef VMIME_BUILDING_DOC
165 	class generatorState
166 	{
167 	public:
168 
generatorState()169 		generatorState()
170 			: isFirstWord(true), prevWordIsEncoded(false), lastCharIsSpace(false)
171 		{
172 		}
173 
174 		bool isFirstWord;
175 		bool prevWordIsEncoded;
176 		bool lastCharIsSpace;
177 	};
178 
179 	class parserState
180 	{
181 	public:
182 
parserState()183 		parserState()
184 			: prevIsEncoded(false), isFirst(true)
185 		{
186 		}
187 
188 		bool prevIsEncoded;
189 		bool isFirst;
190 		std::string undecodedBytes;
191 	};
192 #endif
193 
194 
195 protected:
196 
197 	void parseImpl
198 		(const parsingContext& ctx,
199 		 const string& buffer,
200 		 const size_t position,
201 		 const size_t end,
202 		 size_t* newPosition = NULL);
203 
204 	void generateImpl
205 		(const generationContext& ctx,
206 		 utility::outputStream& os,
207 		 const size_t curLinePos = 0,
208 		 size_t* newLinePos = NULL) const;
209 
210 	void parseWithState
211 		(const parsingContext& ctx,
212 		 const string& buffer,
213 		 const size_t position,
214 		 const size_t end,
215 		 size_t* newPosition,
216 		 parserState* state);
217 
218 public:
219 
220 	using component::generate;
221 
222 #ifndef VMIME_BUILDING_DOC
223 	void generate
224 		(const generationContext& ctx,
225 		 utility::outputStream& os,
226 		 const size_t curLinePos,
227 		 size_t* newLinePos,
228 		 const int flags,
229 		 generatorState* state) const;
230 #endif
231 
232 	const std::vector <shared_ptr <component> > getChildComponents();
233 
234 private:
235 
236 	static shared_ptr <word> parseNext
237 		(const parsingContext& ctx,
238 		 const string& buffer,
239 		 const size_t position,
240 		 const size_t end,
241 		 size_t* newPosition,
242 		 parserState* state);
243 
244 	static const std::vector <shared_ptr <word> > parseMultiple
245 		(const parsingContext& ctx,
246 		 const string& buffer,
247 		 const size_t position,
248 		 const size_t end,
249 		 size_t* newPosition);
250 
251 
252 	// The "m_buffer" of this word holds the data, and this data is encoded
253 	// in the specified "m_charset".
254 	string m_buffer;
255 	charset m_charset;
256 	string m_lang;
257 };
258 
259 
260 } // vmime
261 
262 
263 #endif // VMIME_WORD_HPP_INCLUDED
264