1 //=============================================================================
2 // File:       param.cpp
3 // Contents:   Definitions for DwParameter
4 // Maintainer: Doug Sauder <dwsauder@fwb.gulf.net>
5 // WWW:        http://www.fwb.gulf.net/~dwsauder/mimepp.html
6 // $Revision: 1.6 $
7 // $Date: 1997/09/27 11:54:13 $
8 //
9 // Copyright (c) 1996, 1997 Douglas W. Sauder
10 // All rights reserved.
11 //
12 // IN NO EVENT SHALL DOUGLAS W. SAUDER BE LIABLE TO ANY PARTY FOR DIRECT,
13 // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
14 // THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF DOUGLAS W. SAUDER
15 // HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16 //
17 // DOUGLAS W. SAUDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT
18 // NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
19 // PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
20 // BASIS, AND DOUGLAS W. SAUDER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
21 // SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
22 //
23 //=============================================================================
24 
25 #define DW_IMPLEMENTATION
26 
27 #include <mimelib/config.h>
28 #include <mimelib/debug.h>
29 #include <ctype.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <mimelib/string.h>
33 #include <mimelib/param.h>
34 #include <mimelib/token.h>
35 
36 
37 const char* const DwParameter::sClassName = "DwParameter";
38 
39 
40 DwParameter* (*DwParameter::sNewParameter)(const DwString&,
41     DwMessageComponent*) = 0;
42 
43 
NewParameter(const DwString & aStr,DwMessageComponent * aParent)44 DwParameter* DwParameter::NewParameter(const DwString& aStr,
45     DwMessageComponent* aParent)
46 {
47     if (sNewParameter) {
48         return sNewParameter(aStr, aParent);
49     }
50     else {
51         return new DwParameter(aStr, aParent);
52     }
53 }
54 
55 
DwParameter()56 DwParameter::DwParameter()
57 {
58     mNext = 0;
59     mClassId = kCidParameter;
60     mClassName = sClassName;
61 }
62 
63 
DwParameter(const DwParameter & aParam)64 DwParameter::DwParameter(const DwParameter& aParam)
65   : DwMessageComponent(aParam),
66     mAttribute(aParam.mAttribute),
67     mValue(aParam.mValue)
68 {
69     mNext = 0;
70     mClassId = kCidParameter;
71     mClassName = sClassName;
72 }
73 
74 
DwParameter(const DwString & aStr,DwMessageComponent * aParent)75 DwParameter::DwParameter(const DwString& aStr, DwMessageComponent* aParent)
76     : DwMessageComponent(aStr, aParent)
77 {
78     mNext = 0;
79     mClassId = kCidParameter;
80     mClassName = sClassName;
81 }
82 
83 
~DwParameter()84 DwParameter::~DwParameter()
85 {
86 }
87 
88 
operator =(const DwParameter & aParam)89 const DwParameter& DwParameter::operator = (const DwParameter& aParam)
90 {
91     if (this == &aParam) return *this;
92     DwMessageComponent::operator = (aParam);
93     mAttribute = aParam.mAttribute;
94     mValue     = aParam.mValue;
95     mNext      = 0;
96     return *this;
97 }
98 
99 
Attribute() const100 const DwString& DwParameter::Attribute() const
101 {
102     return mAttribute;
103 }
104 
105 
SetAttribute(const DwString & aAttribute)106 void DwParameter::SetAttribute(const DwString& aAttribute)
107 {
108     mAttribute = aAttribute;
109     SetModified();
110 }
111 
112 
Value() const113 const DwString& DwParameter::Value() const
114 {
115     return mValue;
116 }
117 
118 
SetValue(const DwString & aValue)119 void DwParameter::SetValue(const DwString& aValue)
120 {
121     mValue = aValue;
122     SetModified();
123 }
124 
125 
Next() const126 DwParameter* DwParameter::Next() const
127 {
128     return mNext;
129 }
130 
131 
SetNext(DwParameter * aParam)132 void DwParameter::SetNext(DwParameter* aParam)
133 {
134     mNext = aParam;
135 }
136 
137 
Parse()138 void DwParameter::Parse()
139 {
140     mIsModified = 0;
141     mAttribute = mValue = "";
142     if (mString.length() == 0) return;
143     DwRfc1521Tokenizer tokenizer(mString);
144     // Get attribute
145     int found = 0;
146     while (!found && tokenizer.Type() != eTkNull) {
147         if (tokenizer.Type() == eTkToken) {
148             mAttribute = tokenizer.Token();
149             found = 1;
150         }
151         ++tokenizer;
152     }
153     // Get '='
154     found = 0;
155     while (!found && tokenizer.Type() != eTkNull) {
156         if (tokenizer.Type() == eTkTspecial
157             && tokenizer.Token()[0] == '=') {
158             found = 1;
159         }
160         ++tokenizer;
161     }
162     // Get value
163     found = 0;
164     while (!found && tokenizer.Type() != eTkNull) {
165         if (tokenizer.Type() == eTkToken) {
166             mValue = tokenizer.Token();
167             found = 1;
168         }
169         else if (tokenizer.Type() == eTkQuotedString) {
170             tokenizer.StripDelimiters();
171             mValue = tokenizer.Token();
172             found = 1;
173         }
174         ++tokenizer;
175     }
176     // Some nonstandard MIME implementations use single quotes to quote
177     // the boundary string.  This is incorrect, but we will try to detect
178     // it and work with it.
179     //
180 	// If the first character and last character of the boundary string
181     // are single quote, strip them off.
182     if (DwStrcasecmp(mAttribute, "boundary") == 0) {
183         size_t len = mValue.length();
184         if (len > 2 && mValue[0] == '\'' && mValue[len-1] == '\'') {
185             mValue = mValue.substr(1, len-2);
186         }
187     }
188 }
189 
190 
Assemble()191 void DwParameter::Assemble()
192 {
193     if (mIsModified == 0) return;
194     mString = "";
195     mString += mAttribute;
196     mString += "=\"";
197     mString += mValue;
198     mString += "\"";
199     mIsModified = 0;
200 }
201 
202 
Clone() const203 DwMessageComponent* DwParameter::Clone() const
204 {
205     return new DwParameter(*this);
206 }
207 
208 
PrintDebugInfo(ostream & aStrm,int) const209 void DwParameter::PrintDebugInfo(ostream& aStrm, int /*aDepth*/) const
210 {
211 #if defined (DW_DEBUG_VERSION)
212     aStrm <<
213     "--------------- Debug info for DwParameter class ---------------\n";
214     _PrintDebugInfo(aStrm);
215 #endif // defined (DW_DEBUG_VERSION)
216 }
217 
218 
_PrintDebugInfo(ostream & aStrm) const219 void DwParameter::_PrintDebugInfo(ostream& aStrm) const
220 {
221 #if defined (DW_DEBUG_VERSION)
222     DwMessageComponent::_PrintDebugInfo(aStrm);
223     aStrm << "Attribute:        " << mAttribute << '\n';
224     aStrm << "Value:            " << mValue << '\n';
225     if (mNext) {
226         aStrm << "Next parameter:   " << mNext->ObjectId() << '\n';
227     }
228     else {
229         aStrm << "Next parameter:   " << "(none)\n";
230     }
231 #endif // defined (DW_DEBUG_VERSION)
232 }
233 
234 
CheckInvariants() const235 void DwParameter::CheckInvariants() const
236 {
237 #if defined (DW_DEBUG_VERSION)
238     DwMessageComponent::CheckInvariants();
239     mAttribute.CheckInvariants();
240     mValue.CheckInvariants();
241 #endif // defined (DW_DEBUG_VERSION)
242 }
243 
244