|
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 #include "cimapfetchflags.h" |
|
17 |
|
18 #include "cimapsessionconsts.h" |
|
19 #include "moutputstream.h" |
|
20 #include "imappaniccodes.h" |
|
21 #include "cimaplogger.h" |
|
22 |
|
23 _LIT8(KCommandFetchFlags, "%d UID FETCH %S (UID FLAGS)\r\n"); |
|
24 |
|
25 CImapFetchFlags* CImapFetchFlags::NewL(CImapFolderInfo* aSelectedFolderData, TInt aLogId, const TDesC8& aSequenceSet, RArrayMessageFlagInfo& aOutMessageFlagInfo) |
|
26 { |
|
27 CImapFetchFlags* self = new (ELeave) CImapFetchFlags(aSelectedFolderData, aLogId, aOutMessageFlagInfo); |
|
28 CleanupStack::PushL(self); |
|
29 self->ConstructL(aSequenceSet); |
|
30 CleanupStack::Pop(self); |
|
31 return self; |
|
32 } |
|
33 |
|
34 CImapFetchFlags::CImapFetchFlags(CImapFolderInfo* aSelectedFolderData, TInt aLogId, RArrayMessageFlagInfo& aOutMessageFlagInfo) |
|
35 : CImapCommandEx(aSelectedFolderData, aLogId) |
|
36 , iOutMessageFlagInfo(aOutMessageFlagInfo) |
|
37 { |
|
38 } |
|
39 |
|
40 CImapFetchFlags::~CImapFetchFlags() |
|
41 { |
|
42 delete iSequenceSet; |
|
43 } |
|
44 |
|
45 void CImapFetchFlags::ConstructL(const TDesC8& aSequenceSet) |
|
46 { |
|
47 iSequenceSet = aSequenceSet.AllocL(); |
|
48 } |
|
49 /** |
|
50 Formats and sends the IMAP FETCH FLAGS command. |
|
51 @param aTagId Command sequence id which will be send along with the IMAP command. |
|
52 @param aStream A wrapper for the outbound stream of a connected socket, using which |
|
53 the command will be send to the server |
|
54 */ |
|
55 void CImapFetchFlags::SendMessageL(TInt aTagId, MOutputStream& aStream) |
|
56 { |
|
57 iTagId = aTagId; |
|
58 |
|
59 TInt bufLength = KCommandFetchFlags().Length(); |
|
60 bufLength += TagLength(aTagId); |
|
61 bufLength += iSequenceSet->Length(); |
|
62 |
|
63 __ASSERT_DEBUG(iOutputBuffer==NULL, TImapServerPanic::ImapPanic(TImapServerPanic::ECommandOutputBufferNotNull)); |
|
64 iOutputBuffer = HBufC8::NewL(bufLength); |
|
65 iOutputBuffer->Des().Format(KCommandFetchFlags, aTagId, iSequenceSet); |
|
66 |
|
67 //send the command to the server |
|
68 aStream.SendDataReq(*iOutputBuffer); |
|
69 } |
|
70 |
|
71 /** |
|
72 Called after a line of untagged response data has been received. |
|
73 @param aLine The line to be parsed. |
|
74 @return ECompleteUntagged if the line is a recognised untagged response |
|
75 ENotRecognised for any other response |
|
76 */ |
|
77 CImapCommand::TParseBlockResult CImapFetchFlags::ParseUntaggedResponseL() |
|
78 { |
|
79 TParseBlockResult result = ENotRecognised; |
|
80 |
|
81 // Is this a fetch flags response? |
|
82 // Check for Sequence Number followed by "FETCH" |
|
83 |
|
84 TPtrC8 part1 = GetNextPart(); // returns KNullDesC8 if there is no part available |
|
85 TPtrC8 part2 = GetNextPart(); // returns KNullDesC8 if there is no part available |
|
86 |
|
87 // Is part1 a Sequence Number? |
|
88 TInt sequenceNumber = 0; |
|
89 TLex8 lex(part1); |
|
90 if (lex.Val(sequenceNumber) == KErrNone) |
|
91 { |
|
92 // part1 is a Sequence Number. Now check part2 - is it "FETCH"? |
|
93 |
|
94 if(part2.CompareF(KImapTxtFetch) == 0) |
|
95 { |
|
96 ProcessFetchFlagsResponseL(); |
|
97 result = ECompleteUntagged; |
|
98 } |
|
99 } |
|
100 |
|
101 // If ProcessFetchFlagsResponseL() is not called then result remains ENotRecognised |
|
102 return result; |
|
103 } |
|
104 |
|
105 void CImapFetchFlags::ProcessFetchFlagsResponseL() |
|
106 { |
|
107 // Each untagged response is of the form |
|
108 // * 23 FETCH (FLAGS (\Seen) UID 4827313) |
|
109 // Where 23 is the message sequence number. Discard this. |
|
110 // And 4827313 is the message uid. Keep this. |
|
111 // |
|
112 |
|
113 TMessageFlagInfo messageFlagInfoEntry; |
|
114 |
|
115 // Strip the opening and closing brackets |
|
116 TInt remainderLength = iUnparsedData.Length(); |
|
117 if (remainderLength < 2) |
|
118 { |
|
119 // expecting at least '(' and ')' |
|
120 CorruptDataL(); |
|
121 } |
|
122 if (iUnparsedData[0] != '(' || iUnparsedData[remainderLength-1] != ')') |
|
123 { |
|
124 CorruptDataL(); |
|
125 } |
|
126 |
|
127 iUnparsedData.Set(iUnparsedData.Mid(1, remainderLength-2)); |
|
128 |
|
129 // The UID FETCH and UID STORE commands expect responses to contain |
|
130 // both FLAGS and UID data items. |
|
131 // |
|
132 // If a FETCH response is received that does not contain the UID data item |
|
133 // then it is an unsolicited server event and should not be recorded in the result set. |
|
134 |
|
135 TBool foundFlags = EFalse; |
|
136 TBool foundUid = EFalse; |
|
137 |
|
138 while ( !(foundFlags && foundUid) ) |
|
139 { |
|
140 TPtrC8 dataItem = GetNextPart(); |
|
141 |
|
142 if (dataItem.CompareF(KImapTxtFlags) == 0) |
|
143 { |
|
144 iUnparsedData.Set( messageFlagInfoEntry.ParseFlagsL(Remainder()) ); |
|
145 foundFlags = ETrue; |
|
146 } |
|
147 else if (dataItem.CompareF(KImapTxtUid) == 0) |
|
148 { |
|
149 TPtrC8 uidString = GetNextPart(); |
|
150 |
|
151 TInt err = messageFlagInfoEntry.SetMessageUid(uidString); |
|
152 if (err != KErrNone) |
|
153 { |
|
154 CorruptDataL(); |
|
155 } |
|
156 foundUid = ETrue; |
|
157 } |
|
158 else if (dataItem.Length() == 0) |
|
159 { |
|
160 // No more data items |
|
161 // |
|
162 break; // from while loop |
|
163 } |
|
164 else |
|
165 { |
|
166 // |
|
167 __LOG_FORMAT((iLogId, "CImapFetchFlags::ProcessFetchFlagsResponseL() - Unexpected data item: %S", &dataItem)); |
|
168 CorruptDataL(); |
|
169 } |
|
170 } |
|
171 |
|
172 if (foundFlags && foundUid) |
|
173 { |
|
174 // A genuine response to the UID FETCH or UID STORE was received |
|
175 iOutMessageFlagInfo.AppendL(messageFlagInfoEntry); |
|
176 } |
|
177 else if (foundFlags) |
|
178 { |
|
179 // An unsolicited server event was received - record this so that a sync will be triggered |
|
180 // after this command has completed. |
|
181 __LOG_TEXT(iLogId, "CImapFetchFlags::ProcessFetchFlagsResponseL() - Found unsolicited FETCH FLAGS"); |
|
182 SetMessageFlagsChanged(); |
|
183 } |
|
184 else |
|
185 { |
|
186 // Was expecting at least the FLAGS data item. |
|
187 CorruptDataL(); |
|
188 } |
|
189 } |