1 | /* |
2 | SPDX-FileCopyrightText: 2000-2001 Dawit Alemayehu <adawit@kde.org> |
3 | SPDX-FileCopyrightText: 2001 Rik Hemsley (rikkus) <rik@kde.org> |
4 | SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-only |
7 | |
8 | The quoted-printable codec as described in RFC 2045, section 6.7. is by |
9 | Rik Hemsley (C) 2001. |
10 | */ |
11 | |
12 | #ifndef KCODECS_H |
13 | #define KCODECS_H |
14 | |
15 | #include <kcodecs_export.h> |
16 | |
17 | #include <QString> |
18 | |
19 | #include <memory> |
20 | |
21 | class QByteArray; |
22 | class QIODevice; |
23 | |
24 | /** |
25 | * A wrapper class for the most commonly used encoding and |
26 | * decoding algorithms. Currently there is support for encoding |
27 | * and decoding input using base64, uu and the quoted-printable |
28 | * specifications. |
29 | * |
30 | * \b Usage: |
31 | * |
32 | * \code |
33 | * QByteArray input = "Aladdin:open sesame"; |
34 | * QByteArray result = KCodecs::base64Encode(input); |
35 | * cout << "Result: " << result.data() << endl; |
36 | * \endcode |
37 | * |
38 | * <pre> |
39 | * Output should be |
40 | * Result: QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
41 | * </pre> |
42 | * |
43 | * The above example makes use of the convenience functions |
44 | * (ones that accept/return null-terminated strings) to encode/decode |
45 | * a string. If what you need is to encode or decode binary data, then |
46 | * it is highly recommended that you use the functions that take an input |
47 | * and output QByteArray as arguments. These functions are specifically |
48 | * tailored for encoding and decoding binary data. |
49 | * |
50 | * @short A collection of commonly used encoding and decoding algorithms. |
51 | * @author Dawit Alemayehu <adawit@kde.org> |
52 | * @author Rik Hemsley <rik@kde.org> |
53 | */ |
54 | namespace KCodecs |
55 | { |
56 | /** |
57 | * Encodes the given data using the quoted-printable algorithm. |
58 | * |
59 | * @param in data to be encoded. |
60 | * @param useCRLF if true the input data is expected to have |
61 | * CRLF line breaks and the output will have CRLF line |
62 | * breaks, too. |
63 | * @return quoted-printable encoded string. |
64 | */ |
65 | KCODECS_EXPORT QByteArray quotedPrintableEncode(QByteArrayView in, bool useCRLF = true); |
66 | |
67 | /** |
68 | * Encodes the given data using the quoted-printable algorithm. |
69 | * |
70 | * Use this function if you want the result of the encoding |
71 | * to be placed in another array which cuts down the number |
72 | * of copy operation that have to be performed in the process. |
73 | * This is also the preferred method for encoding binary data. |
74 | * |
75 | * NOTE: the output array is first reset and then resized |
76 | * appropriately before use, hence, all data stored in the |
77 | * output array will be lost. |
78 | * |
79 | * @param in data to be encoded. |
80 | * @param out encoded data. |
81 | * @param useCRLF if true the input data is expected to have |
82 | * CRLF line breaks and the output will have CRLF line |
83 | * breaks, too. |
84 | */ |
85 | KCODECS_EXPORT void quotedPrintableEncode(QByteArrayView in, QByteArray &out, bool useCRLF); |
86 | |
87 | /** |
88 | * Decodes a quoted-printable encoded data. |
89 | * |
90 | * Accepts data with CRLF or standard unix line breaks. |
91 | * |
92 | * @param in data to be decoded. |
93 | * @return decoded string. |
94 | * @since 5.5 |
95 | */ |
96 | KCODECS_EXPORT QByteArray quotedPrintableDecode(QByteArrayView in); |
97 | |
98 | /** |
99 | * Decodes a quoted-printable encoded data. |
100 | * |
101 | * Accepts data with CRLF or standard unix line breaks. |
102 | * Use this function if you want the result of the decoding |
103 | * to be placed in another array which cuts down the number |
104 | * of copy operation that have to be performed in the process. |
105 | * This is also the preferred method for decoding an encoded |
106 | * binary data. |
107 | * |
108 | * NOTE: the output array is first reset and then resized |
109 | * appropriately before use, hence, all data stored in the |
110 | * output array will be lost. |
111 | * |
112 | * @param in data to be decoded. |
113 | * @param out decoded data. |
114 | */ |
115 | KCODECS_EXPORT void quotedPrintableDecode(QByteArrayView in, QByteArray &out); |
116 | |
117 | /** |
118 | * Decodes the given data using the uudecode algorithm. |
119 | * |
120 | * Any 'begin' and 'end' lines like those generated by |
121 | * the utilities in unix and unix-like OS will be |
122 | * automatically ignored. |
123 | * |
124 | * @param in data to be decoded. |
125 | * @return decoded string. |
126 | */ |
127 | KCODECS_EXPORT QByteArray uudecode(QByteArrayView in); |
128 | |
129 | /** |
130 | * Decodes the given data using the uudecode algorithm. |
131 | * |
132 | * Use this function if you want the result of the decoding |
133 | * to be placed in another array which cuts down the number |
134 | * of copy operation that have to be performed in the process. |
135 | * This is the preferred method for decoding binary data. |
136 | * |
137 | * Any 'begin' and 'end' lines like those generated by |
138 | * the utilities in unix and unix-like OS will be |
139 | * automatically ignored. |
140 | * |
141 | * NOTE: the output array is first reset and then resized |
142 | * appropriately before use, hence, all data stored in the |
143 | * output array will be lost. |
144 | * |
145 | * @param in data to be decoded. |
146 | * @param out uudecoded data. |
147 | */ |
148 | KCODECS_EXPORT void uudecode(QByteArrayView in, QByteArray &out); |
149 | |
150 | /** |
151 | * Encodes the given data using the base64 algorithm. |
152 | * |
153 | * The boolean argument determines if the encoded data is |
154 | * going to be restricted to 76 characters or less per line |
155 | * as specified by RFC 2045. If @p insertLFs is true, then |
156 | * there will be 76 characters or less per line. |
157 | * |
158 | * @param in data to be encoded. |
159 | * @param insertLFs limit the number of characters per line. |
160 | * |
161 | * @return base64 encoded string. |
162 | * @since 5.5 |
163 | */ |
164 | KCODECS_EXPORT QByteArray base64Encode(QByteArrayView in); |
165 | |
166 | /** |
167 | * Encodes the given data using the base64 algorithm. |
168 | * |
169 | * Use this function if you want the result of the encoding |
170 | * to be placed in another array which cuts down the number |
171 | * of copy operation that have to be performed in the process. |
172 | * This is also the preferred method for encoding binary data. |
173 | * |
174 | * The boolean argument determines if the encoded data is going |
175 | * to be restricted to 76 characters or less per line as specified |
176 | * by RFC 2045. If @p insertLFs is true, then there will be 76 |
177 | * characters or less per line. |
178 | * |
179 | * NOTE: the output array is first reset and then resized |
180 | * appropriately before use, hence, all data stored in the |
181 | * output array will be lost. |
182 | * |
183 | * @param in data to be encoded. |
184 | * @param out encoded data. |
185 | * @param insertLFs limit the number of characters per line. |
186 | */ |
187 | KCODECS_EXPORT void base64Encode(QByteArrayView in, QByteArray &out, bool insertLFs = false); |
188 | |
189 | /** |
190 | * Decodes the given data that was encoded using the |
191 | * base64 algorithm. |
192 | * |
193 | * @param in data to be decoded. |
194 | * @return decoded string. |
195 | */ |
196 | KCODECS_EXPORT QByteArray base64Decode(QByteArrayView in); |
197 | |
198 | /** |
199 | * Decodes the given data that was encoded with the base64 |
200 | * algorithm. |
201 | * |
202 | * Use this function if you want the result of the decoding |
203 | * to be placed in another array which cuts down the number |
204 | * of copy operation that have to be performed in the process. |
205 | * This is also the preferred method for decoding an encoded |
206 | * binary data. |
207 | * |
208 | * NOTE: the output array is first reset and then resized |
209 | * appropriately before use, hence, all data stored in the |
210 | * output array will be lost. |
211 | * |
212 | * @param in data to be decoded. |
213 | * @param out decoded data. |
214 | */ |
215 | KCODECS_EXPORT void base64Decode(QByteArrayView in, QByteArray &out); |
216 | |
217 | /** |
218 | * Decodes string @p text according to RFC2047, |
219 | * i.e., the construct =?charset?[qb]?encoded?= |
220 | * |
221 | * @param text source string |
222 | * @returns the decoded string |
223 | */ |
224 | KCODECS_EXPORT QString decodeRFC2047String(QStringView text); |
225 | |
226 | /** |
227 | * Charset options for RFC2047 encoder |
228 | * @since 5.5 |
229 | */ |
230 | enum CharsetOption { |
231 | NoOption = 0, /// No special option |
232 | ForceDefaultCharset = 1, /// Force use of the default charset |
233 | }; |
234 | |
235 | /** |
236 | * Decodes string @p src according to RFC2047, i.e. the construct |
237 | * =?charset?[qb]?encoded?= |
238 | * |
239 | * @param src source string. |
240 | * @param usedCS the name of any detected charset or, in case of multiple |
241 | * different ones, "UTF-8" as that of a super charset is |
242 | * returned here |
243 | * @param defaultCS the charset to use in case the detected |
244 | * one isn't known to us. |
245 | * @param option options for the encoder |
246 | * |
247 | * @return the decoded string. |
248 | * @since 5.5 |
249 | */ |
250 | KCODECS_EXPORT QString decodeRFC2047String(QByteArrayView src, QByteArray *usedCS, const QByteArray &defaultCS = QByteArray(), CharsetOption option = NoOption); |
251 | |
252 | /** |
253 | * Encodes string @p src according to RFC2047 using charset @p charset. |
254 | * |
255 | * This function also makes commas, quotes and other characters part of the encoded name, for example |
256 | * the string "Jöhn Döe" <john@example.com"> would be encoded as <encoded word for "Jöhn Döe"> <john@example.com>, |
257 | * i.e. the opening and closing quote mark would be part of the encoded word. |
258 | * Therefore don't use this function for input strings that contain semantically meaningful characters, |
259 | * like the quoting marks in this example. |
260 | * |
261 | * @param src source string. |
262 | * @param charset charset to use. If it can't encode the string, UTF-8 will be used instead. |
263 | * @return the encoded string. |
264 | * @since 5.5 |
265 | */ |
266 | KCODECS_EXPORT QByteArray encodeRFC2047String(QStringView src, const QByteArray &charset); |
267 | |
268 | /** |
269 | * Decodes the given data that was encoded using the |
270 | * base45 codec. |
271 | * |
272 | * @param in data to be decoded. |
273 | * @return decoded string. |
274 | * @since 5.84 |
275 | * @see https://datatracker.ietf.org/doc/draft-faltstrom-base45/ |
276 | */ |
277 | KCODECS_EXPORT QByteArray base45Decode(QByteArrayView in); |
278 | |
279 | class Encoder; |
280 | class EncoderPrivate; |
281 | class Decoder; |
282 | class DecoderPrivate; |
283 | |
284 | /** |
285 | @class KCodecs::Codec kcodecs.h KCodecs |
286 | |
287 | @glossary @anchor MIME @anchor mime @b MIME: |
288 | <b>Multipurpose Internet Mail Extensions</b> or @acronym MIME is an |
289 | Internet Standard that extends the format of e-mail to support text in |
290 | character sets other than US-ASCII, non-text attachments, multi-part message |
291 | bodies, and header information in non-ASCII character sets. Virtually all |
292 | human-written Internet e-mail and a fairly large proportion of automated |
293 | e-mail is transmitted via @acronym SMTP in MIME format. Internet e-mail is |
294 | so closely associated with the SMTP and MIME standards that it is sometimes |
295 | called SMTP/MIME e-mail. The content types defined by MIME standards are |
296 | also of growing importance outside of e-mail, such as in communication |
297 | protocols like @acronym HTTP for the World Wide Web. MIME is also a |
298 | fundamental component of communication protocols such as HTTP, which |
299 | requires that data be transmitted in the context of e-mail-like messages, |
300 | even though the data may not actually be e-mail. |
301 | |
302 | @glossary @anchor codec @anchor codecs @anchor Codec @anchor Codecs @b codec: |
303 | a program capable of performing encoding and decoding on a digital data |
304 | stream. Codecs encode data for storage or encryption and decode it for |
305 | viewing or editing. |
306 | |
307 | @glossary @anchor CRLF @b CRLF: a "Carriage Return (0x0D)" followed by a |
308 | "Line Feed (0x0A)", two ASCII control characters used to represent a |
309 | newline on some operating systems, notably DOS and Microsoft Windows. |
310 | |
311 | @glossary @anchor LF @b LF: a "Line Feed (0x0A)" ASCII control character used |
312 | to represent a newline on some operating systems, notably Unix, Unix-like, |
313 | and Linux. |
314 | |
315 | @brief An abstract base class of @ref codecs for common mail transfer encodings. |
316 | |
317 | Provides an abstract base class of @ref codecs like base64 and quoted-printable. |
318 | Implemented as a singleton. |
319 | |
320 | @authors Marc Mutz \<mutz@kde.org\> |
321 | @since 5.5 |
322 | */ |
323 | class KCODECS_EXPORT Codec |
324 | { |
325 | public: |
326 | enum NewlineType { |
327 | NewlineLF, |
328 | NewlineCRLF, |
329 | }; |
330 | |
331 | /** |
332 | Returns a codec associated with the specified @p name. |
333 | |
334 | @param name is a valid codec name. |
335 | */ |
336 | static Codec *codecForName(QByteArrayView name); |
337 | |
338 | /** |
339 | Computes the maximum size, in characters, needed for the encoding. |
340 | |
341 | @param insize is the number of input characters to be encoded. |
342 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
343 | |
344 | @return the maximum number of characters in the encoding. |
345 | */ |
346 | virtual qsizetype maxEncodedSizeFor(qsizetype insize, NewlineType newline = NewlineLF) const = 0; |
347 | |
348 | /** |
349 | Computes the maximum size, in characters, needed for the deccoding. |
350 | |
351 | @param insize is the number of input characters to be decoded. |
352 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
353 | |
354 | @return the maximum number of characters in the decoding. |
355 | */ |
356 | virtual qsizetype maxDecodedSizeFor(qsizetype insize, NewlineType newline = NewlineLF) const = 0; |
357 | |
358 | /** |
359 | Creates the encoder for the codec. |
360 | |
361 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
362 | |
363 | @return a pointer to an instance of the codec's encoder. |
364 | */ |
365 | virtual Encoder *makeEncoder(NewlineType newline = NewlineLF) const = 0; |
366 | |
367 | /** |
368 | Creates the decoder for the codec. |
369 | |
370 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
371 | |
372 | @return a pointer to an instance of the codec's decoder. |
373 | */ |
374 | virtual Decoder *makeDecoder(NewlineType newline = NewlineLF) const = 0; |
375 | |
376 | /** |
377 | Convenience wrapper that can be used for small chunks of data |
378 | when you can provide a large enough buffer. The default |
379 | implementation creates an Encoder and uses it. |
380 | |
381 | Encodes a chunk of bytes starting at @p scursor and extending to |
382 | @p send into the buffer described by @p dcursor and @p dend. |
383 | |
384 | This function doesn't support chaining of blocks. The returned |
385 | block cannot be added to, but you don't need to finalize it, too. |
386 | |
387 | Example usage (@p in contains the input data): |
388 | <pre> |
389 | KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64"); |
390 | if (!codec) { |
391 | qFatal() << "no base64 codec found!?"; |
392 | } |
393 | QByteArray out(in.size() * 1.4); // crude maximal size of b64 encoding |
394 | QByteArray::Iterator iit = in.begin(); |
395 | QByteArray::Iterator oit = out.begin(); |
396 | if (!codec->encode(iit, in.end(), oit, out.end())) { |
397 | qDebug() << "output buffer too small"; |
398 | return; |
399 | } |
400 | qDebug() << "Size of encoded data:" << oit - out.begin(); |
401 | </pre> |
402 | |
403 | @param scursor is a pointer to the start of the input buffer. |
404 | @param send is a pointer to the end of the input buffer. |
405 | @param dcursor is a pointer to the start of the output buffer. |
406 | @param dend is a pointer to the end of the output buffer. |
407 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
408 | |
409 | @return false if the encoded data didn't fit into the output buffer; |
410 | true otherwise. |
411 | */ |
412 | virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const; |
413 | |
414 | /** |
415 | Convenience wrapper that can be used for small chunks of data |
416 | when you can provide a large enough buffer. The default |
417 | implementation creates a Decoder and uses it. |
418 | |
419 | Decodes a chunk of bytes starting at @p scursor and extending to |
420 | @p send into the buffer described by @p dcursor and @p dend. |
421 | |
422 | This function doesn't support chaining of blocks. The returned |
423 | block cannot be added to, but you don't need to finalize it, too. |
424 | |
425 | Example usage (@p in contains the input data): |
426 | <pre> |
427 | KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64"); |
428 | if (!codec) { |
429 | qFatal() << "no base64 codec found!?"; |
430 | } |
431 | QByteArray out(in.size()); // good guess for any encoding... |
432 | QByteArray::Iterator iit = in.begin(); |
433 | QByteArray::Iterator oit = out.begin(); |
434 | if (!codec->decode(iit, in.end(), oit, out.end())) { |
435 | qDebug() << "output buffer too small"; |
436 | return; |
437 | } |
438 | qDebug() << "Size of decoded data:" << oit - out.begin(); |
439 | </pre> |
440 | |
441 | @param scursor is a pointer to the start of the input buffer. |
442 | @param send is a pointer to the end of the input buffer. |
443 | @param dcursor is a pointer to the start of the output buffer. |
444 | @param dend is a pointer to the end of the output buffer. |
445 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
446 | |
447 | @return false if the decoded data didn't fit into the output buffer; |
448 | true otherwise. |
449 | */ |
450 | virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const; |
451 | |
452 | /** |
453 | Even more convenient, but also a bit slower and more memory |
454 | intensive, since it allocates storage for the worst case and then |
455 | shrinks the result QByteArray to the actual size again. |
456 | |
457 | For use with small @p src. |
458 | |
459 | @param src is the data to encode. |
460 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
461 | */ |
462 | QByteArray encode(QByteArrayView src, NewlineType newline = NewlineLF) const; |
463 | |
464 | /** |
465 | Even more convenient, but also a bit slower and more memory |
466 | intensive, since it allocates storage for the worst case and then |
467 | shrinks the result QByteArray to the actual size again. |
468 | |
469 | For use with small @p src. |
470 | |
471 | @param src is the data to decode. |
472 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
473 | */ |
474 | QByteArray decode(QByteArrayView src, NewlineType newline = NewlineLF) const; |
475 | |
476 | /** |
477 | Returns the name of the encoding. Guaranteed to be lowercase. |
478 | */ |
479 | virtual const char *name() const = 0; |
480 | |
481 | /** |
482 | Destroys the codec. |
483 | */ |
484 | virtual ~Codec() |
485 | { |
486 | } |
487 | |
488 | protected: |
489 | /** |
490 | Constructs the codec. |
491 | */ |
492 | Codec() |
493 | { |
494 | } |
495 | }; |
496 | |
497 | /** |
498 | @class KCodecs::Decoder kcodecs.h KCodecs |
499 | |
500 | @brief Stateful CTE decoder class |
501 | |
502 | Stateful decoder class, modelled after QTextDecoder. |
503 | |
504 | @section Overview |
505 | |
506 | KCodecs decoders are designed to be able to process encoded data in |
507 | chunks of arbitrary size and to work with output buffers of also |
508 | arbitrary size. They maintain any state necessary to go on where |
509 | the previous call left off. |
510 | |
511 | The class consists of only two methods of interest: see decode, |
512 | which decodes an input block and finalize, which flushes any |
513 | remaining data to the output stream. |
514 | |
515 | Typically, you will create a decoder instance, call decode as |
516 | often as necessary, then call finalize (most often a single |
517 | call suffices, but it might be that during that call the output |
518 | buffer is filled, so you should be prepared to call finalize |
519 | as often as necessary, i.e. until it returns @p true). |
520 | |
521 | @section Return Values |
522 | |
523 | Both methods return @p true to indicate that they've finished their |
524 | job. For decode, a return value of @p true means that the |
525 | current input block has been finished (@p false most often means |
526 | that the output buffer is full, but that isn't required |
527 | behavior. The decode call is free to return at arbitrary |
528 | times during processing). |
529 | |
530 | For finalize, a return value of @p true means that all data |
531 | implicitly or explicitly stored in the decoder instance has been |
532 | flushed to the output buffer. A @p false return value should be |
533 | interpreted as "check if the output buffer is full and call me |
534 | again", just as with decode. |
535 | |
536 | @section Usage Pattern |
537 | |
538 | Since the decoder maintains state, you can only use it once. After |
539 | a sequence of input blocks has been processed, you finalize |
540 | the output and then delete the decoder instance. If you want to |
541 | process another input block sequence, you create a new instance. |
542 | |
543 | Typical usage (@p in contains the (base64-encoded) input data), |
544 | taking into account all the conventions detailed above: |
545 | |
546 | <pre> |
547 | KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64"); |
548 | if (!codec) { |
549 | qFatal() << "No codec found for base64!"; |
550 | } |
551 | KCodecs::Decoder *dec = codec->makeDecoder(); |
552 | Q_ASSERT(dec); // should not happen |
553 | QByteArray out(256); // small buffer is enough ;-) |
554 | QByteArray::Iterator iit = in.begin(); |
555 | QByteArray::Iterator oit = out.begin(); |
556 | // decode the chunk |
557 | while (!dec->decode(iit, in.end(), oit, out.end())) |
558 | if (oit == out.end()) { // output buffer full, process contents |
559 | do_something_with(out); |
560 | oit = out.begin(); |
561 | } |
562 | // repeat while loop for each input block |
563 | // ... |
564 | // finish (flush remaining data from decoder): |
565 | while (!dec->finish(oit, out.end())) |
566 | if (oit == out.end()) { // output buffer full, process contents |
567 | do_something_with(out); |
568 | oit = out.begin(); |
569 | } |
570 | // now process last chunk: |
571 | out.resize(oit - out.begin()); |
572 | do_something_with(out); |
573 | // _delete_ the decoder, but not the codec: |
574 | delete dec; |
575 | </pre> |
576 | |
577 | @since 5.5 |
578 | */ |
579 | class KCODECS_EXPORT Decoder |
580 | { |
581 | protected: |
582 | friend class Codec; |
583 | friend class DecoderPrivate; |
584 | |
585 | /** |
586 | Protected constructor. Use KCodecs::Codec::makeDecoder to create an |
587 | instance. |
588 | |
589 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
590 | */ |
591 | Decoder(Codec::NewlineType newline = Codec::NewlineLF); |
592 | |
593 | public: |
594 | /** |
595 | Destroys the decoder. |
596 | */ |
597 | virtual ~Decoder(); |
598 | |
599 | /** |
600 | Decodes a chunk of data, maintaining state information between |
601 | calls. See class decumentation for calling conventions. |
602 | |
603 | @param scursor is a pointer to the start of the input buffer. |
604 | @param send is a pointer to the end of the input buffer. |
605 | @param dcursor is a pointer to the start of the output buffer. |
606 | @param dend is a pointer to the end of the output buffer. |
607 | */ |
608 | virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0; |
609 | |
610 | /** |
611 | Call this method to finalize the output stream. Writes all |
612 | remaining data and resets the decoder. See KCodecs::Codec for |
613 | calling conventions. |
614 | |
615 | @param dcursor is a pointer to the start of the output buffer. |
616 | @param dend is a pointer to the end of the output buffer. |
617 | */ |
618 | virtual bool finish(char *&dcursor, const char *const dend) = 0; |
619 | |
620 | protected: |
621 | //@cond PRIVATE |
622 | std::unique_ptr<DecoderPrivate> const d; |
623 | //@endcond |
624 | }; |
625 | |
626 | /** |
627 | @class KCodecs::Encoder kcodecs.h KCodecs |
628 | |
629 | @brief Stateful encoder class. |
630 | |
631 | Stateful encoder class, modeled after QTextEncoder. |
632 | |
633 | @since 5.5 |
634 | */ |
635 | class KCODECS_EXPORT Encoder |
636 | { |
637 | protected: |
638 | friend class Codec; |
639 | friend class EncoderPrivate; |
640 | |
641 | /** |
642 | Protected constructor. Use KCodecs::Codec::makeEncoder if you want one. |
643 | |
644 | @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). |
645 | */ |
646 | explicit Encoder(Codec::NewlineType newline = Codec::NewlineLF); |
647 | |
648 | public: |
649 | /** |
650 | Destroys the encoder. |
651 | */ |
652 | virtual ~Encoder(); |
653 | |
654 | /** |
655 | Encodes a chunk of data, maintaining state information between |
656 | calls. See KCodecs::Codec for calling conventions. |
657 | |
658 | @param scursor is a pointer to the start of the input buffer. |
659 | @param send is a pointer to the end of the input buffer. |
660 | @param dcursor is a pointer to the start of the output buffer. |
661 | @param dend is a pointer to the end of the output buffer. |
662 | */ |
663 | virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0; |
664 | |
665 | /** |
666 | Call this method to finalize the output stream. Writes all remaining |
667 | data and resets the encoder. See KCodecs::Codec for calling conventions. |
668 | |
669 | @param dcursor is a pointer to the start of the output buffer. |
670 | @param dend is a pointer to the end of the output buffer. |
671 | */ |
672 | virtual bool finish(char *&dcursor, const char *const dend) = 0; |
673 | |
674 | protected: |
675 | /** |
676 | The maximum number of characters permitted in the output buffer. |
677 | */ |
678 | enum { |
679 | maxBufferedChars = 8, /**< Eight */ |
680 | }; |
681 | |
682 | /** |
683 | Writes character @p ch to the output stream or the output buffer, |
684 | depending on whether or not the output stream has space left. |
685 | |
686 | @param ch is the character to write. |
687 | @param dcursor is a pointer to the start of the output buffer. |
688 | @param dend is a pointer to the end of the output buffer. |
689 | |
690 | @return true if written to the output stream; else false if buffered. |
691 | */ |
692 | bool write(char ch, char *&dcursor, const char *const dend); |
693 | |
694 | /** |
695 | Writes characters from the output buffer to the output stream. |
696 | Implementations of encode and finish should call this |
697 | at the very beginning and for each iteration of the while loop. |
698 | |
699 | @param dcursor is a pointer to the start of the output buffer. |
700 | @param dend is a pointer to the end of the output buffer. |
701 | |
702 | @return true if all chars could be written, false otherwise |
703 | */ |
704 | bool flushOutputBuffer(char *&dcursor, const char *const dend); |
705 | |
706 | /** |
707 | Convenience function. Outputs @ref LF or @ref CRLF, based on the |
708 | state of mWithCRLF. |
709 | |
710 | @param dcursor is a pointer to the start of the output buffer. |
711 | @param dend is a pointer to the end of the output buffer. |
712 | */ |
713 | bool writeCRLF(char *&dcursor, const char *const dend); |
714 | |
715 | protected: |
716 | //@cond PRIVATE |
717 | std::unique_ptr<EncoderPrivate> const d; |
718 | //@endcond |
719 | }; |
720 | |
721 | } // namespace KCodecs |
722 | |
723 | #endif // KCODECS_H |
724 | |