summaryrefslogtreecommitdiffstats
path: root/mimelib/disptype.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mimelib/disptype.cpp')
-rw-r--r--mimelib/disptype.cpp446
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)
+}