You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
447 lines
11 KiB
447 lines
11 KiB
15 years ago
|
//=============================================================================
|
||
|
// File: disptype.cpp
|
||
|
// Contents: Definitions for DwDispositionType
|
||
|
// Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
|
||
|
// WWW: http://www.fwb.gulf.net/~dwsauder/mimepp.html
|
||
|
//
|
||
|
// Copyright (c) 1996, 1997 Douglas W. Sauder
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
|
||
|
// INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
|
||
|
// THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
|
||
|
// HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
//
|
||
|
// DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
|
||
|
// NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||
|
// PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
|
||
|
// BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
|
||
|
// SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
#define DW_IMPLEMENTATION
|
||
|
|
||
|
#include <mimelib/config.h>
|
||
|
#include <mimelib/debug.h>
|
||
|
#include <mimelib/string.h>
|
||
|
#include <mimelib/param.h>
|
||
|
#include <mimelib/disptype.h>
|
||
|
#include <mimelib/token.h>
|
||
|
#include <mimelib/enum.h>
|
||
|
|
||
|
|
||
|
const char* const DwDispositionType::sClassName = "DwDispositionType";
|
||
|
|
||
|
|
||
|
DwDispositionType* (*DwDispositionType::sNewDispositionType)(
|
||
|
const DwString&, DwMessageComponent*) = 0;
|
||
|
|
||
|
|
||
|
DwDispositionType* DwDispositionType::NewDispositionType(
|
||
|
const DwString& aStr, DwMessageComponent* aParent)
|
||
|
{
|
||
|
if (sNewDispositionType) {
|
||
|
return sNewDispositionType(aStr, aParent);
|
||
|
}
|
||
|
else {
|
||
|
return new DwDispositionType(aStr, aParent);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
DwDispositionType::DwDispositionType()
|
||
|
{
|
||
|
mDispositionType = DwMime::kDispTypeNull;
|
||
|
mFirstParameter = 0;
|
||
|
mClassId = kCidDispositionType;
|
||
|
mClassName = sClassName;
|
||
|
}
|
||
|
|
||
|
|
||
|
DwDispositionType::DwDispositionType(const DwDispositionType& aDispType)
|
||
|
: DwFieldBody(aDispType),
|
||
|
mDispositionTypeStr(aDispType.mDispositionTypeStr),
|
||
|
mFilenameStr(aDispType.mFilenameStr)
|
||
|
{
|
||
|
mFirstParameter = 0;
|
||
|
mDispositionType = aDispType.mDispositionType;
|
||
|
if (aDispType.mFirstParameter) {
|
||
|
CopyParameterList(aDispType.mFirstParameter);
|
||
|
}
|
||
|
mClassId = kCidDispositionType;
|
||
|
mClassName = sClassName;
|
||
|
}
|
||
|
|
||
|
|
||
|
DwDispositionType::DwDispositionType(const DwString& aStr,
|
||
|
DwMessageComponent* aParent)
|
||
|
: DwFieldBody(aStr, aParent)
|
||
|
{
|
||
|
mDispositionType = DwMime::kDispTypeNull;
|
||
|
mFirstParameter = 0;
|
||
|
mClassId = kCidDispositionType;
|
||
|
mClassName = sClassName;
|
||
|
}
|
||
|
|
||
|
|
||
|
DwDispositionType::~DwDispositionType()
|
||
|
{
|
||
|
if (mFirstParameter) {
|
||
|
DeleteParameterList();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
const DwDispositionType& DwDispositionType::operator = (
|
||
|
const DwDispositionType& aDispType)
|
||
|
{
|
||
|
if (this == &aDispType) return *this;
|
||
|
mDispositionType = aDispType.mDispositionType;
|
||
|
mDispositionTypeStr = aDispType.mDispositionTypeStr;
|
||
|
mFilenameStr = aDispType.mFilenameStr;
|
||
|
|
||
|
if (mFirstParameter) {
|
||
|
DeleteParameterList();
|
||
|
}
|
||
|
if (aDispType.mFirstParameter) {
|
||
|
CopyParameterList(aDispType.mFirstParameter);
|
||
|
}
|
||
|
|
||
|
if (mParent) {
|
||
|
mParent->SetModified();
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
int DwDispositionType::DispositionType() const
|
||
|
{
|
||
|
return mDispositionType;
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::SetDispositionType(int aType)
|
||
|
{
|
||
|
mDispositionType = aType;
|
||
|
EnumToStr();
|
||
|
SetModified();
|
||
|
}
|
||
|
|
||
|
|
||
|
const DwString& DwDispositionType::DispositionTypeStr() const
|
||
|
{
|
||
|
return mDispositionTypeStr;
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::SetDispositionTypeStr(const DwString& aStr)
|
||
|
{
|
||
|
mDispositionTypeStr = aStr;
|
||
|
StrToEnum();
|
||
|
SetModified();
|
||
|
}
|
||
|
|
||
|
|
||
|
const DwString& DwDispositionType::Filename() const
|
||
|
{
|
||
|
DwParameter* param = mFirstParameter;
|
||
|
while (param) {
|
||
|
if (DwStrcasecmp(param->Attribute(), "filename") == 0) {
|
||
|
// Filename parameter found. Return its value.
|
||
|
// Implementation note: this member function is const, which
|
||
|
// forbids us from assigning to mFilenameStr. The following
|
||
|
// trick gets around this. (ANSI implementations could use the
|
||
|
// "mutable" declaration).
|
||
|
DwDispositionType* _this = (DwDispositionType*) this;
|
||
|
_this->mFilenameStr = param->Value();
|
||
|
break;
|
||
|
}
|
||
|
param = param->Next();
|
||
|
}
|
||
|
return mFilenameStr;
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::SetFilename(const DwString& aStr)
|
||
|
{
|
||
|
mFilenameStr = aStr;
|
||
|
// Search for filename parameter in parameter list. If found, set its
|
||
|
// value.
|
||
|
DwParameter* param = mFirstParameter;
|
||
|
while (param) {
|
||
|
if (DwStrcasecmp(param->Attribute(), "filename") == 0) {
|
||
|
param->SetValue(mFilenameStr);
|
||
|
return;
|
||
|
}
|
||
|
param = param->Next();
|
||
|
}
|
||
|
// Boundary parameter not found. Add it.
|
||
|
param = DwParameter::NewParameter("", 0);
|
||
|
param->SetAttribute("Filename");
|
||
|
param->SetValue(aStr);
|
||
|
AddParameter(param);
|
||
|
}
|
||
|
|
||
|
|
||
|
DwParameter* DwDispositionType::FirstParameter() const
|
||
|
{
|
||
|
return mFirstParameter;
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::AddParameter(DwParameter* aParam)
|
||
|
{
|
||
|
_AddParameter(aParam);
|
||
|
SetModified();
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::_AddParameter(DwParameter* aParam)
|
||
|
{
|
||
|
if (!mFirstParameter) {
|
||
|
mFirstParameter = aParam;
|
||
|
}
|
||
|
else {
|
||
|
DwParameter* cur = mFirstParameter;
|
||
|
if( cur ) {
|
||
|
DwParameter* next = cur->Next();
|
||
|
while (next) {
|
||
|
cur = next;
|
||
|
next = cur->Next();
|
||
|
}
|
||
|
cur->SetNext(aParam);
|
||
|
}
|
||
|
}
|
||
|
aParam->SetParent(this);
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::Parse()
|
||
|
{
|
||
|
mIsModified = 0;
|
||
|
mDispositionType = DwMime::kDispTypeNull;
|
||
|
mDispositionTypeStr = "";
|
||
|
if (mFirstParameter) {
|
||
|
DeleteParameterList();
|
||
|
}
|
||
|
if (mString.length() == 0) return;
|
||
|
DwRfc1521Tokenizer tokenizer(mString);
|
||
|
int found = 0;
|
||
|
while (!found && tokenizer.Type() != eTkNull) {
|
||
|
if (tokenizer.Type() == eTkToken) {
|
||
|
mDispositionTypeStr = tokenizer.Token();
|
||
|
found = 1;
|
||
|
}
|
||
|
++tokenizer;
|
||
|
}
|
||
|
// Get parameters
|
||
|
DwTokenString tokenStr(mString);
|
||
|
while (1) {
|
||
|
// Get ';'
|
||
|
found = 0;
|
||
|
while (!found && tokenizer.Type() != eTkNull) {
|
||
|
if (tokenizer.Type() == eTkTspecial
|
||
|
&& tokenizer.Token()[0] == ';') {
|
||
|
found = 1;
|
||
|
}
|
||
|
++tokenizer;
|
||
|
}
|
||
|
if (tokenizer.Type() == eTkNull) {
|
||
|
// No more parameters
|
||
|
break;
|
||
|
}
|
||
|
tokenStr.SetFirst(tokenizer);
|
||
|
// Get attribute
|
||
|
DwString attrib;
|
||
|
int attribFound = 0;
|
||
|
while (!attribFound && tokenizer.Type() != eTkNull) {
|
||
|
if (tokenizer.Type() == eTkToken) {
|
||
|
attrib = tokenizer.Token();
|
||
|
attribFound = 1;
|
||
|
}
|
||
|
++tokenizer;
|
||
|
}
|
||
|
// Get '='
|
||
|
found = 0;
|
||
|
while (!found && tokenizer.Type() != eTkNull) {
|
||
|
if (tokenizer.Type() == eTkTspecial
|
||
|
&& tokenizer.Token()[0] == '=') {
|
||
|
found = 1;
|
||
|
}
|
||
|
++tokenizer;
|
||
|
}
|
||
|
// Get value
|
||
|
int valueFound = 0;
|
||
|
while (!valueFound && tokenizer.Type() != eTkNull) {
|
||
|
if (tokenizer.Type() == eTkToken
|
||
|
|| tokenizer.Type() == eTkQuotedString) {
|
||
|
valueFound = 1;
|
||
|
}
|
||
|
++tokenizer;
|
||
|
}
|
||
|
if (attribFound && valueFound) {
|
||
|
tokenStr.ExtendTo(tokenizer);
|
||
|
DwParameter* param =
|
||
|
DwParameter::NewParameter(tokenStr.Tokens(), this);
|
||
|
param->Parse();
|
||
|
_AddParameter(param);
|
||
|
}
|
||
|
}
|
||
|
StrToEnum();
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::Assemble()
|
||
|
{
|
||
|
if (!mIsModified) return;
|
||
|
mString = "";
|
||
|
if (mDispositionTypeStr.length() == 0)
|
||
|
return;
|
||
|
mString += mDispositionTypeStr;
|
||
|
DwParameter* param = FirstParameter();
|
||
|
while (param) {
|
||
|
param->Assemble();
|
||
|
if (IsFolding()) {
|
||
|
mString += ";" DW_EOL " ";
|
||
|
}
|
||
|
else {
|
||
|
mString += "; ";
|
||
|
}
|
||
|
mString += param->AsString();
|
||
|
param = param->Next();
|
||
|
}
|
||
|
mIsModified = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
DwMessageComponent* DwDispositionType::Clone() const
|
||
|
{
|
||
|
return new DwDispositionType(*this);
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::EnumToStr()
|
||
|
{
|
||
|
switch (mDispositionType) {
|
||
|
case DwMime::kDispTypeInline:
|
||
|
mDispositionTypeStr = "inline";
|
||
|
break;
|
||
|
case DwMime::kDispTypeAttachment:
|
||
|
mDispositionTypeStr = "attachment";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::StrToEnum()
|
||
|
{
|
||
|
switch (mDispositionTypeStr[0]) {
|
||
|
case 'i':
|
||
|
if (DwStrcasecmp(mDispositionTypeStr, "inline") == 0) {
|
||
|
mDispositionType = DwMime::kDispTypeInline;
|
||
|
}
|
||
|
else {
|
||
|
mDispositionType = DwMime::kDispTypeUnknown;
|
||
|
}
|
||
|
break;
|
||
|
case 'a':
|
||
|
if (DwStrcasecmp(mDispositionTypeStr, "attachment") == 0) {
|
||
|
mDispositionType = DwMime::kDispTypeAttachment;
|
||
|
}
|
||
|
else {
|
||
|
mDispositionType = DwMime::kDispTypeUnknown;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::DeleteParameterList()
|
||
|
{
|
||
|
DwParameter* param = mFirstParameter;
|
||
|
while (param) {
|
||
|
DwParameter* nextParam = param->Next();
|
||
|
delete param;
|
||
|
param = nextParam;
|
||
|
}
|
||
|
mFirstParameter = 0;
|
||
|
SetModified();
|
||
|
}
|
||
|
|
||
|
|
||
|
void DwDispositionType::CopyParameterList(DwParameter* aFirst)
|
||
|
{
|
||
|
DwParameter* param = aFirst;
|
||
|
while (param) {
|
||
|
DwParameter* newParam = (DwParameter*) param->Clone();
|
||
|
AddParameter(newParam);
|
||
|
param = param->Next();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#if defined(DW_DEBUG_VERSION)
|
||
|
void DwDispositionType::PrintDebugInfo(std::ostream& aStrm, int aDepth) const
|
||
|
{
|
||
|
aStrm <<
|
||
|
"------------ Debug info for DwDispositionType class ------------\n";
|
||
|
_PrintDebugInfo(aStrm);
|
||
|
int depth = aDepth - 1;
|
||
|
depth = (depth >= 0) ? depth : 0;
|
||
|
if (aDepth == 0 || depth > 0) {
|
||
|
DwParameter* param = mFirstParameter;
|
||
|
while (param) {
|
||
|
param->PrintDebugInfo(aStrm, depth);
|
||
|
param = param->Next();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
void DwDispositionType::PrintDebugInfo(std::ostream&, int) const {}
|
||
|
#endif // defined(DW_DEBUG_VERSION)
|
||
|
|
||
|
|
||
|
#if defined(DW_DEBUG_VERSION)
|
||
|
void DwDispositionType::_PrintDebugInfo(std::ostream& aStrm) const
|
||
|
{
|
||
|
DwFieldBody::_PrintDebugInfo(aStrm);
|
||
|
aStrm << "Disposition Type: " << mDispositionTypeStr
|
||
|
<< " (" << mDispositionType << ")\n";
|
||
|
aStrm << "Filename: " << mFilenameStr << "\n";
|
||
|
aStrm << "Parameters: ";
|
||
|
DwParameter* param = mFirstParameter;
|
||
|
if (param) {
|
||
|
int count = 0;
|
||
|
while (param) {
|
||
|
if (count) aStrm << ' ';
|
||
|
aStrm << param->ObjectId();
|
||
|
param = param->Next();
|
||
|
++count;
|
||
|
}
|
||
|
aStrm << '\n';
|
||
|
}
|
||
|
else {
|
||
|
aStrm << "(none)\n";
|
||
|
}
|
||
|
}
|
||
|
#else
|
||
|
void DwDispositionType::_PrintDebugInfo(std::ostream& ) const {}
|
||
|
#endif // defined(DW_DEBUG_VERSION)
|
||
|
|
||
|
|
||
|
void DwDispositionType::CheckInvariants() const
|
||
|
{
|
||
|
#if defined(DW_DEBUG_VERSION)
|
||
|
mDispositionTypeStr.CheckInvariants();
|
||
|
mFilenameStr.CheckInvariants();
|
||
|
DwParameter* param = mFirstParameter;
|
||
|
while (param) {
|
||
|
param->CheckInvariants();
|
||
|
assert((DwMessageComponent*) this == param->Parent());
|
||
|
param = param->Next();
|
||
|
}
|
||
|
#endif // defined(DW_DEBUG_VERSION)
|
||
|
}
|