LCOV - code coverage report
Current view: top level - include/tools - inetmime.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 32 99 32.3 %
Date: 2014-11-03 Functions: 16 41 39.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : #ifndef INCLUDED_TOOLS_INETMIME_HXX
      20             : #define INCLUDED_TOOLS_INETMIME_HXX
      21             : 
      22             : #include <boost/ptr_container/ptr_vector.hpp>
      23             : 
      24             : #include <tools/toolsdllapi.h>
      25             : #include <rtl/alloc.h>
      26             : #include <rtl/character.hxx>
      27             : #include <rtl/string.hxx>
      28             : #include <rtl/strbuf.hxx>
      29             : #include <rtl/ustring.hxx>
      30             : #include <rtl/tencinfo.h>
      31             : #include <tools/debug.hxx>
      32             : #include <tools/errcode.hxx>
      33             : 
      34             : class DateTime;
      35             : class INetContentTypeParameterList;
      36             : class INetMIMECharsetList_Impl;
      37             : class INetMIMEOutputSink;
      38             : 
      39             : class TOOLS_DLLPUBLIC INetMIME
      40             : {
      41             : public:
      42             :     enum { SOFT_LINE_LENGTH_LIMIT = 76,
      43             :            HARD_LINE_LENGTH_LIMIT = 998 };
      44             : 
      45             :     /** The various types of message header field bodies, with respect to
      46             :         encoding and decoding them.
      47             : 
      48             :         @descr  At the moment, five different types of header fields suffice
      49             :         to describe how to encoded and decode any known message header field
      50             :         body, but need for more types may arise in the future as new header
      51             :         fields are introduced.
      52             : 
      53             :         @descr  The following is an exhaustive list of all the header fields
      54             :         currently known to our implementation.  For every header field, it
      55             :         includes a 'canonic' (with regard to capitalization) name, a grammar
      56             :         rule for the body (using RFC 822 and RFC 2234 conventions), a list of
      57             :         relevant sources of information, and the HeaderFieldType value to use
      58             :         with that header field.  The list is based on RFC 2076 and draft-
      59             :         palme-mailext-headers-02.txt (see also <http://www.dsv.su.se/~jpalme/
      60             :         ietf/jp-ietf-home.html#anchor1003783>).
      61             : 
      62             :         Approved: address  ;RFC 1036; HEADER_FIELD_ADDRESS
      63             :         bcc: #address  ;RFCs 822, 2047; HEADER_FIELD_ADDRESS
      64             :         cc: 1#address  ;RFCs 822, 2047; HEADER_FIELD_ADDRESS
      65             :         Comments: *text  ;RFCs 822, RFC 2047; HEADER_FIELD_TEXT
      66             :         Content-Base: absoluteURI  ;RFC 2110; HEADER_FIELD_TEXT
      67             :         Content-Description: *text  ;RFC 2045, RFC 2047; HEADER_FIELD_TEXT
      68             :         Content-Disposition: disposition-type *(";" disposition-parm)
      69             :             ;RFC 1806; HEADER_FIELD_STRUCTURED
      70             :         Content-ID: msg-id  ;RFC 2045, RFC 2047; HEADER_FIELD_MESSAGE_ID
      71             :         Content-Location: absoluteURI / relativeURI  ;RFC 2110;
      72             :             HEADER_FIELD_TEXT
      73             :         Content-Transfer-Encoding: mechanism  ;RFC 2045, RFC 2047;
      74             :             HEADER_FIELD_STRUCTURED
      75             :         Content-Type: type "/" subtype *(";" parameter)  ;RFC 2045, RFC 2047;
      76             :             HEADER_FIELD_STRUCTURED
      77             :         Control:  *text ;RFC 1036; HEADER_FIELD_TEXT
      78             :         Date: date-time  ;RFC 822, RFC 1123, RFC 2047; HEADER_FIELD_STRUCTURED
      79             :         Distribution: 1#atom  ;RFC 1036; HEADER_FIELD_STRUCTURED
      80             :         Encrypted: 1#2word  ;RFC 822, RFC 2047; HEADER_FIELD_STRUCTURED
      81             :         Expires: date-time  ;RFC 1036; HEADER_FIELD_STRUCTURED
      82             :         Followup-To: 1#(atom *("." atom))  ;RFC 1036; HEADER_FIELD_STRUCTURED
      83             :         From: mailbox / 1#mailbox  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
      84             :         In-Reply-To: *(phrase / msg-id)  ;RFC 822, RFC 2047;
      85             :             HEADER_FIELD_ADDRESS
      86             :         Keywords: #phrase  ;RFC 822, RFC 2047; HEADER_FIELD_PHRASE
      87             :         MIME-Version: 1*DIGIT "." 1*DIGIT  ;RFC 2045, RFC 2047;
      88             :             HEADER_FIELD_STRUCTURED
      89             :         Message-ID: msg-id  ;RFC 822, RFC 2047; HEADER_FIELD_MESSAGE_ID
      90             :         Newsgroups: 1#(atom *("." atom))  ;RFC 1036, RFC 2047;
      91             :             HEADER_FIELD_STRUCTURED
      92             :         Organization: *text  ;RFC 1036; HEADER_FIELD_TEXT
      93             :         Received: ["from" domain] ["by" domain] ["via" atom] *("with" atom)
      94             :             ["id" msg-id] ["for" addr-spec] ";" date-time  ;RFC 822, RFC 1123,
      95             :             RFC 2047; HEADER_FIELD_STRUCTURED
      96             :         References: *(phrase / msg-id)  ;RFC 822, RFC 2047;
      97             :             HEADER_FIELD_ADDRESS
      98             :         Reply-To: 1#address  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
      99             :         Resent-Date: date-time  ;RFC 822, RFC 1123, RFC 2047;
     100             :             HEADER_FIELD_STRUCTURED
     101             :         Resent-From: mailbox / 1#mailbox  ;RFC 822, RFC 2047;
     102             :             HEADER_FIELD_ADDRESS
     103             :         Resent-Message-ID: msg-id  ;RFC 822, RFC 2047; HEADER_FIELD_MESSAGE_ID
     104             :         Resent-Reply-To: 1#address  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
     105             :         Resent-Sender: mailbox  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
     106             :         Resent-To: 1#address  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
     107             :         Resent-bcc: #address  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
     108             :         Resent-cc: 1#address  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
     109             :         Return-path: route-addr / ("<" ">")  ;RFC 822, RFC 1123, RFC 2047;
     110             :             HEADER_FIELD_STRUCTURED
     111             :         Return-Receipt-To: address  ;Not Internet standard;
     112             :             HEADER_FIELD_ADDRES
     113             :         Sender: mailbox  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
     114             :         Subject: *text  ;RFC 822, RFC 2047; HEADER_FIELD_TEXT
     115             :         Summary: *text  ;RFC 1036; HEADER_FIELD_TEXT
     116             :         To: 1#address  ;RFC 822, RFC 2047; HEADER_FIELD_ADDRESS
     117             :         X-CHAOS-Marked: "YES" / "NO"  ;local; HEADER_FIELD_STRUCTURED
     118             :         X-CHAOS-Read: "YES" / "NO"  ;local; HEADER_FIELD_STRUCTURED
     119             :         X-CHAOS-Recipients: #*("<" atom word ">")  ;local;
     120             :             HEADER_FIELD_STRUCTURED
     121             :         X-CHAOS-Size: 1*DIGIT  ;local; HEADER_FIELD_STRUCTURED
     122             :         X-Mailer: *text  ;Not Internet standard; HEADER_FIELD_TEXT
     123             :         X-Mozilla-Status: 4HEXDIG  ;Mozilla; HEADER_FIELD_STRUCTURED
     124             :         X-Newsreader: *text  ;Not Internet standard; HEADER_FIELD_TEXT
     125             :         X-Priority: "1" / "2" / "3" / "4" / "5"  ;Not Internet standard;
     126             :             HEADER_FIELD_STRUCTURED
     127             :         Xref: sub-domain
     128             :             1*((atom / string) *("." (atom / string)) ":" msg-number)
     129             :             ;RFCs 1036, 2047, local; HEADER_FIELD_STRUCTURED
     130             :      */
     131             :     enum HeaderFieldType
     132             :     {
     133             :         HEADER_FIELD_TEXT,
     134             :         HEADER_FIELD_STRUCTURED,
     135             :         HEADER_FIELD_PHRASE,
     136             :         HEADER_FIELD_MESSAGE_ID,
     137             :         HEADER_FIELD_ADDRESS
     138             :     };
     139             : 
     140             :     /** Check for ISO 8859-1 character.
     141             : 
     142             :         @param nChar  Some UCS-4 character.
     143             : 
     144             :         @return  True if nChar is a ISO 8859-1 character (0x00--0xFF).
     145             :      */
     146             :     static inline bool isISO88591(sal_uInt32 nChar);
     147             : 
     148             :     /** Check for US-ASCII control character.
     149             : 
     150             :         @param nChar  Some UCS-4 character.
     151             : 
     152             :         @return  True if nChar is a US-ASCII control character (US-ASCII
     153             :         0x00--0x1F or 0x7F).
     154             :      */
     155             :     static inline bool isControl(sal_uInt32 nChar);
     156             : 
     157             :     /** Check for US-ASCII white space character.
     158             : 
     159             :         @param nChar  Some UCS-4 character.
     160             : 
     161             :         @return  True if nChar is a US-ASCII white space character (US-ASCII
     162             :         0x09 or 0x20).
     163             :      */
     164             :     static inline bool isWhiteSpace(sal_uInt32 nChar);
     165             : 
     166             :     /** Check for US-ASCII visible character.
     167             : 
     168             :         @param nChar  Some UCS-4 character.
     169             : 
     170             :         @return  True if nChar is a US-ASCII visible character (US-ASCII
     171             :         0x21--0x7E).
     172             :      */
     173             :     static inline bool isVisible(sal_uInt32 nChar);
     174             : 
     175             :     /** Check for US-ASCII Base 64 digit character.
     176             : 
     177             :         @param nChar  Some UCS-4 character.
     178             : 
     179             :         @return  True if nChar is a US-ASCII Base 64 digit character (US-ASCII
     180             :         'A'--'Z', 'a'--'z', '0'--'9', '+', or '/').
     181             :      */
     182             :     static inline bool isBase64Digit(sal_uInt32 nChar);
     183             : 
     184             :     /** Check whether some character is valid within an RFC 822 <atom>.
     185             : 
     186             :         @param nChar  Some UCS-4 character.
     187             : 
     188             :         @return  True if nChar is valid within an RFC 822 <atom> (US-ASCII
     189             :         'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '%', '&', ''', '*', '+',
     190             :         '-', '/', '=', '?', '^', '_', '`', '{', '|', '}', or '~').
     191             :      */
     192             :     static bool isAtomChar(sal_uInt32 nChar);
     193             : 
     194             :     /** Check whether some character is valid within an RFC 2045 <token>.
     195             : 
     196             :         @param nChar  Some UCS-4 character.
     197             : 
     198             :         @return  True if nChar is valid within an RFC 2047 <token> (US-ASCII
     199             :         'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '%', '&', ''', '*', '+',
     200             :         '-', '.', '^', '_', '`', '{', '|', '}', or '~').
     201             :      */
     202             :     static bool isTokenChar(sal_uInt32 nChar);
     203             : 
     204             :     /** Check whether some character is valid within an RFC 2047 <token>.
     205             : 
     206             :         @param nChar  Some UCS-4 character.
     207             : 
     208             :         @return  True if nChar is valid within an RFC 2047 <token> (US-ASCII
     209             :         'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '%', '&', ''', '*', '+',
     210             :         '-', '^', '_', '`', '{', '|', '}', or '~').
     211             :      */
     212             :     static bool isEncodedWordTokenChar(sal_uInt32 nChar);
     213             : 
     214             :     /** Check whether some character is valid within an RFC 2060 <atom>.
     215             : 
     216             :         @param nChar  Some UCS-4 character.
     217             : 
     218             :         @return  True if nChar is valid within an RFC 2060 <atom> (US-ASCII
     219             :         'A'--'Z', 'a'--'z', '0'--'9', '!', '#', '$', '&', ''', '+', ',', '-',
     220             :         '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '_', '`',
     221             :         '|', '}', or '~').
     222             :      */
     223             :     static bool isIMAPAtomChar(sal_uInt32 nChar);
     224             : 
     225             :     /** Get the digit weight of a US-ASCII character.
     226             : 
     227             :         @param nChar  Some UCS-4 character.
     228             : 
     229             :         @return  If nChar is a US-ASCII (decimal) digit character (US-ASCII
     230             :         '0'--'9'), return the corresponding weight (0--9); otherwise,
     231             :         return -1.
     232             :      */
     233             :     static inline int getWeight(sal_uInt32 nChar);
     234             : 
     235             :     /** Get the hexadecimal digit weight of a US-ASCII character.
     236             : 
     237             :         @param nChar  Some UCS-4 character.
     238             : 
     239             :         @return  If nChar is a US-ASCII hexadecimal digit character (US-ASCII
     240             :         '0'--'9', 'A'--'F', or 'a'--'f'), return the corresponding weight
     241             :         (0--15); otherwise, return -1.
     242             :      */
     243             :     static inline int getHexWeight(sal_uInt32 nChar);
     244             : 
     245             :     /** Get the Base 64 digit weight of a US-ASCII character.
     246             : 
     247             :         @param nChar  Some UCS-4 character.
     248             : 
     249             :         @return  If nChar is a US-ASCII Base 64 digit character (US-ASCII
     250             :         'A'--'F', or 'a'--'f', '0'--'9', '+', or '/'), return the
     251             :         corresponding weight (0--63); if nChar is the US-ASCII Base 64 padding
     252             :         character (US-ASCII '='), return -1; otherwise, return -2.
     253             :      */
     254             :     static inline int getBase64Weight(sal_uInt32 nChar);
     255             : 
     256             :     /** Get a hexadecimal digit encoded as US-ASCII.
     257             : 
     258             :         @param nWeight  Must be in the range 0--15, inclusive.
     259             : 
     260             :         @return  The canonic (i.e., upper case) hexadecimal digit
     261             :         corresponding to nWeight (US-ASCII '0'--'9' or 'A'--'F').
     262             :      */
     263             :     static sal_uInt32 getHexDigit(int nWeight);
     264             : 
     265             :     static inline bool isHighSurrogate(sal_uInt32 nUTF16);
     266             : 
     267             :     static inline bool isLowSurrogate(sal_uInt32 nUTF16);
     268             : 
     269             :     static inline sal_uInt32 toUTF32(sal_Unicode cHighSurrogate,
     270             :                                      sal_Unicode cLowSurrogate);
     271             : 
     272             :     /** Check two US-ASCII strings for equality, ignoring case.
     273             : 
     274             :         @param pBegin1  Points to the start of the first string, must not be
     275             :         null.
     276             : 
     277             :         @param pEnd1  Points past the end of the first string, must be >=
     278             :         pBegin1.
     279             : 
     280             :         @param pString2  Points to the start of the null terminated second
     281             :         string, must not be null.
     282             : 
     283             :         @return  True if the two strings are equal, ignoring the case of US-
     284             :         ASCII alphabetic characters (US-ASCII 'A'--'Z' and 'a'--'z').
     285             :      */
     286             :     static bool equalIgnoreCase(const sal_Char * pBegin1,
     287             :                                 const sal_Char * pEnd1,
     288             :                                 const sal_Char * pString2);
     289             : 
     290             :     /** Check two US-ASCII strings for equality, ignoring case.
     291             : 
     292             :         @param pBegin1  Points to the start of the first string, must not be
     293             :         null.
     294             : 
     295             :         @param pEnd1  Points past the end of the first string, must be >=
     296             :         pBegin1.
     297             : 
     298             :         @param pString2  Points to the start of the null terminated second
     299             :         string, must not be null.
     300             : 
     301             :         @return  True if the two strings are equal, ignoring the case of US-
     302             :         ASCII alphabetic characters (US-ASCII 'A'--'Z' and 'a'--'z').
     303             :      */
     304             :     static bool equalIgnoreCase(const sal_Unicode * pBegin1,
     305             :                                 const sal_Unicode * pEnd1,
     306             :                                 const sal_Char * pString2);
     307             : 
     308             :     static inline bool startsWithLineBreak(const sal_Char * pBegin,
     309             :                                            const sal_Char * pEnd);
     310             : 
     311             :     static inline bool startsWithLineBreak(const sal_Unicode * pBegin,
     312             :                                            const sal_Unicode * pEnd);
     313             : 
     314             :     static inline bool startsWithLineFolding(const sal_Char * pBegin,
     315             :                                              const sal_Char * pEnd);
     316             : 
     317             :     static inline bool startsWithLineFolding(const sal_Unicode * pBegin,
     318             :                                              const sal_Unicode * pEnd);
     319             : 
     320             :     static bool startsWithLinearWhiteSpace(const sal_Char * pBegin,
     321             :                                            const sal_Char * pEnd);
     322             : 
     323             :     static const sal_Unicode * skipLinearWhiteSpace(const sal_Unicode *
     324             :                                                         pBegin,
     325             :                                                     const sal_Unicode * pEnd);
     326             : 
     327             :     static const sal_Unicode * skipComment(const sal_Unicode * pBegin,
     328             :                                            const sal_Unicode * pEnd);
     329             : 
     330             :     static const sal_Unicode * skipLinearWhiteSpaceComment(const sal_Unicode *
     331             :                                                                pBegin,
     332             :                                                            const sal_Unicode *
     333             :                                                                pEnd);
     334             : 
     335             :     static inline bool needsQuotedStringEscape(sal_uInt32 nChar);
     336             : 
     337             :     static const sal_Char * skipQuotedString(const sal_Char * pBegin,
     338             :                                              const sal_Char * pEnd);
     339             : 
     340             :     static const sal_Unicode * skipQuotedString(const sal_Unicode * pBegin,
     341             :                                                 const sal_Unicode * pEnd);
     342             : 
     343             :     static bool scanUnsigned(const sal_Unicode *& rBegin,
     344             :                              const sal_Unicode * pEnd, bool bLeadingZeroes,
     345             :                              sal_uInt32 & rValue);
     346             : 
     347             :     static const sal_Unicode * scanQuotedBlock(const sal_Unicode * pBegin,
     348             :                                                const sal_Unicode * pEnd,
     349             :                                                sal_uInt32 nOpening,
     350             :                                                sal_uInt32 nClosing,
     351             :                                                sal_Size & rLength,
     352             :                                                bool & rModify);
     353             : 
     354             :     static sal_Unicode const * scanParameters(sal_Unicode const * pBegin,
     355             :                                               sal_Unicode const * pEnd,
     356             :                                               INetContentTypeParameterList *
     357             :                                                   pParameters);
     358             : 
     359             :     /** Parse the body of an RFC 2045 Content-Type header field.
     360             : 
     361             :         @param pBegin  The range (that must be valid) from non-null pBegin,
     362             :         inclusive. to non-null pEnd, exclusive, forms the body of the
     363             :         Content-Type header field.  It must be of the form
     364             : 
     365             :           token "/" token *(";" token "=" (token / quoted-string))
     366             : 
     367             :         with intervening linear white space and comments (cf. RFCs 822, 2045).
     368             :         The RFC 2231 extension are supported.  The encoding of rMediaType
     369             :         should be US-ASCII, but any Unicode values in the range U+0080..U+FFFF
     370             :         are interpretet 'as appropriate.'
     371             : 
     372             :         @param pType  If not null, returns the type (the first of the above
     373             :         tokens), in US-ASCII encoding and converted to lower case.
     374             : 
     375             :         @param pSubType  If not null, returns the sub-type (the second of the
     376             :         above tokens), in US-ASCII encoding and converted to lower case.
     377             : 
     378             :         @param pParameters  If not null, returns the parameters as a list of
     379             :         INetContentTypeParameters (the attributes are in US-ASCII encoding and
     380             :         converted to lower case, the values are in Unicode encoding).  If
     381             :         null, only the syntax of the parameters is checked, but they are not
     382             :         returned.
     383             : 
     384             :         @return  Null if the syntax of the field body is incorrect (i.e., does
     385             :         not start with type and sub-type tokens).  Otherwise, a pointer past the
     386             :         longest valid input prefix.  If null is returned, none of the output
     387             :         parameters will be modified.
     388             :      */
     389             :     static sal_Unicode const * scanContentType(
     390             :         sal_Unicode const *pBegin, sal_Unicode const * pEnd,
     391             :         OUString * pType = 0, OUString * pSubType = 0,
     392             :         INetContentTypeParameterList * pParameters = 0);
     393             : 
     394             :     static inline rtl_TextEncoding translateToMIME(rtl_TextEncoding
     395             :                                                        eEncoding);
     396             : 
     397             :     static inline rtl_TextEncoding translateFromMIME(rtl_TextEncoding
     398             :                                                          eEncoding);
     399             : 
     400             :     static const sal_Char * getCharsetName(rtl_TextEncoding eEncoding);
     401             : 
     402             :     static rtl_TextEncoding getCharsetEncoding(const sal_Char * pBegin,
     403             :                                                const sal_Char * pEnd);
     404             : 
     405             :     static inline bool isMIMECharsetEncoding(rtl_TextEncoding eEncoding);
     406             : 
     407             :     static INetMIMECharsetList_Impl *
     408             :     createPreferredCharsetList(rtl_TextEncoding eEncoding);
     409             : 
     410             :     static sal_Unicode * convertToUnicode(const sal_Char * pBegin,
     411             :                                           const sal_Char * pEnd,
     412             :                                           rtl_TextEncoding eEncoding,
     413             :                                           sal_Size & rSize);
     414             : 
     415             :     static sal_Char * convertFromUnicode(const sal_Unicode * pBegin,
     416             :                                          const sal_Unicode * pEnd,
     417             :                                          rtl_TextEncoding eEncoding,
     418             :                                          sal_Size & rSize);
     419             : 
     420             :     /** Get the number of octets required to encode an UCS-4 character using
     421             :         UTF-8 encoding.
     422             : 
     423             :         @param nChar  Some UCS-4 character.
     424             : 
     425             :         @return  The number of octets required (in the range 1--6, inclusive).
     426             :      */
     427             :     static inline int getUTF8OctetCount(sal_uInt32 nChar);
     428             : 
     429             :     static inline void writeEscapeSequence(INetMIMEOutputSink & rSink,
     430             :                                            sal_uInt32 nChar);
     431             : 
     432             :     static void writeUTF8(INetMIMEOutputSink & rSink, sal_uInt32 nChar);
     433             : 
     434             :     static void writeHeaderFieldBody(INetMIMEOutputSink & rSink,
     435             :                                      HeaderFieldType eType,
     436             :                                      const OUString& rBody,
     437             :                                      rtl_TextEncoding ePreferredEncoding,
     438             :                                      bool bInitialSpace = true);
     439             : 
     440             :     static bool translateUTF8Char(const sal_Char *& rBegin,
     441             :                                   const sal_Char * pEnd,
     442             :                                   rtl_TextEncoding eEncoding,
     443             :                                   sal_uInt32 & rCharacter);
     444             : 
     445             :     static OUString decodeHeaderFieldBody(HeaderFieldType eType,
     446             :                                            const OString& rBody);
     447             : 
     448             :     /** Get the UTF-32 character at the head of a UTF-16 encoded string.
     449             : 
     450             :         @param rBegin  Points to the start of the UTF-16 encoded string, must
     451             :         not be null.  On exit, it points past the first UTF-32 character's
     452             :         encoding.
     453             : 
     454             :         @param pEnd  Points past the end of the UTF-16 encoded string, must be
     455             :         strictly greater than rBegin.
     456             : 
     457             :         @return  The UCS-4 character at the head of the UTF-16 encoded string.
     458             :         If the string does not start with the UTF-16 encoding of a UCS-32
     459             :         character, the first UTF-16 value is returned.
     460             :      */
     461             :     static inline sal_uInt32 getUTF32Character(const sal_Unicode *& rBegin,
     462             :                                                const sal_Unicode * pEnd);
     463             : 
     464             :     /** Put the UTF-16 encoding of a UTF-32 character into a buffer.
     465             : 
     466             :         @param pBuffer  Points to a buffer, must not be null.
     467             : 
     468             :         @param nUTF32  An UTF-32 character, must be in the range 0..0x10FFFF.
     469             : 
     470             :         @return  A pointer past the UTF-16 characters put into the buffer
     471             :         (i.e., pBuffer + 1 or pBuffer + 2).
     472             :      */
     473             :     static inline sal_Unicode * putUTF32Character(sal_Unicode * pBuffer,
     474             :                                                   sal_uInt32 nUTF32);
     475             : };
     476             : 
     477             : // static
     478             : inline bool INetMIME::isISO88591(sal_uInt32 nChar)
     479             : {
     480             :     return nChar <= 0xFF;
     481             : }
     482             : 
     483             : // static
     484             : inline bool INetMIME::isControl(sal_uInt32 nChar)
     485             : {
     486             :     return nChar <= 0x1F || nChar == 0x7F;
     487             : }
     488             : 
     489             : // static
     490           0 : inline bool INetMIME::isWhiteSpace(sal_uInt32 nChar)
     491             : {
     492           0 :     return nChar == '\t' || nChar == ' ';
     493             : }
     494             : 
     495             : // static
     496        2260 : inline bool INetMIME::isVisible(sal_uInt32 nChar)
     497             : {
     498        2260 :     return nChar >= '!' && nChar <= '~';
     499             : }
     500             : 
     501             : // static
     502             : inline bool INetMIME::isBase64Digit(sal_uInt32 nChar)
     503             : {
     504             :     return rtl::isAsciiUpperCase(nChar) || rtl::isAsciiLowerCase(nChar) || rtl::isAsciiDigit(nChar)
     505             :            || nChar == '+' || nChar == '/';
     506             : }
     507             : 
     508             : // static
     509         248 : inline int INetMIME::getWeight(sal_uInt32 nChar)
     510             : {
     511         248 :     return rtl::isAsciiDigit(nChar) ? int(nChar - '0') : -1;
     512             : }
     513             : 
     514             : // static
     515      122272 : inline int INetMIME::getHexWeight(sal_uInt32 nChar)
     516             : {
     517      184428 :     return rtl::isAsciiDigit(nChar) ? int(nChar - '0') :
     518       60116 :            nChar >= 'A' && nChar <= 'F' ? int(nChar - 'A' + 10) :
     519      244544 :            nChar >= 'a' && nChar <= 'f' ? int(nChar - 'a' + 10) : -1;
     520             : }
     521             : 
     522             : // static
     523          24 : inline int INetMIME::getBase64Weight(sal_uInt32 nChar)
     524             : {
     525          42 :     return rtl::isAsciiUpperCase(nChar) ? int(nChar - 'A') :
     526           6 :            rtl::isAsciiLowerCase(nChar) ? int(nChar - 'a' + 26) :
     527           6 :            rtl::isAsciiDigit(nChar) ? int(nChar - '0' + 52) :
     528             :            nChar == '+' ? 62 :
     529             :            nChar == '/' ? 63 :
     530          54 :            nChar == '=' ? -1 : -2;
     531             : }
     532             : 
     533             : // static
     534        1614 : inline bool INetMIME::isHighSurrogate(sal_uInt32 nUTF16)
     535             : {
     536        1614 :     return nUTF16 >= 0xD800 && nUTF16 <= 0xDBFF;
     537             : }
     538             : 
     539             : // static
     540         122 : inline bool INetMIME::isLowSurrogate(sal_uInt32 nUTF16)
     541             : {
     542         122 :     return nUTF16 >= 0xDC00 && nUTF16 <= 0xDFFF;
     543             : }
     544             : 
     545             : // static
     546             : inline sal_uInt32 INetMIME::toUTF32(sal_Unicode cHighSurrogate,
     547             :                                     sal_Unicode cLowSurrogate)
     548             : {
     549             :     DBG_ASSERT(isHighSurrogate(cHighSurrogate)
     550             :                && isLowSurrogate(cLowSurrogate),
     551             :                "INetMIME::toUTF32(): Bad chars");
     552             :     return ((sal_uInt32(cHighSurrogate) & 0x3FF) << 10)
     553             :                | (sal_uInt32(cLowSurrogate) & 0x3FF);
     554             : }
     555             : 
     556             : // static
     557             : inline bool INetMIME::startsWithLineBreak(const sal_Char * pBegin,
     558             :                                           const sal_Char * pEnd)
     559             : {
     560             :     DBG_ASSERT(pBegin && pBegin <= pEnd,
     561             :                "INetMIME::startsWithLineBreak(): Bad sequence");
     562             : 
     563             :     return pEnd - pBegin >= 2 && pBegin[0] == 0x0D && pBegin[1] == 0x0A;
     564             :         // CR, LF
     565             : }
     566             : 
     567             : // static
     568           0 : inline bool INetMIME::startsWithLineBreak(const sal_Unicode * pBegin,
     569             :                                               const sal_Unicode * pEnd)
     570             : {
     571             :     DBG_ASSERT(pBegin && pBegin <= pEnd,
     572             :                "INetMIME::startsWithLineBreak(): Bad sequence");
     573             : 
     574           0 :     return pEnd - pBegin >= 2 && pBegin[0] == 0x0D && pBegin[1] == 0x0A;
     575             :         // CR, LF
     576             : }
     577             : 
     578             : // static
     579             : inline bool INetMIME::startsWithLineFolding(const sal_Char * pBegin,
     580             :                                             const sal_Char * pEnd)
     581             : {
     582             :     DBG_ASSERT(pBegin && pBegin <= pEnd,
     583             :                "INetMIME::startsWithLineFolding(): Bad sequence");
     584             : 
     585             :     return pEnd - pBegin >= 3 && pBegin[0] == 0x0D && pBegin[1] == 0x0A
     586             :            && isWhiteSpace(pBegin[2]); // CR, LF
     587             : }
     588             : 
     589             : // static
     590           0 : inline bool INetMIME::startsWithLineFolding(const sal_Unicode * pBegin,
     591             :                                             const sal_Unicode * pEnd)
     592             : {
     593             :     DBG_ASSERT(pBegin && pBegin <= pEnd,
     594             :                "INetMIME::startsWithLineFolding(): Bad sequence");
     595             : 
     596           0 :     return pEnd - pBegin >= 3 && pBegin[0] == 0x0D && pBegin[1] == 0x0A
     597           0 :            && isWhiteSpace(pBegin[2]); // CR, LF
     598             : }
     599             : 
     600             : // static
     601             : inline bool INetMIME::startsWithLinearWhiteSpace(const sal_Char * pBegin,
     602             :                                                  const sal_Char * pEnd)
     603             : {
     604             :     DBG_ASSERT(pBegin && pBegin <= pEnd,
     605             :                "INetMIME::startsWithLinearWhiteSpace(): Bad sequence");
     606             : 
     607             :     return pBegin != pEnd
     608             :            && (isWhiteSpace(*pBegin) || startsWithLineFolding(pBegin, pEnd));
     609             : }
     610             : 
     611             : // static
     612           0 : inline bool INetMIME::needsQuotedStringEscape(sal_uInt32 nChar)
     613             : {
     614           0 :     return nChar == '"' || nChar == '\\';
     615             : }
     616             : 
     617             : // static
     618           0 : inline rtl_TextEncoding INetMIME::translateToMIME(rtl_TextEncoding eEncoding)
     619             : {
     620             : #if defined WNT
     621             :     return eEncoding == RTL_TEXTENCODING_MS_1252 ?
     622             :                RTL_TEXTENCODING_ISO_8859_1 : eEncoding;
     623             : #else // WNT
     624           0 :     return eEncoding;
     625             : #endif // WNT
     626             : }
     627             : 
     628             : // static
     629           6 : inline rtl_TextEncoding INetMIME::translateFromMIME(rtl_TextEncoding
     630             :                                                         eEncoding)
     631             : {
     632             : #if defined WNT
     633             :     return eEncoding == RTL_TEXTENCODING_ISO_8859_1 ?
     634             :                RTL_TEXTENCODING_MS_1252 : eEncoding;
     635             : #else
     636           6 :     return eEncoding;
     637             : #endif
     638             : }
     639             : 
     640             : // static
     641           6 : inline bool INetMIME::isMIMECharsetEncoding(rtl_TextEncoding eEncoding)
     642             : {
     643           6 :     return ( rtl_isOctetTextEncoding(eEncoding) == sal_True );
     644             : }
     645             : 
     646             : // static
     647           0 : inline int INetMIME::getUTF8OctetCount(sal_uInt32 nChar)
     648             : {
     649             :     DBG_ASSERT(nChar < 0x80000000, "INetMIME::getUTF8OctetCount(): Bad char");
     650             : 
     651             :     return nChar < 0x80 ? 1 :
     652             :            nChar < 0x800 ? 2 :
     653             :            nChar <= 0x10000 ? 3 :
     654             :            nChar <= 0x200000 ? 4 :
     655           0 :            nChar <= 0x4000000 ? 5 : 6;
     656             : }
     657             : 
     658             : // static
     659    62103815 : inline sal_uInt32 INetMIME::getUTF32Character(const sal_Unicode *& rBegin,
     660             :                                               const sal_Unicode * pEnd)
     661             : {
     662             :     DBG_ASSERT(rBegin && rBegin < pEnd,
     663             :                "INetMIME::getUTF32Character(): Bad sequence");
     664    62103815 :     if (rBegin + 1 < pEnd && rBegin[0] >= 0xD800 && rBegin[0] <= 0xDBFF
     665           0 :         && rBegin[1] >= 0xDC00 && rBegin[1] <= 0xDFFF)
     666             :     {
     667           0 :         sal_uInt32 nUTF32 = sal_uInt32(*rBegin++ & 0x3FF) << 10;
     668           0 :         return (nUTF32 | (*rBegin++ & 0x3FF)) + 0x10000;
     669             :     }
     670             :     else
     671    62103815 :         return *rBegin++;
     672             : }
     673             : 
     674             : // static
     675           0 : inline sal_Unicode * INetMIME::putUTF32Character(sal_Unicode * pBuffer,
     676             :                                                  sal_uInt32 nUTF32)
     677             : {
     678             :     DBG_ASSERT(nUTF32 <= 0x10FFFF, "INetMIME::putUTF32Character(): Bad char");
     679           0 :     if (nUTF32 < 0x10000)
     680           0 :         *pBuffer++ = sal_Unicode(nUTF32);
     681             :     else
     682             :     {
     683           0 :         nUTF32 -= 0x10000;
     684           0 :         *pBuffer++ = sal_Unicode(0xD800 | (nUTF32 >> 10));
     685           0 :         *pBuffer++ = sal_Unicode(0xDC00 | (nUTF32 & 0x3FF));
     686             :     }
     687           0 :     return pBuffer;
     688             : }
     689             : 
     690             : class INetMIMEOutputSink
     691             : {
     692             : public:
     693             :     static sal_uInt32 const NO_LINE_LENGTH_LIMIT = SAL_MAX_UINT32;
     694             : 
     695             : private:
     696             :     sal_uInt32 m_nColumn;
     697             :     sal_uInt32 m_nLineLengthLimit;
     698             : 
     699             : protected:
     700             :     /** Write a sequence of octets.
     701             : 
     702             :         @param pBegin  Points to the start of the sequence, must not be null.
     703             : 
     704             :         @param pEnd  Points past the end of the sequence, must be >= pBegin.
     705             :      */
     706             :     virtual void writeSequence(const sal_Char * pBegin,
     707             :                                const sal_Char * pEnd) = 0;
     708             : 
     709             :     /** Write a null terminated sequence of octets (without the terminating
     710             :         null).
     711             : 
     712             :         @param pOctets  A null terminated sequence of octets, must not be
     713             :         null.
     714             : 
     715             :         @return  The length of pOctets (without the terminating null).
     716             :      */
     717             :     virtual sal_Size writeSequence(const sal_Char * pSequence);
     718             : 
     719             :     /** Write a sequence of octets.
     720             : 
     721             :         @descr  The supplied sequence of UCS-4 characters is interpreted as a
     722             :         sequence of octets.  It is an error if any of the elements of the
     723             :         sequence has a numerical value greater than 255.
     724             : 
     725             :         @param pBegin  Points to the start of the sequence, must not be null.
     726             : 
     727             :         @param pEnd  Points past the end of the sequence, must be >= pBegin.
     728             :      */
     729             :     virtual void writeSequence(const sal_uInt32 * pBegin,
     730             :                                const sal_uInt32 * pEnd);
     731             : 
     732             :     /** Write a sequence of octets.
     733             : 
     734             :         @descr  The supplied sequence of Unicode characters is interpreted as
     735             :         a sequence of octets.  It is an error if any of the elements of the
     736             :         sequence has a numerical value greater than 255.
     737             : 
     738             :         @param pBegin  Points to the start of the sequence, must not be null.
     739             : 
     740             :         @param pEnd  Points past the end of the sequence, must be >= pBegin.
     741             :      */
     742             :     virtual void writeSequence(const sal_Unicode * pBegin,
     743             :                                const sal_Unicode * pEnd);
     744             : 
     745             : public:
     746           0 :     INetMIMEOutputSink(sal_uInt32 nTheColumn = 0,
     747             :                        sal_uInt32 nTheLineLengthLimit
     748             :                            = INetMIME::SOFT_LINE_LENGTH_LIMIT):
     749           0 :         m_nColumn(nTheColumn), m_nLineLengthLimit(nTheLineLengthLimit) {}
     750             : 
     751           0 :     virtual ~INetMIMEOutputSink() {}
     752             : 
     753             :     /** Get the current column.
     754             : 
     755             :         @return  The current column (starting from zero).
     756             :      */
     757           0 :     sal_uInt32 getColumn() const { return m_nColumn; }
     758             : 
     759           0 :     sal_uInt32 getLineLengthLimit() const { return m_nLineLengthLimit; }
     760             : 
     761             :     void setLineLengthLimit(sal_uInt32 nTheLineLengthLimit)
     762             :     { m_nLineLengthLimit = nTheLineLengthLimit; }
     763             : 
     764             :     virtual ErrCode getError() const;
     765             : 
     766             :     /** Write a sequence of octets.
     767             : 
     768             :         @param pBegin  Points to the start of the sequence, must not be null.
     769             : 
     770             :         @param pEnd  Points past the end of the sequence, must be >= pBegin.
     771             :      */
     772             :     inline void write(const sal_Char * pBegin, const sal_Char * pEnd);
     773             : 
     774             :     /** Write a sequence of octets.
     775             : 
     776             :         @param pBegin  Points to the start of the sequence, must not be null.
     777             : 
     778             :         @param nLength  The length of the sequence.
     779             :      */
     780             :     void write(const sal_Char * pBegin, sal_Size nLength)
     781             :     { write(pBegin, pBegin + nLength); }
     782             : 
     783             :     /** Write a sequence of octets.
     784             : 
     785             :         @descr  The supplied sequence of UCS-4 characters is interpreted as a
     786             :         sequence of octets.  It is an error if any of the elements of the
     787             :         sequence has a numerical value greater than 255.
     788             : 
     789             :         @param pBegin  Points to the start of the sequence, must not be null.
     790             : 
     791             :         @param pEnd  Points past the end of the sequence, must be >= pBegin.
     792             :      */
     793             :     inline void write(const sal_uInt32 * pBegin, const sal_uInt32 * pEnd);
     794             : 
     795             :     /** Write a sequence of octets.
     796             : 
     797             :         @descr  The supplied sequence of Unicode characters is interpreted as
     798             :         a sequence of octets.  It is an error if any of the elements of the
     799             :         sequence has a numerical value greater than 255.
     800             : 
     801             :         @param pBegin  Points to the start of the sequence, must not be null.
     802             : 
     803             :         @param pEnd  Points past the end of the sequence, must be >= pBegin.
     804             :      */
     805             :     inline void write(const sal_Unicode * pBegin, const sal_Unicode * pEnd);
     806             : 
     807             :     /** Write a sequence of octets.
     808             : 
     809             :         @param rOctets  A OString, interpreted as a sequence of octets.
     810             : 
     811             :         @param nBegin  The offset of the first character to write.
     812             : 
     813             :         @param nEnd  The offset past the last character to write.
     814             :      */
     815             :     void write(const OString& rOctets, sal_Int32 nBegin, sal_Int32 nEnd)
     816             :     {
     817             :         writeSequence(rOctets.getStr() + nBegin, rOctets.getStr() + nEnd);
     818             :         m_nColumn += nEnd - nBegin;
     819             :     }
     820             : 
     821             :     /** Write a single octet.
     822             : 
     823             :         @param nOctet  Some octet.
     824             : 
     825             :         @return  This instance.
     826             :      */
     827             :     inline INetMIMEOutputSink & operator <<(sal_Char nOctet);
     828             : 
     829             :     /** Write a null terminated sequence of octets (without the terminating
     830             :         null).
     831             : 
     832             :         @param pOctets  A null terminated sequence of octets, must not be
     833             :         null.
     834             : 
     835             :         @return  This instance.
     836             :      */
     837             :     inline INetMIMEOutputSink & operator <<(const sal_Char * pOctets);
     838             : 
     839             :     /** Write a sequence of octets.
     840             : 
     841             :         @param rOctets  A OString, interpreted as a sequence of octets.
     842             : 
     843             :         @return  This instance.
     844             :      */
     845             :     INetMIMEOutputSink & operator <<(const OString& rOctets)
     846             :     {
     847             :         writeSequence(rOctets.getStr(), rOctets.getStr() + rOctets.getLength());
     848             :         m_nColumn += rOctets.getLength();
     849             :         return *this;
     850             :     }
     851             : 
     852             :     /** Call a manipulator function.
     853             : 
     854             :         @param  pManipulator  A manipulator function.
     855             : 
     856             :         @return  Whatever the manipulator function returns.
     857             :      */
     858             :     INetMIMEOutputSink &
     859           0 :     operator <<(INetMIMEOutputSink & (* pManipulator)(INetMIMEOutputSink &))
     860           0 :     { return pManipulator(*this); }
     861             : 
     862             :     /** Write a line end (CR LF).
     863             :      */
     864             :     void writeLineEnd();
     865             : 
     866             :     /** A manipulator function that writes a line end (CR LF).
     867             : 
     868             :         @param rSink  Some sink.
     869             : 
     870             :         @return  The sink rSink.
     871             :      */
     872             :     static inline INetMIMEOutputSink & endl(INetMIMEOutputSink & rSink);
     873             : };
     874             : 
     875             : inline void INetMIMEOutputSink::write(const sal_Char * pBegin,
     876             :                                       const sal_Char * pEnd)
     877             : {
     878             :     writeSequence(pBegin, pEnd);
     879             :     m_nColumn += pEnd - pBegin;
     880             : }
     881             : 
     882             : inline void INetMIMEOutputSink::write(const sal_uInt32 * pBegin,
     883             :                                       const sal_uInt32 * pEnd)
     884             : {
     885             :     writeSequence(pBegin, pEnd);
     886             :     m_nColumn += pEnd - pBegin;
     887             : }
     888             : 
     889           0 : inline void INetMIMEOutputSink::write(const sal_Unicode * pBegin,
     890             :                                       const sal_Unicode * pEnd)
     891             : {
     892           0 :     writeSequence(pBegin, pEnd);
     893           0 :     m_nColumn += pEnd - pBegin;
     894           0 : }
     895             : 
     896           0 : inline INetMIMEOutputSink & INetMIMEOutputSink::operator <<(sal_Char nOctet)
     897             : {
     898           0 :     writeSequence(&nOctet, &nOctet + 1);
     899           0 :     ++m_nColumn;
     900           0 :     return *this;
     901             : }
     902             : 
     903           0 : inline INetMIMEOutputSink & INetMIMEOutputSink::operator <<(const sal_Char *
     904             :                                                                 pOctets)
     905             : {
     906           0 :     m_nColumn += writeSequence(pOctets);
     907           0 :     return *this;
     908             : }
     909             : 
     910             : // static
     911           0 : inline INetMIMEOutputSink & INetMIMEOutputSink::endl(INetMIMEOutputSink &
     912             :                                                          rSink)
     913             : {
     914           0 :     rSink.writeLineEnd();
     915           0 :     return rSink;
     916             : }
     917             : 
     918             : // static
     919           0 : inline void INetMIME::writeEscapeSequence(INetMIMEOutputSink & rSink,
     920             :                                           sal_uInt32 nChar)
     921             : {
     922             :     DBG_ASSERT(nChar <= 0xFF, "INetMIME::writeEscapeSequence(): Bad char");
     923           0 :     rSink << '=' << sal_uInt8(getHexDigit(nChar >> 4))
     924           0 :           << sal_uInt8(getHexDigit(nChar & 15));
     925           0 : }
     926             : 
     927           0 : class INetMIMEStringOutputSink: public INetMIMEOutputSink
     928             : {
     929             :     OStringBuffer m_aBuffer;
     930             : 
     931             :     using INetMIMEOutputSink::writeSequence;
     932             : 
     933             :     virtual void writeSequence(const sal_Char * pBegin,
     934             :                                const sal_Char * pEnd) SAL_OVERRIDE;
     935             : 
     936             : public:
     937           0 :     inline INetMIMEStringOutputSink(sal_uInt32 nColumn = 0,
     938             :                                     sal_uInt32 nLineLengthLimit
     939             :                                         = INetMIME::SOFT_LINE_LENGTH_LIMIT):
     940           0 :         INetMIMEOutputSink(nColumn, nLineLengthLimit) {}
     941             : 
     942             :     virtual ErrCode getError() const SAL_OVERRIDE;
     943             : 
     944           0 :     OString takeBuffer()
     945             :     {
     946           0 :         return m_aBuffer.makeStringAndClear();
     947             :     }
     948             : };
     949             : 
     950             : class INetMIMEEncodedWordOutputSink
     951             : {
     952             : public:
     953             :     enum Context { CONTEXT_TEXT = 1,
     954             :                    CONTEXT_COMMENT = 2,
     955             :                    CONTEXT_PHRASE = 4 };
     956             : 
     957             :     enum Space { SPACE_NO, SPACE_ENCODED, SPACE_ALWAYS };
     958             : 
     959             : private:
     960             :     enum { BUFFER_SIZE = 256 };
     961             : 
     962             :     enum Coding { CODING_NONE, CODING_QUOTED, CODING_ENCODED,
     963             :                   CODING_ENCODED_TERMINATED };
     964             : 
     965             :     enum EncodedWordState { STATE_INITIAL, STATE_FIRST_EQUALS,
     966             :                             STATE_FIRST_QUESTION, STATE_CHARSET,
     967             :                             STATE_SECOND_QUESTION, STATE_ENCODING,
     968             :                             STATE_THIRD_QUESTION, STATE_ENCODED_TEXT,
     969             :                             STATE_FOURTH_QUESTION, STATE_SECOND_EQUALS,
     970             :                             STATE_BAD };
     971             : 
     972             :     INetMIMEOutputSink & m_rSink;
     973             :     Context m_eContext;
     974             :     Space m_eInitialSpace;
     975             :     sal_uInt32 m_nExtraSpaces;
     976             :     INetMIMECharsetList_Impl * m_pEncodingList;
     977             :     sal_Unicode * m_pBuffer;
     978             :     sal_uInt32 m_nBufferSize;
     979             :     sal_Unicode * m_pBufferEnd;
     980             :     Coding m_ePrevCoding;
     981             :     rtl_TextEncoding m_ePrevMIMEEncoding;
     982             :     Coding m_eCoding;
     983             :     sal_uInt32 m_nQuotedEscaped;
     984             :     EncodedWordState m_eEncodedWordState;
     985             : 
     986             :     inline bool needsEncodedWordEscape(sal_uInt32 nChar) const;
     987             : 
     988             :     void finish(bool bWriteTrailer);
     989             : 
     990             : public:
     991             :     inline INetMIMEEncodedWordOutputSink(INetMIMEOutputSink & rTheSink,
     992             :                                          Context eTheContext,
     993             :                                          Space eTheInitialSpace,
     994             :                                          rtl_TextEncoding ePreferredEncoding);
     995             : 
     996             :     ~INetMIMEEncodedWordOutputSink();
     997             : 
     998             :     INetMIMEEncodedWordOutputSink & operator <<(sal_uInt32 nChar);
     999             : 
    1000             :     inline void write(const sal_Char * pBegin, const sal_Char * pEnd);
    1001             : 
    1002             :     inline void write(const sal_Unicode * pBegin, const sal_Unicode * pEnd);
    1003             : 
    1004             :     inline bool flush();
    1005             : };
    1006             : 
    1007           0 : inline INetMIMEEncodedWordOutputSink::INetMIMEEncodedWordOutputSink(
    1008             :            INetMIMEOutputSink & rTheSink, Context eTheContext,
    1009             :            Space eTheInitialSpace, rtl_TextEncoding ePreferredEncoding):
    1010             :     m_rSink(rTheSink),
    1011             :     m_eContext(eTheContext),
    1012             :     m_eInitialSpace(eTheInitialSpace),
    1013             :     m_nExtraSpaces(0),
    1014           0 :     m_pEncodingList(INetMIME::createPreferredCharsetList(ePreferredEncoding)),
    1015             :     m_ePrevCoding(CODING_NONE),
    1016             :     m_ePrevMIMEEncoding(RTL_TEXTENCODING_DONTKNOW),
    1017             :     m_eCoding(CODING_NONE),
    1018             :     m_nQuotedEscaped(0),
    1019           0 :     m_eEncodedWordState(STATE_INITIAL)
    1020             : {
    1021           0 :     m_nBufferSize = BUFFER_SIZE;
    1022             :     m_pBuffer = static_cast< sal_Unicode * >(rtl_allocateMemory(
    1023             :                                                  m_nBufferSize
    1024           0 :                                                      * sizeof (sal_Unicode)));
    1025           0 :     m_pBufferEnd = m_pBuffer;
    1026           0 : }
    1027             : 
    1028             : inline void INetMIMEEncodedWordOutputSink::write(const sal_Char * pBegin,
    1029             :                                                  const sal_Char * pEnd)
    1030             : {
    1031             :     DBG_ASSERT(pBegin && pBegin <= pEnd,
    1032             :                "INetMIMEEncodedWordOutputSink::write(): Bad sequence");
    1033             : 
    1034             :     while (pBegin != pEnd)
    1035             :         operator <<(*pBegin++);
    1036             : }
    1037             : 
    1038           0 : inline void INetMIMEEncodedWordOutputSink::write(const sal_Unicode * pBegin,
    1039             :                                                  const sal_Unicode * pEnd)
    1040             : {
    1041             :     DBG_ASSERT(pBegin && pBegin <= pEnd,
    1042             :                "INetMIMEEncodedWordOutputSink::write(): Bad sequence");
    1043             : 
    1044           0 :     while (pBegin != pEnd)
    1045           0 :         operator <<(*pBegin++);
    1046           0 : }
    1047             : 
    1048           0 : inline bool INetMIMEEncodedWordOutputSink::flush()
    1049             : {
    1050           0 :     finish(true);
    1051           0 :     return m_ePrevCoding != CODING_NONE;
    1052             : }
    1053             : 
    1054          66 : struct INetContentTypeParameter
    1055             : {
    1056             :     /** The name of the attribute, in US-ASCII encoding and converted to lower
    1057             :         case.  If a parameter value is split as described in RFC 2231, there
    1058             :         will only be one item for the complete parameter, with the attribute
    1059             :         name lacking any section suffix.
    1060             :      */
    1061             :     const OString m_sAttribute;
    1062             : 
    1063             :     /** The optional character set specification (see RFC 2231), in US-ASCII
    1064             :         encoding and converted to lower case.
    1065             :      */
    1066             :     const OString m_sCharset;
    1067             : 
    1068             :     /** The optional language specification (see RFC 2231), in US-ASCII
    1069             :         encoding and converted to lower case.
    1070             :      */
    1071             :     const OString m_sLanguage;
    1072             : 
    1073             :     /** The attribute value.  If the value is a quoted-string, it is
    1074             :         'unpacked.'  If a character set is specified, and the value can be
    1075             :         converted to Unicode, this is done.  Also, if no character set is
    1076             :         specified, it is first tried to convert the value from UTF-8 encoding
    1077             :         to Unicode, and if that doesn't work (because the value is not in
    1078             :         UTF-8 encoding), it is converted from ISO-8859-1 encoding to Unicode
    1079             :         (which will always work).  But if a character set is specified and the
    1080             :         value cannot be converted from that character set to Unicode, special
    1081             :         action is taken to produce a value that can possibly be transformed
    1082             :         back into its original form:  Any 8-bit character from a non-encoded
    1083             :         part of the original value is directly converted to Unicode
    1084             :         (effectively handling it as if it was ISO-8859-1 encoded), and any
    1085             :         8-bit character from an encoded part of the original value is mapped
    1086             :         to the range U+F800..U+F8FF at the top of the Corporate Use Subarea
    1087             :         within Unicode's Private Use Area (effectively adding 0xF800 to the
    1088             :         character's numeric value).
    1089             :      */
    1090             :     const OUString m_sValue;
    1091             : 
    1092             :     /** This is true if the value is successfully converted to Unicode, and
    1093             :         false if the value is a special mixture of ISO-LATIN-1 characters and
    1094             :         characters from Unicode's Private Use Area.
    1095             :      */
    1096             :     const bool m_bConverted;
    1097             : 
    1098          22 :     INetContentTypeParameter(const OString& rTheAttribute,
    1099             :         const OString& rTheCharset, const OString& rTheLanguage,
    1100             :         const OUString& rTheValue, bool bTheConverted)
    1101             :     : m_sAttribute(rTheAttribute)
    1102             :     , m_sCharset(rTheCharset)
    1103             :     , m_sLanguage(rTheLanguage)
    1104             :     , m_sValue(rTheValue)
    1105          22 :     , m_bConverted(bTheConverted)
    1106             :     {
    1107          22 :     }
    1108             : };
    1109             : 
    1110         186 : class TOOLS_DLLPUBLIC INetContentTypeParameterList
    1111             : {
    1112             : public:
    1113             : 
    1114             :     void Clear();
    1115             : 
    1116             :     void Insert(INetContentTypeParameter * pParameter, sal_uIntPtr nIndex)
    1117             :     {
    1118             :         maEntries.insert(maEntries.begin()+nIndex,pParameter);
    1119             :     }
    1120             : 
    1121          22 :     void Append(INetContentTypeParameter *pParameter)
    1122             :     {
    1123          22 :         maEntries.push_back(pParameter);
    1124          22 :     }
    1125             : 
    1126             :     inline const INetContentTypeParameter * GetObject(sal_uIntPtr nIndex) const
    1127             :     {
    1128             :         return &(maEntries[nIndex]);
    1129             :     }
    1130             : 
    1131             :     const INetContentTypeParameter * find(const OString& rAttribute) const;
    1132             : 
    1133             : private:
    1134             : 
    1135             :     boost::ptr_vector<INetContentTypeParameter> maEntries;
    1136             : };
    1137             : 
    1138             : #endif
    1139             : 
    1140             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10