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 #include "vmime/stringContentHandler.hpp"
25 
26 #include "vmime/utility/inputStreamStringAdapter.hpp"
27 #include "vmime/utility/inputStreamStringProxyAdapter.hpp"
28 #include "vmime/utility/outputStreamAdapter.hpp"
29 
30 
31 namespace vmime
32 {
33 
34 
stringContentHandler()35 stringContentHandler::stringContentHandler()
36 {
37 }
38 
39 
stringContentHandler(const string & buffer,const vmime::encoding & enc)40 stringContentHandler::stringContentHandler(const string& buffer, const vmime::encoding& enc)
41 	: m_encoding(enc), m_string(buffer)
42 {
43 }
44 
45 
stringContentHandler(const stringContentHandler & cts)46 stringContentHandler::stringContentHandler(const stringContentHandler& cts)
47 	: contentHandler(), m_contentType(cts.m_contentType),
48 	  m_encoding(cts.m_encoding), m_string(cts.m_string)
49 {
50 }
51 
52 
stringContentHandler(const utility::stringProxy & str,const vmime::encoding & enc)53 stringContentHandler::stringContentHandler(const utility::stringProxy& str, const vmime::encoding& enc)
54 	: m_encoding(enc), m_string(str)
55 {
56 }
57 
58 
stringContentHandler(const string & buffer,const size_t start,const size_t end,const vmime::encoding & enc)59 stringContentHandler::stringContentHandler(const string& buffer, const size_t start,
60 	const size_t end, const vmime::encoding& enc)
61 	: m_encoding(enc), m_string(buffer, start, end)
62 {
63 }
64 
65 
~stringContentHandler()66 stringContentHandler::~stringContentHandler()
67 {
68 }
69 
70 
clone() const71 shared_ptr <contentHandler> stringContentHandler::clone() const
72 {
73 	return make_shared <stringContentHandler>(*this);
74 }
75 
76 
operator =(const stringContentHandler & cts)77 stringContentHandler& stringContentHandler::operator=(const stringContentHandler& cts)
78 {
79 	m_contentType = cts.m_contentType;
80 	m_encoding = cts.m_encoding;
81 	m_string = cts.m_string;
82 
83 	return (*this);
84 }
85 
86 
setData(const utility::stringProxy & str,const vmime::encoding & enc)87 void stringContentHandler::setData(const utility::stringProxy& str, const vmime::encoding& enc)
88 {
89 	m_encoding = enc;
90 	m_string = str;
91 }
92 
93 
setData(const string & buffer,const vmime::encoding & enc)94 void stringContentHandler::setData(const string& buffer, const vmime::encoding& enc)
95 {
96 	m_encoding = enc;
97 	m_string.set(buffer);
98 }
99 
100 
setData(const string & buffer,const size_t start,const size_t end,const vmime::encoding & enc)101 void stringContentHandler::setData(const string& buffer, const size_t start,
102 	const size_t end, const vmime::encoding& enc)
103 {
104 	m_encoding = enc;
105 	m_string.set(buffer, start, end);
106 }
107 
108 
operator =(const string & buffer)109 stringContentHandler& stringContentHandler::operator=(const string& buffer)
110 {
111 	setData(buffer, NO_ENCODING);
112 	return (*this);
113 }
114 
115 
generate(utility::outputStream & os,const vmime::encoding & enc,const size_t maxLineLength) const116 void stringContentHandler::generate(utility::outputStream& os,
117 	const vmime::encoding& enc, const size_t maxLineLength) const
118 {
119 	// Managed data is already encoded
120 	if (isEncoded())
121 	{
122 		// The data is already encoded but the encoding specified for
123 		// the generation is different from the current one. We need
124 		// to re-encode data: decode from input buffer to temporary
125 		// buffer, and then re-encode to output stream...
126 		if (m_encoding != enc)
127 		{
128 			shared_ptr <utility::encoder::encoder> theDecoder = m_encoding.getEncoder();
129 			shared_ptr <utility::encoder::encoder> theEncoder = enc.getEncoder();
130 
131 			theEncoder->getProperties()["maxlinelength"] = maxLineLength;
132 			theEncoder->getProperties()["text"] = (m_contentType.getType() == mediaTypes::TEXT);
133 
134 			utility::inputStreamStringProxyAdapter in(m_string);
135 
136 			std::ostringstream oss;
137 			utility::outputStreamAdapter tempOut(oss);
138 
139 			theDecoder->decode(in, tempOut);
140 
141 			string str = oss.str();
142 			utility::inputStreamStringAdapter tempIn(str);
143 
144 			theEncoder->encode(tempIn, os);
145 		}
146 		// No encoding to perform
147 		else
148 		{
149 			m_string.extract(os);
150 		}
151 	}
152 	// Need to encode data before
153 	else
154 	{
155 		shared_ptr <utility::encoder::encoder> theEncoder = enc.getEncoder();
156 		theEncoder->getProperties()["maxlinelength"] = maxLineLength;
157 		theEncoder->getProperties()["text"] = (m_contentType.getType() == mediaTypes::TEXT);
158 
159 		utility::inputStreamStringProxyAdapter in(m_string);
160 
161 		theEncoder->encode(in, os);
162 	}
163 }
164 
165 
extract(utility::outputStream & os,utility::progressListener * progress) const166 void stringContentHandler::extract(utility::outputStream& os,
167 	utility::progressListener* progress) const
168 {
169 	// No decoding to perform
170 	if (!isEncoded())
171 	{
172 		m_string.extract(os, 0, m_string.length(), progress);
173 	}
174 	// Need to decode data
175 	else
176 	{
177 		shared_ptr <utility::encoder::encoder> theDecoder = m_encoding.getEncoder();
178 
179 		utility::inputStreamStringProxyAdapter in(m_string);
180 		utility::progressListenerSizeAdapter plsa(progress, getLength());
181 
182 		theDecoder->decode(in, os, &plsa);
183 	}
184 }
185 
186 
extractRaw(utility::outputStream & os,utility::progressListener * progress) const187 void stringContentHandler::extractRaw(utility::outputStream& os,
188 	utility::progressListener* progress) const
189 {
190 	m_string.extract(os, 0, m_string.length(), progress);
191 }
192 
193 
getLength() const194 size_t stringContentHandler::getLength() const
195 {
196 	return (m_string.length());
197 }
198 
199 
isEmpty() const200 bool stringContentHandler::isEmpty() const
201 {
202 	return (m_string.length() == 0);
203 }
204 
205 
isEncoded() const206 bool stringContentHandler::isEncoded() const
207 {
208 	return (m_encoding != NO_ENCODING);
209 }
210 
211 
getEncoding() const212 const vmime::encoding& stringContentHandler::getEncoding() const
213 {
214 	return (m_encoding);
215 }
216 
217 
isBuffered() const218 bool stringContentHandler::isBuffered() const
219 {
220 	return true;
221 }
222 
223 
setContentTypeHint(const mediaType & type)224 void stringContentHandler::setContentTypeHint(const mediaType& type)
225 {
226 	m_contentType = type;
227 }
228 
229 
getContentTypeHint() const230 const mediaType stringContentHandler::getContentTypeHint() const
231 {
232 	return m_contentType;
233 }
234 
235 
236 } // vmime
237