smsdecoder.cpp
来自「Qtopia下的邮件处理程序」· C++ 代码 · 共 879 行 · 第 1/2 页
CPP
879 行
};class EmsAttachmentPart : public EmsPart{public: QString source() const { return _source; } void setSource( const QString& value ) { _source = value; } QString name() const { return _name; } void setName( const QString& value ) { _name = value; } virtual void startFormat( EmsFormatter& formatter );private: QString _source; QString _name;};EmsFormatter::~EmsFormatter(){ delete _parts;}void EmsFormatter::addQuotedText( const QString& value, uint start, uint end ){ uint posn = start; while ( posn < end ) { switch ( (value[posn]).toAscii() ) { case '&': { addText( value.mid( start, posn - start ) ); addText( "&" ); start = posn + 1; } break; case '<': { addText( value.mid( start, posn - start ) ); addText( "<" ); start = posn + 1; } break; case '>': { addText( value.mid( start, posn - start ) ); addText( ">" ); start = posn + 1; } break; case '\r': { addText( value.mid( start, posn - start ) ); addText("<br>"); if ( ( posn + 1 ) < end && value[posn + 1] == '\n' ) ++posn; start = posn + 1; } break; case '\n': { addText( value.mid( start, posn - start ) ); addText("<br>"); start = posn + 1; } break; default: break; } ++posn; } if ( start < end ) { addText( value.mid( start, end - start ) ); }}void EmsFormatter::addPart( EmsPart *part ){ EmsPart *current = _parts; EmsPart *prev = 0; while ( current != 0 ) { if ( current->_start > part->_start ) { break; } if ( current->_start == part->_start ) { // Insert zero-length image and sound parts after // text formatting parts that refer to the range. // This makes the formatting apply to the image or // sound part as well. if ( current->_length <= part->_length ) break; } prev = current; current = current->_next; } if ( prev ) { part->_next = prev->_next; prev->_next = part; } else { part->_next = _parts; _parts = part; }}void EmsFormatter::flushParts( const QString& text, bool final ){ uint posn; uint last = 0; EmsPart *part; // Output parts that are interspersed with the text. for ( posn = 0; posn < (uint)text.length(); ++posn ) { part = _parts; while ( part != 0 ) { if ( (uint)part->start() == posn ) { if ( last < posn ) { addQuotedText( text, last, posn ); last = posn; } part->startFormat( *this ); } if ( (uint)( part->start() + part->length() ) == posn ) { if ( last < posn ) { addQuotedText( text, last, posn ); last = posn; } part->endFormat( *this ); } part = part->_next; } } // Output the remaining text. if ( last < (uint)text.length() ) { addQuotedText( text, last, text.length() ); last = text.length(); } // Output any parts that appear after the end of the text. part = _parts; while ( part != 0 ) { if ( (uint)part->start() >= last ) { part->startFormat( *this ); part->endFormat( *this ); } part = part->_next; } delete _parts; _parts = 0; // Flush the remaining close tags. if ( final ) { _text += _closeTags + _closeAlignmentTags; _closeTags = QString(); _closeAlignmentTags = QString(); _alignment = 0; } else { _text += _closeTags; _closeTags = QString(); }}EmsPart::~EmsPart(){ if ( _next ) delete _next;}void EmsPart::startFormat( EmsFormatter& ){ // Nothing to do here.}void EmsPart::endFormat( EmsFormatter& ){ // Nothing to do here.}void EmsTextFormattingPart::startFormat( EmsFormatter& formatter ){ QString pending; QString pendingAlignment; QString openTags; QString openAlignmentTags; QString closeTags; QString closeAlignmentTags; static const char *colorMap[16] = { "000000", "808080", "800000", "808000", "008000", "008080", "000080", "800080", "C0C0C0", "FFFFFF", "FF0000", "FFFF00", "00FF00", "00FFFF", "0000FF", "FF00FF" }; // Get the pending close tags to reset the previous text format. pending = formatter.closeTags(); pendingAlignment = formatter.closeAlignmentTags(); // Build the new open and close tags for this range. if ( ( _format & 0x03 ) == 0x01 ) { openAlignmentTags = "<center>"; closeAlignmentTags = "</center>"; } else if ( ( _format & 0x03 ) == 0x02 ) { openAlignmentTags = "<p align=\"right\">"; closeAlignmentTags = "</p>"; } if ( _hasColors ) { openTags += "<font color=\"#" + QString( colorMap[_colors & 0x0F] ) + "\">"; closeTags = "</font>" + closeTags; } if ( ( _format & 0x0C ) == 0x04 ) { openTags += "<big>"; closeTags = "</big>" + closeTags; } else if ( ( _format & 0x0C ) == 0x08 ) { openTags += "<small>"; closeTags = "</small>" + closeTags; } if ( ( _format & 0x10 ) != 0x00 ) { openTags += "<b>"; closeTags = "</b>" + closeTags; } if ( ( _format & 0x20 ) != 0x00 ) { openTags += "<i>"; closeTags = "</i>" + closeTags; } if ( ( _format & 0x40 ) != 0x00 ) { openTags += "<u>"; closeTags = "</u>" + closeTags; } if ( ( _format & 0x80 ) != 0x00 ) { openTags += "<strike>"; closeTags = "</strike>" + closeTags; } // Update the current view of the tags. if ( ( _format & 0x03 ) != formatter.alignment() ) { pending += pendingAlignment; openTags = openAlignmentTags + openTags; } formatter.setAlignment( _format & 0x03 ); formatter.setCloseTags( closeTags ); formatter.setCloseAlignmentTags( closeAlignmentTags ); // Add the formatting tags to output at this location. formatter.addText( pending + openTags );}void EmsTextFormattingPart::endFormat( EmsFormatter& formatter ){ // If the length is zero, then we have set a default and we don't // want to reset it until the next text formatting change. if ( length() == 0 ) { return; } // Add the accumulated format close tags, but not the alignment tags. formatter.addText( formatter.closeTags() ); formatter.setCloseTags( QString() );}void EmsImagePart::startFormat( EmsFormatter& formatter ){ formatter.addText( "<img src=\"" + _source + "\">" );}void EmsAttachmentPart::startFormat( EmsFormatter& formatter ){ formatter.addText( "<a href=\"" + _source + "\">" + _name + "</a>" );}// Predefined EMS image types, from GSM 23.040, section 9.2.3.24.10.3.3.static const char * const predefinedImages[15] = { "ironic", // No tr "glad", // No tr "skeptical", // No tr "sad", // No tr "wow", // No tr "crying", // No tr "winking", // No tr "laughing", // No tr "indifferent", // No tr "kissing", // No tr "confused", // No tr "tongue", // No tr "angry", // No tr "glasses", // No tr "devil" // No tr};void SMSDecoder::formatMessage( MailMessage& mail, const QSMSMessage& msg ){ QList<QSMSMessagePart> parts = msg.parts(); uint part; bool hasDatagram = false; QString mimeType; uint position; uint partNum = 1; EmsFormatter formatter; QString id; for ( part = 0; part < (uint)parts.count(); ++part ) { if ( parts[part].isText() ) { // Process the parts that relate to this text part. formatter.flushParts( parts[part].text() ); } else { mimeType = parts[part].mimeType(); position = parts[part].position(); if ( mimeType.startsWith( "application/x-qtopia-wdp" ) ) { // The message contains a WDP datagram, which we // need to process separately below. hasDatagram = true; } else if ( mimeType.startsWith( "image/" ) ) { // Process an inline image. EmsImagePart *emsPart = new EmsImagePart(); emsPart->setStart( position ); id = "part" + QString::number( partNum ) + "@local"; emsPart->setSource( "cid:" + id ); formatter.addPart( emsPart ); MailMessagePart mpart; mpart.setContentType( mimeType ); mpart.setContentID( "<" + id + ">" ); mpart.setEncodedBody ( MailMessage::encodeBase64( parts[part].data() ), Base64 ); mail.addMessagePart( mpart ); ++partNum; } else if ( mimeType == "application/x-qtopia-sms-10" ) { // EMS text formatting information. QByteArray contents = parts[part].data(); if ( contents.count() >= 3 ) { EmsTextFormattingPart *emsPart; emsPart = new EmsTextFormattingPart(); emsPart->setStart( contents[0] & 0xFF ); emsPart->setLength( contents[1] & 0xFF ); emsPart->setFormat( contents[2] & 0xFF ); if ( contents.count() >= 4 ) { emsPart->setColors( contents[3] & 0xFF ); } formatter.addPart( emsPart ); } } else if ( mimeType == "application/x-qtopia-predefined-animation" ) { // EMS predefined animation. if ( parts[part].data().count() > 0 ) { int imageNum = parts[part].data()[0] & 0xFF; if ( imageNum < 15 ) { EmsImagePart *emsPart = new EmsImagePart(); emsPart->setStart( position ); emsPart->setSource ( QString( "x-sms-predefined:" ) + // No tr predefinedImages[imageNum] ); formatter.addPart( emsPart ); } } } else { // Everything else is inserted inline as-is. EmsAttachmentPart *emsPart = new EmsAttachmentPart(); emsPart->setStart( position ); id = "part" + QString::number( partNum ) + "@local"; emsPart->setSource( "cid:" + id ); emsPart->setName( QObject::tr("Attachment: ") + mimeType ); formatter.addPart( emsPart ); MailMessagePart mpart; mpart.setContentType( mimeType ); mpart.setContentID( "<" + id + ">" ); mpart.setEncodedBody ( MailMessage::encodeBase64( parts[part].data() ), Base64 ); mpart.setName( "part" + QString::number( partNum ) ); mail.addMessagePart( mpart ); ++partNum; } } } // Flush the remaining parts and get the resultant text/html. formatter.flushParts( "", true ); if ( formatter.text().length() != 0 ) { MailMessagePart htmlPart; QByteArray toUtf8 = formatter.text().toUtf8(); QByteArray array(toUtf8.length(),0); memcpy( array.data(), toUtf8.data(), toUtf8.length() ); htmlPart.setContentType( "text/html; charset=utf-8" ); htmlPart.setEncodedBody ( MailMessage::encodeQuotedPrintable( array ), QuotedPrintable ); mail.setMultipartRelated( true ); mail.prependMessagePart( htmlPart ); } // If we saw a WDP datagram, then we need to process it now. if ( hasDatagram ) { int port = msg.destinationPort(); QString type = SMSDecoder::mimeTypeForPort( port ); SMSDecoder *decoder; MailMessagePart mpart; if ( !type.isNull() ) { // We know the MIME type for this port number. mpart.setContentType( type ); if ( type.startsWith( "text/" ) ) { mpart.setEncodedBody ( MailMessage::encodeQuotedPrintable ( msg.applicationData() ), QuotedPrintable ); } else { mpart.setEncodedBody ( MailMessage::encodeBase64( msg.applicationData() ), Base64 ); } mail.addMessagePart( mpart ); } else if ( ( decoder = SMSDecoder::decoder( port ) ) != 0 ) { // Use the decoder to turn the datagram into something useful. decoder->decode( mail, msg ); delete decoder; } else { // We don't know what to do with this kind of datagram. mpart.setContentType ( "application/x-smsapp-" + QString::number( port ) ); mpart.setEncodedBody ( MailMessage::encodeBase64( msg.applicationData() ), Base64 ); mail.addMessagePart( mpart ); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?