|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #ifndef __CIMAPBODYSTRUCTUREBUILDER_H__ |
|
17 #define __CIMAPBODYSTRUCTUREBUILDER_H__ |
|
18 |
|
19 #include <e32base.h> |
|
20 #include "cimapenvelope.h" |
|
21 |
|
22 class CImapBodyStructure; |
|
23 class CImapAtomParser; |
|
24 class CImapAtomWalker; |
|
25 class CImapFetchResponse; |
|
26 |
|
27 /** |
|
28 Builds a tree of CImapBodyStructure objects in order to represent the incoming |
|
29 bodystructure data from the IMAP server. |
|
30 Incoming data is passed into ProcessBlockL() which parses the data into an atom tree. |
|
31 Once ProcessBlockL() has completed the atom tree, it uses ParseLoopL() to parse the |
|
32 atom tree into the bodystructure tree. |
|
33 Finally, ownership of the completed bodystructure tree is passed to the CImapFetchResponse |
|
34 object that was provided on construction. |
|
35 */ |
|
36 class CImapBodyStructureBuilder : public CBase |
|
37 { |
|
38 public: |
|
39 static CImapBodyStructureBuilder* NewL(CImapFetchResponse& aFetchResponse, TInt aLogId); |
|
40 ~CImapBodyStructureBuilder(); |
|
41 |
|
42 TBool ProcessBlockL(const TDesC8& aData); |
|
43 |
|
44 TPtrC8 UnparsedData(); |
|
45 |
|
46 private: |
|
47 /** |
|
48 States used by ParseLoopL(); |
|
49 */ |
|
50 enum TParseStep |
|
51 { |
|
52 /** |
|
53 Indicates the start of the root body structure, or that an embedded body structure has been identified. |
|
54 iAtomWalker is either positioned at the opening bracket of the body structure in question. |
|
55 A new bodystructure object will be constructed and pushed onto the bodystructure stack. |
|
56 */ |
|
57 EParseNewBodyStructure, |
|
58 /** |
|
59 Indicates that a "basic" bodystructure has been identified - i.e. not text, rfc822 or multipart. |
|
60 iAtomWalker is positioned at the subtype field of the structure. |
|
61 */ |
|
62 EParseBasic, |
|
63 /** |
|
64 Indicates that a "TEXT" bodystructure has been identified - i.e. not text, rfc822 or multipart. |
|
65 iAtomWalker is positioned at the subtype field of the structure. |
|
66 */ |
|
67 EParseText, |
|
68 /** |
|
69 Indicates that a "MESSAGE/RFC822" bodystructure has been identified - i.e. not text, rfc822 or multipart. |
|
70 iAtomWalker is positioned at the subtype field of the structure. |
|
71 */ |
|
72 EParseBodyTypeMessageRfc822, |
|
73 /** |
|
74 Indicates that the embedded bodystructure of a "MESSAGE/RFC822" has just completed parsing. |
|
75 iAtomWalker is positioned ready to walk accross to the next field of body-type-msg. |
|
76 */ |
|
77 EParseRemainderMessageRfc822, |
|
78 /** |
|
79 Indicates that the final embedded bodystructure of a MULTIPART structure has just completed parsing. |
|
80 iAtomWalker is positioned ready to walk accross to the next field of body-type-mpart. |
|
81 */ |
|
82 EParseRemainderMultipart, |
|
83 /** |
|
84 Indicates that a bodystructure has completed parsing. |
|
85 The current CImapBodyStructure will be popped off the bodystructure stack |
|
86 and ParseSubStructureCompleteL() will be called to tidy up and decide the next state. |
|
87 */ |
|
88 EParseSubStructureComplete, |
|
89 /** |
|
90 Finished parsing the atom tree. |
|
91 This state is used to exit the parse loop. |
|
92 */ |
|
93 EParseComplete |
|
94 }; |
|
95 |
|
96 CImapBodyStructureBuilder(CImapFetchResponse& aFetchResponse, TInt aLogId); |
|
97 void ConstructL(); |
|
98 |
|
99 void TransferBufferOwnershipToFetchResponseL(); |
|
100 |
|
101 void ParseLoopL(); |
|
102 |
|
103 void PushNewBodyStructureL(); |
|
104 TBool PopBodyStructureL(); |
|
105 |
|
106 TParseStep ParseSubStructureCompleteL(); |
|
107 TParseStep ParseBodyStructureTypeL(); |
|
108 |
|
109 // Each of the following ParseBodyXxxL() methods is named after the corresponding |
|
110 // formal syntax item in RFC3501 section 9 that it is responsible for parsing. |
|
111 |
|
112 void ParseBodyTypeBasicL(); |
|
113 void ParseBodyTypeTextL(); |
|
114 void ParseBodyTypeMessageRfc822L(); |
|
115 |
|
116 void ParseBodyFieldsL(); |
|
117 void ParseBodyFieldParamsL(TBool aStoreAsDisposition); |
|
118 |
|
119 void ParseBodyFieldDispL(); |
|
120 void ParseBodyFieldLangL(); |
|
121 void ParseBodyExt1PartL(); |
|
122 void ParseRemainderMultipartL(); |
|
123 void ParseRemainderMessageRfc822L(); |
|
124 void ParseCommonOptionalExtensionsL(); |
|
125 void ParseBodyExtensionL(); |
|
126 |
|
127 void ParseEnvelopeL(); |
|
128 void ParseAddressL(CImapEnvelope::TAddress& aAddress); |
|
129 private: |
|
130 /** |
|
131 Receives ownership of the root body structure and data, upon successful completion of parsing. |
|
132 */ |
|
133 CImapFetchResponse& iFetchResponse; |
|
134 |
|
135 /** |
|
136 Whether root body structure is owned by this object. If EFalse, then it is owned by iFetchResponse. |
|
137 */ |
|
138 TBool iBodyStructureOwned; |
|
139 |
|
140 /** |
|
141 A stack of the bodystructures that have not yet completed parsing. |
|
142 Together with the parse loop, this enables embedded bodystructures to be parsed without using recursion. |
|
143 iBodyStructureStack[0] is the root body structure, and owns the bodystructure while |
|
144 iBodyStructureOwned is ETrue. |
|
145 Indexes greater than 0 do not own the bodystructure they point to. |
|
146 This is because each CImapBodyStructure owns it's children, so ultimately |
|
147 the root bodystructure owns all the bodystructure in its tree. |
|
148 */ |
|
149 RPointerArray<CImapBodyStructure> iBodyStructureStack; |
|
150 /** |
|
151 Points at the top bodystructure in the stack. |
|
152 This is the CImapBodyStructure that is currently being parsed. |
|
153 */ |
|
154 CImapBodyStructure* iBodyStructure; |
|
155 |
|
156 /** |
|
157 Parses incoming blocks of data into a tree of CImapAtom's |
|
158 */ |
|
159 CImapAtomParser* iAtomParser; |
|
160 /** |
|
161 Walks the CImapAtom tree, tracking the current position in the tree, |
|
162 and making it possible to WalkAcross to the next sibling atom, WalkDown to the child atom |
|
163 and WalkUp to the parent. |
|
164 */ |
|
165 CImapAtomWalker* iAtomWalker; |
|
166 |
|
167 /** |
|
168 States used by ProcessBlockL() |
|
169 */ |
|
170 enum TProcessBlockState |
|
171 { |
|
172 /** |
|
173 Expecting ProcessBlockL() to be called with a line of data |
|
174 */ |
|
175 EWaitLine, |
|
176 /** |
|
177 Expecting ProcessBlockL() to be called with a block of literal data |
|
178 */ |
|
179 EWaitLiteral, |
|
180 /** |
|
181 All data has been recieved. The Atom tree is now being parsed. |
|
182 Not Expecting ProcessBlockL() to be called again on this object. |
|
183 */ |
|
184 EParsing |
|
185 } iProcessBlockState; |
|
186 |
|
187 /** |
|
188 Log id of the owning session |
|
189 */ |
|
190 TInt iLogId; |
|
191 }; |
|
192 |
|
193 #endif // __CIMAPBODYSTRUCTUREBUILDER_H__ |