summaryrefslogtreecommitdiffstats
path: root/mimelib/mimelib/msgcmp.h
blob: c9e6707ee971e32c1520480c5fd72d747bd5c4b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
//=============================================================================
// File:       msgcmp.h
// Contents:   Declarations for DwMessageComponent
// 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.
//
//=============================================================================

#ifndef DW_MSGCMP_H
#define DW_MSGCMP_H

#ifndef DW_CONFIG_H
#include <mimelib/config.h>
#endif

#ifndef DW_STRING_H
#include <mimelib/string.h>
#endif

#if !(defined(__DECCXX) && defined(__linux__))
#include <iosfwd>
#endif


//=============================================================================
//+ Name DwMessageComponent -- Abstract base class for all message components
//+ Description
//. {\tt DwMessageComponent} is the root of an inheritance hierarchy from
//. which all MIME message components are derived.  Thus,
//. {\tt DwMessageComponent} defines important features that are inherited by
//. nearly all other classes that represent components of a MIME message.
//. These features are the following:
//.
//. \begin{enumerate}
//. \item
//.    A string representation.  The {\tt DwMessageComponent} class provides
//.    a member function {\tt FromString(const DwString&)} to set the string
//.    representation and a member function {\tt AsString()} to get the
//.    string representation.
//.
//. \item
//.    A broken-down, or parsed, representation.  An RFC-822 date-time,
//.    for example, has a year, month, day, hour, minute, second, and
//.    time zone as elements of its broken-down representation.
//.    {\tt DwMessageComponent} does not deal directly with the
//.    broken-down representation, since it is component-specific.
//.    Derived classes bear all the responsibility for their broken-down
//.    representations.
//.
//. \item
//.    A parse method to extract the broken-down representation from
//.    the string representation.  In the {\tt DwDateTime} class, for
//.    example, the parse method extracts the year, month, day, hour,
//.    minute, second, and time zone from the RFC-822 {\it date-time}
//.    contained in the string representation.  {\tt DwMessageComponent}
//.    provides a pure virtual function {\tt Parse()}, which executes
//.    the parse method for a derived class.
//.
//. \item
//.    An assemble method to convert the broken-down representation to
//.    a string representation.  This is the opposite of the parse method.
//.    In the {\tt DwDateTime} class, for example, the assemble method
//.    creates an RFC-822 {\it date-time} string from values of the
//.    year, month, day, hour, minute, second, and time zone.
//.    {\tt DwMessageComponent} provides a pure virtual function
//.    {\tt Assemble()}, which executes the assemble method for
//.    a derived class.
//.
//. \item
//.    An is-modified flag.  When the string representation and the
//.    broken-down representation are consistent, the assemble
//.    method does not need to be executed.  The is-modified flag is
//.    cleared when the two representations are consistent, and is set
//.    when they are inconsistent.  The flag is set automatically
//.    whenever a {\tt DwMessageComponent} object's broken-down
//.    representation is changed by calling one of the object's member
//.    functions, and it is cleared when the assemble or parse method
//.    is executed.  {\tt DwMessageComponent} also provides a member
//.    function {\tt SetModified()} which forces the is-modified flag
//.    to be set.
//.
//. \item
//.    A parent.  Most message components are part of another component.
//.    A collection of headers is part of a message or body part, a header
//.    field is part of a collection of headers, a field-body is part
//.    of a header field, and so on.  The parent of
//.    a component is the component that contains it.  This tree structure
//.    is important, since a component's parent must be parsed before the
//.    component can be.  Also, a component's string representation must
//.    be assembled before its parent's.  To maintain consistency in the
//.    tree, whenever a component's is-modified flag is set,
//.    the component notifies its parent to also set its is-modified flag.
//.    In this way, an is-modified flag set anywhere in the tree always
//.    propagates up to the root component.
//.
//. \item
//.    Children.  The preceding discussion about a component's parent is
//.    relevant to an understanding of a component's children.  A component's
//.    parse method calls the parse methods of its children
//.    after it has executed its own parse method (and, in some cases, created
//.    all of its children).
//.    Also, a component typically calls the assemble method of its
//.    children before it executes its own.  A component's child may request
//.    that the component set its is-modified flag.
//.    {\tt DwMessageComponent} does not deal directly with children.
//.    Derived classes bear all the responsibility for handling their
//.    children.
//. \end{enumerate}
//=============================================================================
//+ Noentry ~DwMessageComponent _PrintDebugInfo mString mIsModified mParent
//+ Noentry mClassId mClassName

class DW_EXPORT DwMessageComponent {

private:

    DwUint32 mMagicNumber;

public:

    enum componentType {
        kCidError=-1,
        kCidUnknown=0,
        kCidAddress,
        kCidAddressList,
        kCidBody,
        kCidBodyPart,
        kCidDispositionType,
        kCidMechanism,
        kCidMediaType,
        kCidParameter,
        kCidDateTime,
        kCidEntity,
        kCidField,
        kCidFieldBody,
        kCidGroup,
        kCidHeaders,
        kCidMailbox,
        kCidMailboxList,
        kCidMessage,
        kCidMessageComponent,
        kCidMsgId,
        kCidText
    };
    //. Class identifier enumeration

