/** @short Decode RFC2231-style eextended parameter values into a real Unicode string */ QString extractRfc2231Param(const QMap<QByteArray, QByteArray> ¶meters, const QByteArray &key) { QMap<QByteArray, QByteArray>::const_iterator it = parameters.constFind(key); if (it != parameters.constEnd()) { // This parameter is not using the RFC 2231 syntax for extended parameters. // I have no idea whether this is correct, but I *guess* that trying to use RFC2047 is not going to hurt. return decodeRFC2047String(*it); } if (parameters.constFind(key + "*0") != parameters.constEnd()) { // There's a 2231-style continuation *without* the language/charset extension QByteArray raw; int num = 0; while ((it = parameters.constFind(key + '*' + QByteArray::number(num++))) != parameters.constEnd()) { raw += *it; } return decodeRFC2047String(raw); } QByteArray raw; if ((it = parameters.constFind(key + '*')) != parameters.constEnd()) { // No continuation, but language/charset is present raw = *it; } else if (parameters.constFind(key + "*0*") != parameters.constEnd()) { // Both continuation *and* the lang/charset extension are in there int num = 0; // The funny thing is that the other values might or might not end with the trailing star, // at least according to the example in the RFC do { if ((it = parameters.constFind(key + '*' + QByteArray::number(num))) != parameters.constEnd()) raw += *it; else if ((it = parameters.constFind(key + '*' + QByteArray::number(num) + '*')) != parameters.constEnd()) raw += *it; ++num; } while (it != parameters.constEnd()); } // Process 2231-style language/charset continuation, if present int pos1 = raw.indexOf('\'', 0); int pos2 = raw.indexOf('\'', qMax(1, pos1 + 1)); if (pos1 != -1 && pos2 != -1) { return decodeByteArray(translatePercentToBin(raw.mid(pos2 + 1)), raw.left(pos1)); } // Fallback: it could be empty, or otherwise malformed. Just treat it as UTF-8 for compatibility return QString::fromUtf8(raw); }
//----------------------------------------------------------------------------- void KMMsgInfo::init(const QCString& aSubject, const QCString& aFrom, const QCString& aTo, time_t aDate, KMMsgStatus aStatus, const QCString& aXMark, const QCString& replyToId, const QCString& replyToAuxId, const QCString& msgId, KMMsgEncryptionState encryptionState, KMMsgSignatureState signatureState, KMMsgMDNSentState mdnSentState, const QCString& prefCharset, off_t aFolderOffset, size_t aMsgSize, size_t aMsgSizeServer, ulong aUID) { mIndexOffset = 0; mIndexLength = 0; if(!kd) kd = new KMMsgInfoPrivate; kd->modifiers = KMMsgInfoPrivate::ALL_SET; kd->subject = decodeRFC2047String(aSubject, prefCharset); kd->from = decodeRFC2047String( KMMessage::stripEmailAddr( aFrom ), prefCharset ); kd->to = decodeRFC2047String( KMMessage::stripEmailAddr( aTo ), prefCharset ); kd->replyToIdMD5 = base64EncodedMD5( replyToId ); kd->replyToAuxIdMD5 = base64EncodedMD5( replyToAuxId ); kd->strippedSubjectMD5 = base64EncodedMD5( KMMessage::stripOffPrefixes( kd->subject ), true /*utf8*/ ); kd->msgIdMD5 = base64EncodedMD5( msgId ); kd->xmark = aXMark; kd->folderOffset = aFolderOffset; mStatus = aStatus; kd->msgSize = aMsgSize; kd->date = aDate; kd->file = ""; kd->encryptionState = encryptionState; kd->signatureState = signatureState; kd->mdnSentState = mdnSentState; kd->msgSizeServer = aMsgSizeServer; kd->UID = aUID; mDirty = false; }