|
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 // Implementation of the CROCHCAFInterface class. |
|
15 // |
|
16 // |
|
17 |
|
18 |
|
19 #include "ROCHCAFInterface.h" |
|
20 |
|
21 _LIT8(KXHyphen,"X-"); |
|
22 _LIT8(KContentHyphen,"Content-"); |
|
23 const TUint8 KImcvColon = ':'; |
|
24 |
|
25 #if _DEBUG |
|
26 _LIT(KErrInvalidCafState, "Invalid CAF State"); |
|
27 #endif |
|
28 |
|
29 /** |
|
30 Construct with callers file session handle. |
|
31 c'tor |
|
32 */ |
|
33 EXPORT_C CROCHCAFInterface::CROCHCAFInterface(RFs& aFs) : iFsSession(aFs) |
|
34 {} |
|
35 |
|
36 /** |
|
37 d'tor |
|
38 */ |
|
39 EXPORT_C CROCHCAFInterface::~CROCHCAFInterface() |
|
40 { |
|
41 delete iSupplier; |
|
42 delete iContentType; |
|
43 delete iMetaData; |
|
44 delete iImportFile; |
|
45 iAttachmentFile.Close(); |
|
46 } |
|
47 |
|
48 |
|
49 /** |
|
50 Prior to StartProcessing() the CAF agent could provide an initial filename for the CAF session. |
|
51 @param aAttachmentFileName Descriptor for writing CAF agent suggested filename. |
|
52 @return KErrNone success or system error code. |
|
53 @pre PrepareProcessingL() must be called prior to this call. |
|
54 @panic imut 36 |
|
55 */ |
|
56 EXPORT_C TInt CROCHCAFInterface::GetSuggestedAttachmentFileName(TDes& aAttachmentFileName) const |
|
57 { |
|
58 __ASSERT_DEBUG(iImportFile != NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
59 return iImportFile->GetSuggestedOutputFileName(aAttachmentFileName); |
|
60 } |
|
61 |
|
62 |
|
63 /** |
|
64 Write a buffer of data to the CAF Agent. |
|
65 @param aData Data to write to the CAF agent. |
|
66 @return KErrNone success or system error code. |
|
67 @pre StartProcessingL() must be called prior to this call |
|
68 @post Generates 0-N receipt files under the current message attachment entry. |
|
69 @panic imut 36 |
|
70 */ |
|
71 EXPORT_C void CROCHCAFInterface::WriteDataL(const TDesC8& aData) |
|
72 { |
|
73 __ASSERT_DEBUG(iImportFile != NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
74 User::LeaveIfError(iImportFile->WriteData(aData)); |
|
75 } |
|
76 |
|
77 /** |
|
78 Add Mime header metadata to CAF class in preparation for PrepareProcessingL() |
|
79 Metadata comprises a field and data pair. For example: |
|
80 aField - "X-Oma-Drm-Separate-Delivery" aData - "12" |
|
81 If field does not contain "X-" or "Content-" then the method returns without |
|
82 adding them to the class. |
|
83 @param aField - Mime header field |
|
84 @param aData - Mime field's corresponding data |
|
85 @panic imut 36 |
|
86 */ |
|
87 EXPORT_C void CROCHCAFInterface::AddToMetaDataL(const TDesC8& aField, const TDesC8& aData) |
|
88 { |
|
89 if(aField.FindF(KContentHyphen) == KErrNone && aField.FindF(KXHyphen) == KErrNone) |
|
90 { |
|
91 return; |
|
92 } |
|
93 if(!iMetaData) |
|
94 { |
|
95 iMetaData = CMetaDataArray::NewL(); |
|
96 } |
|
97 // Check we're not overwriting an existing one. Could show up a logic error. |
|
98 #if (defined _DEBUG) |
|
99 TPtrC8 des(iMetaData->SearchL(aField)); |
|
100 __ASSERT_DEBUG(des.Length() == 0, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
101 #endif |
|
102 iMetaData->AddL(aField,aData); |
|
103 } |
|
104 |
|
105 /** |
|
106 Add Mime header metadata to CAF class in preparation for PrepareProcessingL() |
|
107 Parses a complete unfolded mime header line to extract fields and values |
|
108 Format expected: |
|
109 Fieldxxx: Valuexxx;ParamField=ParamValue |
|
110 If line does not contain "X-" or "Content-" then the method returns without |
|
111 adding data to the class. |
|
112 @param aMimeLine - Mime header data line minus CRLF |
|
113 @panic imut 36 |
|
114 */ |
|
115 EXPORT_C void CROCHCAFInterface::AddToMetaDataL(const TDesC8& aMimeLine) |
|
116 { |
|
117 // Don't bother adding if it's neither of these |
|
118 // This means we won't add envelope stuff |
|
119 if(aMimeLine.FindF(KContentHyphen) == KErrNone && aMimeLine.FindF(KXHyphen) == KErrNone) |
|
120 { |
|
121 return; |
|
122 } |
|
123 if(!iMetaData) |
|
124 { |
|
125 iMetaData = CMetaDataArray::NewL(); |
|
126 } |
|
127 TInt offset; |
|
128 TPtrC8 field; |
|
129 TPtrC8 data; |
|
130 // Isolate the field and data pair separated by ':' |
|
131 if((offset = aMimeLine.Locate(KImcvColon)) != KErrNotFound) |
|
132 { |
|
133 field.Set(aMimeLine.Left(++offset)); |
|
134 // Remove leading whitespace |
|
135 while(aMimeLine[offset] == ' ') |
|
136 { |
|
137 offset++; |
|
138 } |
|
139 data.Set(aMimeLine.Mid(offset)); |
|
140 } |
|
141 else |
|
142 { |
|
143 // No colon should never happen if mail is not corrupt |
|
144 __ASSERT_DEBUG(offset != KErrNotFound, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
145 return; |
|
146 } |
|
147 // Check we're not overwriting an existing one. Could show up a logic error. |
|
148 #if (defined _DEBUG) |
|
149 TPtrC8 des(iMetaData->SearchL(field)); |
|
150 __ASSERT_DEBUG(des.Length() == 0, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
151 #endif |
|
152 iMetaData->AddL(field,data); |
|
153 } |
|
154 |
|
155 /** |
|
156 Prepare the CROCHCAFInterface class for a CAF session. |
|
157 @pre RegisterL() must be called prior to this call and success checked with a Registered() call. |
|
158 @panic imut 36 |
|
159 */ |
|
160 EXPORT_C void CROCHCAFInterface::PrepareProcessingL() |
|
161 { |
|
162 __ASSERT_DEBUG(iSupplier != NULL && iContentType != NULL && iMetaData != NULL && iImportFile == NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
163 iImportFile = iSupplier->ImportFileL(iContentType->Des(),*iMetaData);// Prepare agent for writing data. |
|
164 Deregister(); |
|
165 } |
|
166 |
|
167 /** |
|
168 Set the CAF class variables required to Start the CAF write session. |
|
169 @param aDefaultAttachmentFileName Localised default attachment name. |
|
170 @param aAttachmentFilePath If CAF agent requires extra files, this is the folder/attachment entry path. |
|
171 @param aStartFile An open File handle for attachment write. Caller can close following this call. |
|
172 @pre PrepareProcessingL() must be called prior to this call |
|
173 @panic imut 36 |
|
174 */ |
|
175 EXPORT_C void CROCHCAFInterface::StartProcessing(const TDesC& aDefaultAttachmentFileName,const TDesC& aAttachmentFilePath,RFile& aStartFile) |
|
176 { |
|
177 __ASSERT_DEBUG(iSupplier != NULL && iImportFile != NULL && iContentType == NULL && iMetaData == NULL && aStartFile.SubSessionHandle() != 0, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
178 iDefaultAttachmentFileName.Set(aDefaultAttachmentFileName); |
|
179 iAttachmentFilePath = aAttachmentFilePath; |
|
180 iAttachmentFile.Duplicate(aStartFile); // Caller can close their copy |
|
181 } |
|
182 |
|
183 /** |
|
184 Terminate CAF session. |
|
185 Set the mime type to a unique CAF one if there are. |
|
186 @panic imut 36 |
|
187 */ |
|
188 EXPORT_C void CROCHCAFInterface::EndProcessingL() |
|
189 { |
|
190 __ASSERT_DEBUG(iImportFile != NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
191 WriteDataCompleteL(); |
|
192 |
|
193 delete iImportFile; |
|
194 iImportFile = NULL; |
|
195 } |
|
196 |
|
197 /** |
|
198 Attempt to register a mime content-type with a CAF agent. |
|
199 Success can be checked by a subsequent call to Registered(). |
|
200 @param aMimeLine MIME Content-Type for possible interest by a CAF agent. For example - application/vnd.oma.drm.rights+xml |
|
201 @panic imut 36 |
|
202 */ |
|
203 EXPORT_C void CROCHCAFInterface::RegisterL(const TDesC8& aMimeLine) |
|
204 { |
|
205 __ASSERT_DEBUG(iContentType == NULL, User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
206 if(!iSupplier) |
|
207 { |
|
208 iSupplier = CSupplier::NewL(); |
|
209 } |
|
210 if(iSupplier->IsImportSupported(aMimeLine)) |
|
211 { |
|
212 // CAF agent interested in the content-type |
|
213 // Use this buffer for storing the content-type. |
|
214 // We could extract it from the caf metadata later but this will be quicker |
|
215 iContentType = aMimeLine.AllocL(); |
|
216 // REMOVE when CAF fixed |
|
217 iContentType->Des().LowerCase(); |
|
218 // Construct the metadata array here but add to it later |
|
219 // Could contain stuff like "X-Oma-Drm-Separate-Delivery: 12" |
|
220 if(!iMetaData) |
|
221 { |
|
222 iMetaData = CMetaDataArray::NewL(); |
|
223 } |
|
224 } |
|
225 } |
|
226 |
|
227 /** |
|
228 Free resources allocated during CAF session |
|
229 @pre RegisterL() must be called prior to this call. |
|
230 @panic imut 36 |
|
231 */ |
|
232 EXPORT_C void CROCHCAFInterface::Deregister() |
|
233 { |
|
234 __ASSERT_DEBUG(Registered(), User::Panic(KErrInvalidCafState, EPanicInvalidCafState)); |
|
235 // Don't delete iSupplier. This is kept open to prevent reloading of DLLs |
|
236 delete iContentType; |
|
237 iContentType = NULL; |
|
238 delete iMetaData; |
|
239 iMetaData = NULL; |
|
240 } |
|
241 |
|
242 /** |
|
243 Check whether RegisterL() succeeded. |
|
244 @return Registered status of the CAF instance. |
|
245 */ |
|
246 EXPORT_C TBool CROCHCAFInterface::Registered() const |
|
247 { |
|
248 return iContentType != NULL; |
|
249 } |
|
250 |
|
251 /** |
|
252 Retrieve processing status for the CAF session. |
|
253 @return Processing status of the CAF instance |
|
254 */ |
|
255 EXPORT_C TBool CROCHCAFInterface::Processing() const |
|
256 { |
|
257 return iImportFile != NULL; |
|
258 } |
|
259 |
|
260 //Tell the CAF agent this that the last data for the CAF session has been written. |
|
261 void CROCHCAFInterface::WriteDataCompleteL() |
|
262 { |
|
263 User::LeaveIfError(iImportFile->WriteDataComplete()); |
|
264 } |
|
265 |