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