📄 msgpartc.c
字号:
/* * $Id: MsgPartC.C,v 1.3 2001/01/03 09:57:02 evgeny Exp $ * * Copyright (c) 1994 HAL Computer Systems International, Ltd. * * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. * 1315 Dell Avenue * Campbell, CA 95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include "MsgPartC.h"#include "ParamC.h"#include "HeaderC.h"#include "HeaderValC.h"#include "Mailcap.h"#include "QuotedP.h"#include "Base64.h"#include "MsgC.h"#include "FileMsgC.h"#include "MhMsgC.h"#include "FolderC.h"#include "UnixFolderC.h"#include "MimeEncode.h"#include <hgl/HalAppC.h>#include <hgl/SysErr.h>#include <hgl/PtrListC.h>#include <hgl/StringListC.h>#include <hgl/CharC.h>#include <hgl/RegexC.h>#include <unistd.h> #include <errno.h> #include <sys/stat.h> extern int debuglev;#define BUFLEN 1024/*--------------------------------------------------------------- * MsgPartC constructor */MsgPartC::MsgPartC(MsgPartC *parPart){ Init();//// These variables cannot be reset// parentMsg = NULL; parent = parPart; prev = NULL; next = NULL;}/*--------------------------------------------------------------- * Method to initialize variables */voidMsgPartC::Init(){ conType = CT_UNKNOWN; grpType = GT_UNKNOWN; accType = AT_INLINE; encType = ET_NONE; defConType = True; conParams = NULL; accParams = NULL; disParams = NULL; offset = 0; bytes = -1; lines = -1; headBytes = -1; headLines = -1; extOffset = -1; extBytes = -1; extLines = -1; extBlank = 0; bodyOffset = -1; bodyBytes = -1; bodyLines = -1; headers = NULL; extHeaders = NULL; subject = NULL; headScanned = False; bodyScanned = False; msgFile = ""; dataFile = ""; delMsgFile = False; delDataFile = False; childMsg = NULL; child = NULL;} // End Init/*--------------------------------------------------------------- * Method to delete variables */voidMsgPartC::Delete(){ while ( child ) { MsgPartC *next = child->next; delete child; child = next; } delete childMsg; delete conParams; delete accParams; delete disParams; if ( delMsgFile ) unlink(msgFile); if ( delDataFile ) unlink(dataFile); delete subject; delete headers; delete extHeaders;} // End Delete/*--------------------------------------------------------------- * Method to reset variables */voidMsgPartC::Reset(){ Delete(); Init();}/*--------------------------------------------------------------- * MsgPartC destructor */MsgPartC::~MsgPartC(){ Delete();}/*--------------------------------------------------------------- * Method to print */voidMsgPartC::Print(ostream& strm) const{ if ( debuglev == 0 ) return; StringC headStr; if ( IsMultipart() ) { if ( conStr.size() > 0 ) strm <<conStr <<" "; } else { if ( partNum.size() > 0 ) strm <<partNum <<" "; if ( conStr.size() > 0 ) strm <<conStr <<" "; headStr.Clear(); GetHeaderValue("Content-Disposition", headStr); if ( headStr.size() > 0 ) strm <<headStr <<" "; strm <<EncodingTypeStr(encType) <<" "; strm <<"(" <<lines <<" lines, " <<bytes <<" bytes @ " <<offset <<")" <<endl; } headStr.Clear(); GetDescription(headStr); if ( headStr.size() > 0 ) strm <<"\t" <<headStr <<endl; if ( debuglev > 1 ) { ParamC *param; for ( param=conParams; param; param=param->next ) strm <<" " <<*param; for ( param=accParams; param; param=param->next ) strm <<" " <<*param; for ( param=disParams; param; param=param->next ) strm <<" " <<*param; }} // End Print/*--------------------------------------------------------------- * Methods to query headers */HeaderC*MsgPartC::Header(CharC key) const{//// Loop through external headers// HeaderC *head = extHeaders; while ( head ) { if ( head->key.Equals(key, IGNORE_CASE) ) return head; head = head->next; }//// Loop through regular headers// head = headers; while ( head ) { if ( head->key.Equals(key, IGNORE_CASE) ) return head; head = head->next; } return NULL;} // End HeaderHeaderValC*MsgPartC::HeaderValue(CharC key) const{//// Look up header// HeaderC *head = Header(key); if ( head ) return head->value; return NULL;}voidMsgPartC::GetHeaderValue(CharC key, StringC& val) const{//// Look up header// HeaderC *head = Header(key); if ( head ) head->GetValueText(val);}/*--------------------------------------------------------------- * Method to return a pointer to the requested parameter */ParamC*MsgPartC::Param(CharC key) const{//// Check type, access and disposition parameters// ParamC *param = Param(key, conParams); if ( !param ) param = Param(key, accParams); if ( !param ) param = Param(key, disParams); return param;} // End Param/*--------------------------------------------------------------- * Method to return a pointer to the requested parameter */ParamC*MsgPartC::Param(CharC key, ParamC *list) const{//// Loop through list// ParamC *param; for ( param=list; param; param=param->next ) if ( param->key.Equals(key, IGNORE_CASE) ) return param; return NULL;} // End Param/*--------------------------------------------------------------- * Methods to add a parameter */voidMsgPartC::AddConParam(CharC key, CharC val){ if ( !conParams ) conParams = new ParamC(key, val); else AddParam(key, val, conParams);}voidMsgPartC::AddAccParam(CharC key, CharC val){ if ( !accParams ) accParams = new ParamC(key, val); else AddParam(key, val, accParams);}voidMsgPartC::AddDisParam(CharC key, CharC val){ if ( !disParams ) disParams = new ParamC(key, val); else AddParam(key, val, disParams);}voidMsgPartC::AddParam(CharC key, CharC val, ParamC *params){//// See if this parameter is already defined// ParamC *param = Param(key, params);//// If it is, check the value. Change it if necessary// if ( param ) { if ( !param->val.Equals(val, IGNORE_CASE) ) param->SetValue(val); }//// Create a new parameter at the end of the list// else { param = params; while ( param->next ) param = param->next; param->next = new ParamC(key, val); }} // End AddParam/*--------------------------------------------------------------- * Method to calculate part number */voidMsgPartC::SetPartNumber(char *num){ if ( IsMultipart() ) {//// See how many children we have// int partCount = ChildCount(); if ( partCount == 1 ) child->SetPartNumber(num); else { int index = 1; StringC partStr; MsgPartC *part = child; while ( part ) { if ( parent ) { partStr = num; partStr += "."; } else partStr.Clear(); partStr += index; part->SetPartNumber(partStr); index++; part = part->next; } } } // End if this is a multipart else { partNum = num;//// message/rfc822 can have a single child// if ( child ) { StringC partStr = num; if ( !child->IsMultipart() ) partStr += ".1"; child->SetPartNumber(partStr); } }} // End SetPartNumber/*--------------------------------------------------------------- * Method to calculate the maximum length of all part numbers */intMsgPartC::GetPartNumberMaxSize(){ if ( IsMultipart() || (Is822() && child) ) {//// Loop through children// int maxSize = 0; if ( !IsMultipart() ) maxSize = partNum.size(); MsgPartC *part; for (part=child; part; part=part->next) { int size = part->GetPartNumberMaxSize(); if ( size > maxSize ) maxSize = size; } return maxSize; } return partNum.size(); } // End GetPartNumberMaxSize/*--------------------------------------------------------------- * Method to set the length of all part numbers */voidMsgPartC::SetPartNumberSize(int size){ if ( !IsMultipart() ) {#if 0 int pad = size - partNum.size(); int i=0; for (i=0; i<pad; i++) partNum += ' ';#endif if ( child ) child->SetPartNumberSize(size); } else {//// Loop through children// MsgPartC *part; for (part=child; part; part=part->next) part->SetPartNumberSize(size); }} // End SetPartNumberSize/*--------------------------------------------------------------- * Method to find a part matching the specified part number */MsgPartC*MsgPartC::FindPart(CharC num){ if ( !IsMultipart() ) { CharC tmp = partNum; tmp.Trim(); if ( tmp == num ) return this; if ( child ) return child->FindPart(num); } else {//// Loop through children// MsgPartC *part; for (part=child; part; part=part->next) { MsgPartC *found = part->FindPart(num); if ( found ) return found; } } return NULL;} // End FindPart/*--------------------------------------------------------------- * Method to update the part offset */voidMsgPartC::Move(long headDelta, long bodyDelta){ offset = (u_int)((long)offset + headDelta); bodyOffset = (u_int)((long)bodyOffset + bodyDelta); if ( IsExternal() ) extOffset = (u_int)((long)extOffset + bodyDelta); int newHeadBytes = bodyOffset - offset - 1; if ( newHeadBytes > headBytes ) { headLines++; // Assume a Status line was added headBytes = newHeadBytes; }//// Loop through children// MsgPartC *part; for (part=child; part; part=part->next) part->Move(headDelta, bodyDelta);}/*----------------------------------------------------------------------- * Method to return best alternative. The best alternative for printing * may be different than the best alternative for display. */MsgPartC*MsgPartC::BestAlternative(Boolean forPrinting) const{ if ( !IsAlternative() || !child ) return NULL; MsgPartC *lastChild = NULL; MsgPartC *cp = child;//// Loop through children// Boolean done = False; while ( !done && cp ) {//// Check the recognized types// if ( forPrinting ) {//// Can't print most external bodies// if ( cp->IsExternal() && !cp->IsLocal() ) done = True; else if ( cp->IsOctet() || cp->IsJPEG() || cp->IsGIF() || cp->IsAudio() || cp->IsMPEG() ) done = True;//// If this is an unknown type, see if there's a mailcap entry// else if ( cp->IsUnknown() ) { MailcapC *mcap = MailcapEntry(cp); done = (!mcap || mcap->print.size()==0); } } // End if for printing else if ( cp->IsPlainText() || cp->IsRichText() || cp->IsEnriched() || cp->IsMixed() || cp->IsAlternative() || cp->IsDigest() || // cp->IsParallel() || cp->Is822() || // cp->IsPartial() || cp->IsOctet() || cp->IsPostScript() || cp->IsJPEG() || cp->IsGIF() || cp->IsAudio() || cp->IsMPEG() ) done = False;//// If this is an unknown type, see if there's a mailcap entry// else if ( cp->conType == CT_UNKNOWN ) { MailcapC *mcap = MailcapEntry(cp); done = (!mcap || mcap->present.size()==0); } else done = True;//// Mark this one if it was ok// if ( !done ) { lastChild = cp; cp = cp->next; } } // End for each child//// If there are no known types, use the last one// if ( !lastChild ) { lastChild = child;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -