File indexing completed on 2024-04-14 14:18:28

0001 /*
0002     SPDX-FileCopyrightText: 2000-2001 Dawit Alemayehu <adawit@kde.org>
0003     SPDX-FileCopyrightText: 2001 Rik Hemsley (rikkus) <rik@kde.org>
0004     SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 
0008     The quoted-printable codec as described in RFC 2045, section 6.7. is by
0009     Rik Hemsley (C) 2001.
0010 */
0011 
0012 #ifndef KCODECS_H
0013 #define KCODECS_H
0014 
0015 #include <kcodecs_export.h>
0016 
0017 #include <QString>
0018 
0019 #include <memory>
0020 
0021 #if KCODECS_ENABLE_DEPRECATED_SINCE(5, 79)
0022 // KBase64 methods were moved to KCodecs for kdelibs 3.1
0023 #define KBase64 KCodecs
0024 #else
0025 #define KBase64 KBase64_is_deprecated_use_KCodecs
0026 #endif
0027 
0028 template<typename T, typename U>
0029 class QHash;
0030 
0031 class QByteArray;
0032 class QIODevice;
0033 
0034 /**
0035  * A wrapper class for the most commonly used encoding and
0036  * decoding algorithms.  Currently there is support for encoding
0037  * and decoding input using base64, uu and the quoted-printable
0038  * specifications.
0039  *
0040  * \b Usage:
0041  *
0042  * \code
0043  * QByteArray input = "Aladdin:open sesame";
0044  * QByteArray result = KCodecs::base64Encode(input);
0045  * cout << "Result: " << result.data() << endl;
0046  * \endcode
0047  *
0048  * <pre>
0049  * Output should be
0050  * Result: QWxhZGRpbjpvcGVuIHNlc2FtZQ==
0051  * </pre>
0052  *
0053  * The above example makes use of the convenience functions
0054  * (ones that accept/return null-terminated strings) to encode/decode
0055  * a string.  If what you need is to encode or decode binary data, then
0056  * it is highly recommended that you use the functions that take an input
0057  * and output QByteArray as arguments.  These functions are specifically
0058  * tailored for encoding and decoding binary data.
0059  *
0060  * @short A collection of commonly used encoding and decoding algorithms.
0061  * @author Dawit Alemayehu <adawit@kde.org>
0062  * @author Rik Hemsley <rik@kde.org>
0063  */
0064 namespace KCodecs
0065 {
0066 /**
0067  * Encodes the given data using the quoted-printable algorithm.
0068  *
0069  * @param in      data to be encoded.
0070  * @param useCRLF if true the input data is expected to have
0071  *                CRLF line breaks and the output will have CRLF line
0072  *                breaks, too.
0073  * @return        quoted-printable encoded string.
0074  */
0075 KCODECS_EXPORT QByteArray quotedPrintableEncode(const QByteArray &in, bool useCRLF = true);
0076 
0077 /**
0078  * Encodes the given data using the quoted-printable algorithm.
0079  *
0080  * Use this function if you want the result of the encoding
0081  * to be placed in another array which cuts down the number
0082  * of copy operation that have to be performed in the process.
0083  * This is also the preferred method for encoding binary data.
0084  *
0085  * NOTE: the output array is first reset and then resized
0086  * appropriately before use, hence, all data stored in the
0087  * output array will be lost.
0088  *
0089  * @param in      data to be encoded.
0090  * @param out     encoded data.
0091  * @param useCRLF if true the input data is expected to have
0092  *                CRLF line breaks and the output will have CRLF line
0093  *                breaks, too.
0094  */
0095 KCODECS_EXPORT void quotedPrintableEncode(const QByteArray &in, QByteArray &out, bool useCRLF);
0096 
0097 /**
0098  * Decodes a quoted-printable encoded data.
0099  *
0100  * Accepts data with CRLF or standard unix line breaks.
0101  *
0102  * @param in  data to be decoded.
0103  * @return    decoded string.
0104  * @since 5.5
0105  */
0106 KCODECS_EXPORT QByteArray quotedPrintableDecode(const QByteArray &in);
0107 
0108 /**
0109  * Decodes a quoted-printable encoded data.
0110  *
0111  * Accepts data with CRLF or standard unix line breaks.
0112  * Use this function if you want the result of the decoding
0113  * to be placed in another array which cuts down the number
0114  * of copy operation that have to be performed in the process.
0115  * This is also the preferred method for decoding an encoded
0116  * binary data.
0117  *
0118  * NOTE: the output array is first reset and then resized
0119  * appropriately before use, hence, all data stored in the
0120  * output array will be lost.
0121  *
0122  * @param in   data to be decoded.
0123  * @param out  decoded data.
0124  */
0125 KCODECS_EXPORT void quotedPrintableDecode(const QByteArray &in, QByteArray &out);
0126 
0127 #if KCODECS_ENABLE_DEPRECATED_SINCE(5, 56)
0128 /**
0129  * Encodes the given data using the uuencode algorithm.
0130  *
0131  * The output is split into lines starting with the number of
0132  * encoded octets in the line and ending with a newline.  No
0133  * line is longer than 45 octets (60 characters), excluding the
0134  * line terminator.
0135  *
0136  * @param in   data to be uuencoded
0137  * @return     uuencoded string.
0138  * @deprecated Not implemented, always returns an empty bytearray.
0139  */
0140 KCODECS_EXPORT
0141 KCODECS_DEPRECATED_VERSION(5, 56, "Not implemented")
0142 QByteArray uuencode(const QByteArray &in);
0143 #endif
0144 
0145 #if KCODECS_ENABLE_DEPRECATED_SINCE(5, 56)
0146 /**
0147  * Encodes the given data using the uuencode algorithm.
0148  *
0149  * Use this function if you want the result of the encoding
0150  * to be placed in another array and cut down the number of
0151  * copy operation that have to be performed in the process.
0152  * This is the preferred method for encoding binary data.
0153  *
0154  * NOTE: the output array is first reset and then resized
0155  * appropriately before use, hence, all data stored in the
0156  * output array will be lost.
0157  *
0158  * @param in   data to be uuencoded.
0159  * @param out  an empty byte array
0160  * @deprecated Not implemented, always set @p out to an empty bytearray.
0161  */
0162 KCODECS_EXPORT
0163 KCODECS_DEPRECATED_VERSION(5, 56, "Not implemented")
0164 void uuencode(const QByteArray &in, QByteArray &out);
0165 #endif
0166 
0167 /**
0168  * Decodes the given data using the uudecode algorithm.
0169  *
0170  * Any 'begin' and 'end' lines like those generated by
0171  * the utilities in unix and unix-like OS will be
0172  * automatically ignored.
0173  *
0174  * @param in   data to be decoded.
0175  * @return     decoded string.
0176  */
0177 KCODECS_EXPORT QByteArray uudecode(const QByteArray &in);
0178 
0179 /**
0180  * Decodes the given data using the uudecode algorithm.
0181  *
0182  * Use this function if you want the result of the decoding
0183  * to be placed in another array which cuts down the number
0184  * of copy operation that have to be performed in the process.
0185  * This is the preferred method for decoding binary data.
0186  *
0187  * Any 'begin' and 'end' lines like those generated by
0188  * the utilities in unix and unix-like OS will be
0189  * automatically ignored.
0190  *
0191  * NOTE: the output array is first reset and then resized
0192  * appropriately before use, hence, all data stored in the
0193  * output array will be lost.
0194  *
0195  * @param in   data to be decoded.
0196  * @param out  uudecoded data.
0197  */
0198 KCODECS_EXPORT void uudecode(const QByteArray &in, QByteArray &out);
0199 
0200 /**
0201  * Encodes the given data using the base64 algorithm.
0202  *
0203  * The boolean argument determines if the encoded data is
0204  * going to be restricted to 76 characters or less per line
0205  * as specified by RFC 2045.  If @p insertLFs is true, then
0206  * there will be 76 characters or less per line.
0207  *
0208  * @param in         data to be encoded.
0209  * @param insertLFs  limit the number of characters per line.
0210  *
0211  * @return           base64 encoded string.
0212  * @since 5.5
0213  */
0214 KCODECS_EXPORT QByteArray base64Encode(const QByteArray &in);
0215 
0216 #if KCODECS_ENABLE_DEPRECATED_SINCE(5, 5)
0217 /**
0218  * @copydoc
0219  * KCodecs::base64Encode(QByteArray)
0220  * @deprecated Since 5.5, use KCodecs::base64Encode(QByteArray) instead.
0221  */
0222 KCODECS_EXPORT
0223 KCODECS_DEPRECATED_VERSION(5, 5, "Use QByteArray base64Encode(const QByteArray &)")
0224 QByteArray base64Encode(const QByteArray &in, bool insertLFs);
0225 #endif
0226 
0227 /**
0228  * Encodes the given data using the base64 algorithm.
0229  *
0230  * Use this function if you want the result of the encoding
0231  * to be placed in another array which cuts down the number
0232  * of copy operation that have to be performed in the process.
0233  * This is also the preferred method for encoding binary data.
0234  *
0235  * The boolean argument determines if the encoded data is going
0236  * to be restricted to 76 characters or less per line as specified
0237  * by RFC 2045.  If @p insertLFs is true, then there will be 76
0238  * characters or less per line.
0239  *
0240  * NOTE: the output array is first reset and then resized
0241  * appropriately before use, hence, all data stored in the
0242  * output array will be lost.
0243  *
0244  * @param in        data to be encoded.
0245  * @param out       encoded data.
0246  * @param insertLFs limit the number of characters per line.
0247  */
0248 KCODECS_EXPORT void base64Encode(const QByteArray &in, QByteArray &out, bool insertLFs = false);
0249 
0250 /**
0251  * Decodes the given data that was encoded using the
0252  * base64 algorithm.
0253  *
0254  * @param in   data to be decoded.
0255  * @return     decoded string.
0256  */
0257 KCODECS_EXPORT QByteArray base64Decode(const QByteArray &in);
0258 
0259 /**
0260  * Decodes the given data that was encoded with the base64
0261  * algorithm.
0262  *
0263  * Use this function if you want the result of the decoding
0264  * to be placed in another array which cuts down the number
0265  * of copy operation that have to be performed in the process.
0266  * This is also the preferred method for decoding an encoded
0267  * binary data.
0268  *
0269  * NOTE: the output array is first reset and then resized
0270  * appropriately before use, hence, all data stored in the
0271  * output array will be lost.
0272  *
0273  * @param in   data to be decoded.
0274  * @param out  decoded data.
0275  */
0276 KCODECS_EXPORT void base64Decode(const QByteArray &in, QByteArray &out);
0277 
0278 /**
0279  * Decodes string @p text according to RFC2047,
0280  * i.e., the construct =?charset?[qb]?encoded?=
0281  *
0282  * @param text source string
0283  * @returns the decoded string
0284  */
0285 KCODECS_EXPORT QString decodeRFC2047String(const QString &text);
0286 
0287 /**
0288  * Charset options for RFC2047 encoder
0289  * @since 5.5
0290  */
0291 enum CharsetOption {
0292     NoOption = 0, /// No special option
0293     ForceDefaultCharset = 1, /// Force use of the default charset
0294 };
0295 
0296 /**
0297  * Decodes string @p src according to RFC2047, i.e. the construct
0298  *  =?charset?[qb]?encoded?=
0299  *
0300  * @param src       source string.
0301  * @param usedCS    the name of any detected charset or, in case of multiple
0302  *                  different ones, "UTF-8" as that of a super charset is
0303  *                  returned here
0304  * @param defaultCS the charset to use in case the detected
0305  *                  one isn't known to us.
0306  * @param option    options for the encoder
0307  *
0308  * @return the decoded string.
0309  * @since 5.5
0310  */
0311 KCODECS_EXPORT QString decodeRFC2047String(const QByteArray &src,
0312                                            QByteArray *usedCS,
0313                                            const QByteArray &defaultCS = QByteArray(),
0314                                            CharsetOption option = NoOption);
0315 
0316 /**
0317  * Encodes string @p src according to RFC2047 using charset @p charset.
0318  *
0319  * This function also makes commas, quotes and other characters part of the encoded name, for example
0320  * the string "Jöhn Döe" <john@example.com"> would be encoded as <encoded word for "Jöhn Döe"> <john@example.com>,
0321  * i.e. the opening and closing quote mark would be part of the encoded word.
0322  * Therefore don't use this function for input strings that contain semantically meaningful characters,
0323  * like the quoting marks in this example.
0324  *
0325  * @param src           source string.
0326  * @param charset       charset to use. If it can't encode the string, UTF-8 will be used instead.
0327  * @return the encoded string.
0328  * @since 5.5
0329  */
0330 KCODECS_EXPORT QByteArray encodeRFC2047String(const QString &src, const QByteArray &charset);
0331 
0332 /**
0333  * Decodes the given data that was encoded using the
0334  * base45 codec.
0335  *
0336  * @param in   data to be decoded.
0337  * @return     decoded string.
0338  * @since 5.84
0339  * @see https://datatracker.ietf.org/doc/draft-faltstrom-base45/
0340  */
0341 KCODECS_EXPORT QByteArray base45Decode(const QByteArray &in);
0342 
0343 class Encoder;
0344 class EncoderPrivate;
0345 class Decoder;
0346 class DecoderPrivate;
0347 
0348 /**
0349   @class KCodecs::Codec kcodecs.h KCodecs
0350 
0351   @glossary @anchor MIME @anchor mime @b MIME:
0352   <b>Multipurpose Internet Mail Extensions</b> or @acronym MIME is an
0353   Internet Standard that extends the format of e-mail to support text in
0354   character sets other than US-ASCII, non-text attachments, multi-part message
0355   bodies, and header information in non-ASCII character sets. Virtually all
0356   human-written Internet e-mail and a fairly large proportion of automated
0357   e-mail is transmitted via @acronym SMTP in MIME format. Internet e-mail is
0358   so closely associated with the SMTP and MIME standards that it is sometimes
0359   called SMTP/MIME e-mail. The content types defined by MIME standards are
0360   also of growing importance outside of e-mail, such as in communication
0361   protocols like @acronym HTTP for the World Wide Web. MIME is also a
0362   fundamental component of communication protocols such as  HTTP, which
0363   requires that data be transmitted in the context of e-mail-like messages,
0364   even though the data may not actually be e-mail.
0365 
0366   @glossary @anchor codec @anchor codecs @anchor Codec @anchor Codecs @b codec:
0367   a program capable of performing encoding and decoding on a digital data
0368   stream. Codecs encode data for storage or encryption and decode it for
0369   viewing or editing.
0370 
0371   @glossary @anchor CRLF @b CRLF: a "Carriage Return (0x0D)" followed by a
0372   "Line Feed (0x0A)", two ASCII control characters used to represent a
0373   newline on some operating systems, notably DOS and Microsoft Windows.
0374 
0375   @glossary @anchor LF @b LF: a "Line Feed (0x0A)" ASCII control character used
0376   to represent a newline on some operating systems, notably Unix, Unix-like,
0377   and Linux.
0378 
0379   @brief An abstract base class of @ref codecs for common mail transfer encodings.
0380 
0381   Provides an abstract base class of @ref codecs like base64 and quoted-printable.
0382   Implemented as a singleton.
0383 
0384   @authors Marc Mutz \<mutz@kde.org\>
0385   @since 5.5
0386 */
0387 class KCODECS_EXPORT Codec
0388 {
0389 public:
0390     enum NewlineType {
0391         NewlineLF,
0392         NewlineCRLF,
0393     };
0394 
0395     /**
0396       Returns a codec associated with the specified @p name.
0397 
0398       @param name points to a character string containing a valid codec name.
0399     */
0400     static Codec *codecForName(const char *name);
0401 
0402     /**
0403       Returns a codec associated with the specified @p name.
0404 
0405       @param name is a QByteArray containing a valid codec name.
0406     */
0407     static Codec *codecForName(const QByteArray &name);
0408 
0409     /**
0410       Computes the maximum size, in characters, needed for the encoding.
0411 
0412       @param insize is the number of input characters to be encoded.
0413       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0414 
0415       @return the maximum number of characters in the encoding.
0416     */
0417     virtual int maxEncodedSizeFor(int insize, NewlineType newline = NewlineLF) const = 0;
0418 
0419     /**
0420       Computes the maximum size, in characters, needed for the deccoding.
0421 
0422       @param insize is the number of input characters to be decoded.
0423       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0424 
0425       @return the maximum number of characters in the decoding.
0426     */
0427     virtual int maxDecodedSizeFor(int insize, NewlineType newline = NewlineLF) const = 0;
0428 
0429     /**
0430       Creates the encoder for the codec.
0431 
0432       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0433 
0434       @return a pointer to an instance of the codec's encoder.
0435     */
0436     virtual Encoder *makeEncoder(NewlineType newline = NewlineLF) const = 0;
0437 
0438     /**
0439       Creates the decoder for the codec.
0440 
0441       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0442 
0443       @return a pointer to an instance of the codec's decoder.
0444     */
0445     virtual Decoder *makeDecoder(NewlineType newline = NewlineLF) const = 0;
0446 
0447     /**
0448       Convenience wrapper that can be used for small chunks of data
0449       when you can provide a large enough buffer. The default
0450       implementation creates an Encoder and uses it.
0451 
0452       Encodes a chunk of bytes starting at @p scursor and extending to
0453       @p send into the buffer described by @p dcursor and @p dend.
0454 
0455       This function doesn't support chaining of blocks. The returned
0456       block cannot be added to, but you don't need to finalize it, too.
0457 
0458       Example usage (@p in contains the input data):
0459       <pre>
0460       KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
0461       if (!codec) {
0462           qFatal() << "no base64 codec found!?";
0463       }
0464       QByteArray out(in.size() * 1.4); // crude maximal size of b64 encoding
0465       QByteArray::Iterator iit = in.begin();
0466       QByteArray::Iterator oit = out.begin();
0467       if (!codec->encode(iit, in.end(), oit, out.end())) {
0468           qDebug() << "output buffer too small";
0469           return;
0470       }
0471       qDebug() << "Size of encoded data:" << oit - out.begin();
0472       </pre>
0473 
0474       @param scursor is a pointer to the start of the input buffer.
0475       @param send is a pointer to the end of the input buffer.
0476       @param dcursor is a pointer to the start of the output buffer.
0477       @param dend is a pointer to the end of the output buffer.
0478       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0479 
0480       @return false if the encoded data didn't fit into the output buffer;
0481       true otherwise.
0482     */
0483     virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const;
0484 
0485     /**
0486       Convenience wrapper that can be used for small chunks of data
0487       when you can provide a large enough buffer. The default
0488       implementation creates a Decoder and uses it.
0489 
0490       Decodes a chunk of bytes starting at @p scursor and extending to
0491       @p send into the buffer described by @p dcursor and @p dend.
0492 
0493       This function doesn't support chaining of blocks. The returned
0494       block cannot be added to, but you don't need to finalize it, too.
0495 
0496       Example usage (@p in contains the input data):
0497       <pre>
0498       KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
0499       if (!codec) {
0500           qFatal() << "no base64 codec found!?";
0501       }
0502       QByteArray out(in.size()); // good guess for any encoding...
0503       QByteArray::Iterator iit = in.begin();
0504       QByteArray::Iterator oit = out.begin();
0505       if (!codec->decode(iit, in.end(), oit, out.end())) {
0506           qDebug() << "output buffer too small";
0507           return;
0508       }
0509       qDebug() << "Size of decoded data:" << oit - out.begin();
0510       </pre>
0511 
0512       @param scursor is a pointer to the start of the input buffer.
0513       @param send is a pointer to the end of the input buffer.
0514       @param dcursor is a pointer to the start of the output buffer.
0515       @param dend is a pointer to the end of the output buffer.
0516       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0517 
0518       @return false if the decoded data didn't fit into the output buffer;
0519       true otherwise.
0520     */
0521     virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const;
0522 
0523     /**
0524       Even more convenient, but also a bit slower and more memory
0525       intensive, since it allocates storage for the worst case and then
0526       shrinks the result QByteArray to the actual size again.
0527 
0528       For use with small @p src.
0529 
0530       @param src is a QByteArray containing the data to encode.
0531       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0532     */
0533     virtual QByteArray encode(const QByteArray &src, NewlineType newline = NewlineLF) const;
0534 
0535     /**
0536       Even more convenient, but also a bit slower and more memory
0537       intensive, since it allocates storage for the worst case and then
0538       shrinks the result QByteArray to the actual size again.
0539 
0540       For use with small @p src.
0541 
0542       @param src is a QByteArray containing the data to decode.
0543       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0544     */
0545     virtual QByteArray decode(const QByteArray &src, NewlineType newline = NewlineLF) const;
0546 
0547     /**
0548       Returns the name of the encoding. Guaranteed to be lowercase.
0549     */
0550     virtual const char *name() const = 0;
0551 
0552     /**
0553       Destroys the codec.
0554     */
0555     virtual ~Codec()
0556     {
0557     }
0558 
0559 protected:
0560     /**
0561       Constructs the codec.
0562     */
0563     Codec()
0564     {
0565     }
0566 };
0567 
0568 /**
0569   @class KCodecs::Decoder kcodecs.h KCodecs
0570 
0571   @brief Stateful CTE decoder class
0572 
0573   Stateful decoder class, modelled after QTextDecoder.
0574 
0575   @section Overview
0576 
0577   KCodecs decoders are designed to be able to process encoded data in
0578   chunks of arbitrary size and to work with output buffers of also
0579   arbitrary size. They maintain any state necessary to go on where
0580   the previous call left off.
0581 
0582   The class consists of only two methods of interest: see decode,
0583   which decodes an input block and finalize, which flushes any
0584   remaining data to the output stream.
0585 
0586   Typically, you will create a decoder instance, call decode as
0587   often as necessary, then call finalize (most often a single
0588   call suffices, but it might be that during that call the output
0589   buffer is filled, so you should be prepared to call finalize
0590   as often as necessary, ie. until it returns @p true).
0591 
0592   @section Return Values
0593 
0594   Both methods return @p true to indicate that they've finished their
0595   job. For decode, a return value of @p true means that the
0596   current input block has been finished (@p false most often means
0597   that the output buffer is full, but that isn't required
0598   behavior. The decode call is free to return at arbitrary
0599   times during processing).
0600 
0601   For finalize, a return value of @p true means that all data
0602   implicitly or explicitly stored in the decoder instance has been
0603   flushed to the output buffer. A @p false return value should be
0604   interpreted as "check if the output buffer is full and call me
0605   again", just as with decode.
0606 
0607   @section Usage Pattern
0608 
0609   Since the decoder maintains state, you can only use it once. After
0610   a sequence of input blocks has been processed, you finalize
0611   the output and then delete the decoder instance. If you want to
0612   process another input block sequence, you create a new instance.
0613 
0614   Typical usage (@p in contains the (base64-encoded) input data),
0615   taking into account all the conventions detailed above:
0616 
0617   <pre>
0618   KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
0619   if (!codec) {
0620       qFatal() << "No codec found for base64!";
0621   }
0622   KCodecs::Decoder *dec = codec->makeDecoder();
0623   Q_ASSERT(dec); // should not happen
0624   QByteArray out(256); // small buffer is enough ;-)
0625   QByteArray::Iterator iit = in.begin();
0626   QByteArray::Iterator oit = out.begin();
0627   // decode the chunk
0628   while (!dec->decode(iit, in.end(), oit, out.end()))
0629     if (oit == out.end()) { // output buffer full, process contents
0630       do_something_with(out);
0631       oit = out.begin();
0632     }
0633   // repeat while loop for each input block
0634   // ...
0635   // finish (flush remaining data from decoder):
0636   while (!dec->finish(oit, out.end()))
0637     if (oit == out.end()) { // output buffer full, process contents
0638       do_something_with(out);
0639       oit = out.begin();
0640     }
0641   // now process last chunk:
0642   out.resize(oit - out.begin());
0643   do_something_with(out);
0644   // _delete_ the decoder, but not the codec:
0645   delete dec;
0646   </pre>
0647 
0648   @since 5.5
0649 */
0650 class KCODECS_EXPORT Decoder
0651 {
0652 protected:
0653     friend class Codec;
0654     friend class DecoderPrivate;
0655 
0656     /**
0657       Protected constructor. Use KCodecs::Codec::makeDecoder to create an
0658       instance.
0659 
0660       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0661     */
0662     Decoder(Codec::NewlineType newline = Codec::NewlineLF);
0663 
0664 public:
0665     /**
0666       Destroys the decoder.
0667     */
0668     virtual ~Decoder();
0669 
0670     /**
0671       Decodes a chunk of data, maintaining state information between
0672       calls. See class decumentation for calling conventions.
0673 
0674       @param scursor is a pointer to the start of the input buffer.
0675       @param send is a pointer to the end of the input buffer.
0676       @param dcursor is a pointer to the start of the output buffer.
0677       @param dend is a pointer to the end of the output buffer.
0678     */
0679     virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0;
0680 
0681     /**
0682       Call this method to finalize the output stream. Writes all
0683       remaining data and resets the decoder. See KCodecs::Codec for
0684       calling conventions.
0685 
0686       @param dcursor is a pointer to the start of the output buffer.
0687       @param dend is a pointer to the end of the output buffer.
0688     */
0689     virtual bool finish(char *&dcursor, const char *const dend) = 0;
0690 
0691 protected:
0692     //@cond PRIVATE
0693     std::unique_ptr<DecoderPrivate> const d;
0694     //@endcond
0695 };
0696 
0697 /**
0698   @class KCodecs::Encoder kcodecs.h KCodecs
0699 
0700   @brief Stateful encoder class.
0701 
0702   Stateful encoder class, modeled after QTextEncoder.
0703 
0704   @since 5.5
0705 */
0706 class KCODECS_EXPORT Encoder
0707 {
0708 protected:
0709     friend class Codec;
0710     friend class EncoderPrivate;
0711 
0712     /**
0713       Protected constructor. Use KCodecs::Codec::makeEncoder if you want one.
0714 
0715       @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF).
0716     */
0717     explicit Encoder(Codec::NewlineType newline = Codec::NewlineLF);
0718 
0719 public:
0720     /**
0721       Destroys the encoder.
0722     */
0723     virtual ~Encoder();
0724 
0725     /**
0726       Encodes a chunk of data, maintaining state information between
0727       calls. See KCodecs::Codec for calling conventions.
0728 
0729       @param scursor is a pointer to the start of the input buffer.
0730       @param send is a pointer to the end of the input buffer.
0731       @param dcursor is a pointer to the start of the output buffer.
0732       @param dend is a pointer to the end of the output buffer.
0733     */
0734     virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0;
0735 
0736     /**
0737       Call this method to finalize the output stream. Writes all remaining
0738       data and resets the encoder. See KCodecs::Codec for calling conventions.
0739 
0740       @param dcursor is a pointer to the start of the output buffer.
0741       @param dend is a pointer to the end of the output buffer.
0742     */
0743     virtual bool finish(char *&dcursor, const char *const dend) = 0;
0744 
0745 protected:
0746     /**
0747       The maximum number of characters permitted in the output buffer.
0748     */
0749     enum {
0750         maxBufferedChars = 8, /**< Eight */
0751     };
0752 
0753     /**
0754       Writes character @p ch to the output stream or the output buffer,
0755       depending on whether or not the output stream has space left.
0756 
0757       @param ch is the character to write.
0758       @param dcursor is a pointer to the start of the output buffer.
0759       @param dend is a pointer to the end of the output buffer.
0760 
0761       @return true if written to the output stream; else false if buffered.
0762     */
0763     bool write(char ch, char *&dcursor, const char *const dend);
0764 
0765     /**
0766       Writes characters from the output buffer to the output stream.
0767       Implementations of encode and finish should call this
0768       at the very beginning and for each iteration of the while loop.
0769 
0770       @param dcursor is a pointer to the start of the output buffer.
0771       @param dend is a pointer to the end of the output buffer.
0772 
0773       @return true if all chars could be written, false otherwise
0774     */
0775     bool flushOutputBuffer(char *&dcursor, const char *const dend);
0776 
0777     /**
0778       Convenience function. Outputs @ref LF or @ref CRLF, based on the
0779       state of mWithCRLF.
0780 
0781       @param dcursor is a pointer to the start of the output buffer.
0782       @param dend is a pointer to the end of the output buffer.
0783     */
0784     bool writeCRLF(char *&dcursor, const char *const dend);
0785 
0786 protected:
0787     //@cond PRIVATE
0788     std::unique_ptr<EncoderPrivate> const d;
0789     //@endcond
0790 };
0791 
0792 } // namespace KCodecs
0793 
0794 #endif // KCODECS_H