diff options
Diffstat (limited to 'mimelib/disptype.cpp')
-rw-r--r-- | mimelib/disptype.cpp | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/mimelib/disptype.cpp b/mimelib/disptype.cpp new file mode 100644 index 000000000..f93dc21be --- /dev/null +++ b/mimelib/disptype.cpp @@ -0,0 +1,446 @@ +//============================================================================= +// 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) +} |