    DwMessageComponent();
    DwMessageComponent(const DwMessageComponent& aCmp);
    DwMessageComponent(const DwString& aStr, DwMessageComponent* aParent=0);
    //. The first constructor is the default constructor, which sets the
    //. {\tt DwMessageComponent} object's string representation to the
    //. empty string and sets its parent to NULL.
    //.
    //. The second constructor is the copy constructor, which performs
    //. a deep copy of {\tt aCmp}.  The parent of the new
    //. {\tt DwMessageComponent} object is set to NULL.
    //.
    //. The third constructor copies {\tt aStr} to the new
    //. {\tt DwMessageComponent} object's string representation and sets
    //. {\tt aParent} as its parent.  In typical cases, the virtual
    //. member function {\tt Parse()} should be called immediately after
    //. this constructor to parse the new {\tt DwMessageComponent} object
    //. and all of its children into their broken-down representations.

    virtual ~DwMessageComponent();

    const DwMessageComponent& operator = (const DwMessageComponent& aCmp);
    //. This is the assignment operator, which performs a deep copy of
    //. {\tt aCmp}.

    virtual void Parse() = 0;
    //. A pure virtual function which provides an interface to the parse
    //. method.  The parse method, implemented in derived classes, is
    //. responsible for extracting the broken-down representation from
    //. the string representation.  In some derived classes, such as
    //. {\tt DwHeaders}, the parse method is also responsible for creating the
    //. children of the object.  (In the case of {\tt DwHeaders}, the children
    //. created are the {\tt DwField} objects that represent the {\it field}s
    //. contained in the {\it headers}.)  The {\tt Parse()} function always
    //. calls the {\tt Parse()} function of all of its children.

    virtual void Assemble() = 0;
    //. A pure virtual function which provides an interface to the
    //. assemble method.  The assemble method, implemented in derived
    //. classes, is responsible for creating the string representation
    //. from the broken-down representation.  In other words, the
    //. assemble method is the opposite of the parse method.  Before
    //. assembling its string representation, the assemble method calls
    //. the assemble method of each of its children.  In this way, the
    //. entire tree structure that represents a message may be traversed.
    //. If the is-modifed flag for a {\tt DwMessageComponent} is cleared,
    //. the {\tt Assemble()} function will return immediately without
    //. calling the {\tt Assemble()} function of any of its children.

    virtual DwMessageComponent* Clone() const = 0;
    //. Creates a new {\tt DwMessageComponent} on the free store that is of
    //. the same type as, and has the same value as, this object.  The
    //. basic idea is that of a ``virtual copy constructor.''

    void FromString(const DwString& aStr);
    void FromString(const char* aCstr);
    //. Sets the object's string representation.  {\tt aCstr} must be
    //. NUL-terminated. This member function does not invoke the parse
    //. method.  Typically, the virtual member function {\tt Parse()}
    //. should be called immediately after this member function to parse
    //. the {\tt DwMessageComponent} object and all of its children into
    //. their broken-down representations.  See also
    //. {\tt DwMessageComponent::Parse()}

    const DwString& AsString();
    //. Returns the {\tt DwMessageComponent} object's string representation.
    //. The assemble method is not called automatically.  Typically, the
    //. {\tt Assemble()} member function should be called immediately before
    //. this member function to insure that the broken-down representation
    //. and the string representation are consistent.  See also
    //. {\tt DwMessageComponent::Assemble()}.

    DwMessageComponent* Parent();
    //. Returns the {\tt DwMessageComponent} object that is the parent
    //. of this object.

    void SetParent(DwMessageComponent* aParent);
    //. Sets {\tt aParent} as the {\tt DwMessageComponent} object's parent.

    DwBool IsModified() const;
    //. Returns 1 if the is-modified flag is set for this
    //. {\tt DwMessageComponent} object.

    void SetModified();
    //. Sets the is-modified (dirty) flag for this {\tt DwMessageComponent}
    //. object and notifies the object's parent to also set its is-modified
    //. flag.

    int ClassId() const;
    //. Returns an integer id for the object's class.

    const char* ClassName() const;
    //. Returns the name of the class as a NUL-terminated
    //. char string.

    int ObjectId() const;
    //. Returns a object id that is unique among all DwMessageComponent
    //. objects.

    const char* partId() const { return mId.c_str(); }
    void SetPartId( DwString id ) { mId = id; }
    // set or get a unique string for that part

protected:

    DwString mString;
    // String representation

    DwBool mIsModified;
    // Is-modified flag

    DwMessageComponent* mParent;
    // Component that contains this component

    componentType mClassId;
    // Class identifier for runtime type identification

    const char* mClassName;
    // Class name for runtime type identification

    DwString mId;
    // unique indentifier

private:

    static const char* const sClassName;

public:

    virtual void PrintDebugInfo(std::ostream& aStrm, int aDepth=0) const;
    //. This virtual function
    //. prints debugging information about this object to {\tt aStrm}.
    //. It will also call {\tt PrintDebugInfo()} for any of its child
    //. components down to a level of {\tt aDepth}.
    //.
    //. This member function is available only in the debug version of
    //. the library.

    virtual void CheckInvariants() const;
    //. Aborts if one of the invariants of the object fails.  Use this
    //. member function to track down bugs.
    //.
    //. This member function is available only in the debug version of
    //. the library.

protected:

    void _PrintDebugInfo(std::ostream& aStrm) const;

};

#endif