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