|
1 /* |
|
2 * Copyright (c) 2008-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Header declaration |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 #include "senmtomutils.h" |
|
22 |
|
23 // ======== MEMBER FUNCTIONS ======== |
|
24 |
|
25 // --------------------------------------------------------------------------- |
|
26 // Serializes SoapEnvelope message in XOP message |
|
27 // --------------------------------------------------------------------------- |
|
28 // |
|
29 EXPORT_C void SenMtomUtils::SerializeEnvelope2L(CSenSoapEnvelope2& aSoapEnvelope2, |
|
30 RBuf8& aXopEnvelope) |
|
31 { |
|
32 __ASSERT_ALWAYS(&aSoapEnvelope2, |
|
33 User::Panic(KMtomNoRequestSoapEnvelopePanicText, EMtomNoRequestSoapEnvelope)); |
|
34 RSenDocument doc = aSoapEnvelope2.AsDocumentL(); |
|
35 CXmlEngSerializer* serializer = CXmlEngSerializer::NewL(ESerializerXOPInfoset); |
|
36 __ASSERT_ALWAYS(serializer, User::Panic(KMtomPanicText, KErrNotFound)); |
|
37 CleanupStack::PushL(serializer); |
|
38 TXmlEngSerializationOptions options(TXmlEngSerializationOptions::KOptionIndent & TXmlEngSerializationOptions::KOptionOmitXMLDeclaration); |
|
39 serializer->SetOutput(aXopEnvelope); |
|
40 serializer->SetSerializationOptions(options); |
|
41 serializer->SerializeL(doc); |
|
42 CleanupStack::PopAndDestroy(serializer); |
|
43 } |
|
44 |
|
45 // --------------------------------------------------------------------------- |
|
46 // Generates random content-ID for header of XOP message and for headers of BLOBs |
|
47 // as randomNumber@homeTime |
|
48 // @param aRootCid is ReAlloc'd, which means that any existing data is freed |
|
49 // prior the generated root cid is assinged to that buffer. |
|
50 // --------------------------------------------------------------------------- |
|
51 // |
|
52 EXPORT_C void SenMtomUtils::GenerateRandomRootCidL(RBuf8& aRootCid) |
|
53 { |
|
54 _LIT8(KAt, "@"); |
|
55 TTime now; |
|
56 now.HomeTime(); |
|
57 TInt64 homeTime = now.Int64(); |
|
58 TInt64 randomNumber = Math::Random(); |
|
59 aRootCid.ReAllocL(32+KAt().Length()); |
|
60 aRootCid.AppendNum(randomNumber); |
|
61 aRootCid.Append(KAt); |
|
62 aRootCid.AppendNum(homeTime); |
|
63 } |
|
64 |
|
65 // --------------------------------------------------------------------------- |
|
66 // Generates random boundary for mime header as randomNumber |
|
67 // @param aBoundary is ReAlloc'd, which means that any existing data is freed |
|
68 // prior the generated root cid is assinged to that buffer. |
|
69 // --------------------------------------------------------------------------- |
|
70 // |
|
71 EXPORT_C void SenMtomUtils::GenerateRandomBoundaryL(RBuf8& aBoundary) |
|
72 { |
|
73 TInt64 randomNumber = Math::Random(); |
|
74 aBoundary.ReAllocL(16); |
|
75 aBoundary.AppendNum(randomNumber); |
|
76 } |
|
77 |
|
78 // --------------------------------------------------------------------------- |
|
79 // Generates MimeBoundary to separate mime parts of the message |
|
80 // as --randomNumber |
|
81 // --------------------------------------------------------------------------- |
|
82 // |
|
83 EXPORT_C void SenMtomUtils::BoundaryLineStartL(const RBuf8& aBoundary, RBuf8& aBoundaryStart) |
|
84 { |
|
85 aBoundaryStart.ReAllocL(KNewLine().Length()+KDush().Length()+aBoundary.Length()); |
|
86 aBoundaryStart.Append(KDush); |
|
87 aBoundaryStart.Append(aBoundary); |
|
88 aBoundaryStart.Append(KNewLine); |
|
89 } |
|
90 |
|
91 // --------------------------------------------------------------------------- |
|
92 // Generates MimeBoundaryEnd to end the multipart message (MTOM message) |
|
93 // as --randomNumber-- |
|
94 // --------------------------------------------------------------------------- |
|
95 // |
|
96 EXPORT_C void SenMtomUtils::BoundaryLineEndL(const RBuf8& aBoundary, RBuf8& aBoundaryEnd) |
|
97 { |
|
98 aBoundaryEnd.ReAllocL(3*KNewLine().Length()+2*KDush().Length()+aBoundary.Length()); |
|
99 aBoundaryEnd.Append(KNewLine); |
|
100 aBoundaryEnd.Append(KNewLine); |
|
101 aBoundaryEnd.Append(KDush); |
|
102 aBoundaryEnd.Append(aBoundary); |
|
103 aBoundaryEnd.Append(KDush); |
|
104 aBoundaryEnd.Append(KNewLine); |
|
105 } |
|
106 |
|
107 // --------------------------------------------------------------------------- |
|
108 // Creates header for root of XOP message |
|
109 // The header sould be the next: |
|
110 // |
|
111 // Content-Type: application/xop+xml; |
|
112 // charset=UTF-8; |
|
113 // type="text/xml" (for SOAP 1.1) or "application/soap+xml" (for SOAP 1.2) |
|
114 // Content-Transfer-Encoding: 8bit |
|
115 // Content-ID: <randomNumber@homeTime> |
|
116 // |
|
117 // where "Content-ID" is the same as "start" in Header of Outer Package |
|
118 // --------------------------------------------------------------------------- |
|
119 // |
|
120 EXPORT_C void SenMtomUtils::HeaderRootL(CSenSoapEnvelope2& aSoapEnvelope2, |
|
121 const RBuf8& aRootCid, RBuf8& aHeaderRoot) |
|
122 { |
|
123 switch (aSoapEnvelope2.SoapVersion()) |
|
124 { |
|
125 case ESOAP11: |
|
126 { |
|
127 aHeaderRoot.ReAllocL(KHeaderRootStart11().Length()+KHeaderRootEnd().Length()+aRootCid.Length()); |
|
128 aHeaderRoot.Append(KHeaderRootStart11); |
|
129 break; |
|
130 } |
|
131 case ESOAP12: |
|
132 { |
|
133 aHeaderRoot.ReAllocL(KHeaderRootStart12().Length()+KHeaderRootEnd().Length()+aRootCid.Length()); |
|
134 aHeaderRoot.Append(KHeaderRootStart12); |
|
135 break; |
|
136 } |
|
137 default: |
|
138 { |
|
139 User::Panic(KMtomSoapVersionInvalidPanicText, EMtomSoapVersionInvalid); |
|
140 } |
|
141 } |
|
142 aHeaderRoot.Append(aRootCid); |
|
143 aHeaderRoot.Append(KHeaderRootEnd); |
|
144 } |
|
145 |
|
146 // --------------------------------------------------------------------------- |
|
147 // Creates the header for binary data[aIndex] of XOP message |
|
148 // The header sould be the next: |
|
149 // |
|
150 // --MIME_boundary |
|
151 // Content-Type: image/png (for images) or some other type for other BLOBs |
|
152 // Content-Transfer-Encoding: binary |
|
153 // Content-ID: <randomNumber@homeTime> |
|
154 // |
|
155 // --------------------------------------------------------------------------- |
|
156 // |
|
157 EXPORT_C void SenMtomUtils::HeaderBinaryDataL(TUint aIndex, |
|
158 RArray<TXmlEngDataContainer>& aBinaryDataList, |
|
159 RBuf8& aHeaderBinaryData) |
|
160 { |
|
161 __ASSERT_ALWAYS(aBinaryDataList.Count(), User::Panic(KMtomNoBlobsPanicText, EMtomNoBlobs)); |
|
162 __ASSERT_ALWAYS((aIndex < aBinaryDataList.Count()), User::Panic(KMtomPanicText, KErrArgument)); |
|
163 |
|
164 TPtrC8 cid = aBinaryDataList[aIndex].Cid(); |
|
165 |
|
166 RXmlEngNodeList<TXmlEngAttr> attributes; // to take value of "ContentType" attribute |
|
167 aBinaryDataList[aIndex].ParentNode().AsElement().GetAttributes(attributes); |
|
168 CleanupClosePushL(attributes); |
|
169 |
|
170 RBuf8 contentType; |
|
171 CleanupClosePushL(contentType); |
|
172 while (attributes.HasNext()) |
|
173 { |
|
174 TXmlEngAttr attr = attributes.Next(); |
|
175 if (attr.Name() == KContentTypeName) |
|
176 { |
|
177 contentType.ReAllocL(attr.Value().Length()); |
|
178 contentType.Copy(attr.Value()); |
|
179 break; |
|
180 } |
|
181 } |
|
182 |
|
183 __ASSERT_ALWAYS((contentType != _L8("")), |
|
184 User::Panic(KMtomNoContentTypeInBlobHeaderPanicText, EMtomNoContentTypeInBlobHeader)); |
|
185 |
|
186 aHeaderBinaryData.ReAllocL(KHeaderBinaryDataContentType().Length()+ |
|
187 KHeaderBinaryDataContentID().Length()+ |
|
188 KHeaderBinaryDataEnd().Length()+ |
|
189 contentType.Length()+ |
|
190 cid.Length()); |
|
191 aHeaderBinaryData.Append(KHeaderBinaryDataContentType); |
|
192 aHeaderBinaryData.Append(contentType); |
|
193 aHeaderBinaryData.Append(KHeaderBinaryDataContentID); |
|
194 aHeaderBinaryData.Append(cid); |
|
195 aHeaderBinaryData.Append(KHeaderBinaryDataEnd); |
|
196 |
|
197 CleanupStack::PopAndDestroy(&contentType); |
|
198 CleanupStack::PopAndDestroy(&attributes); |
|
199 } |
|
200 |
|
201 // --------------------------------------------------------------------------- |
|
202 // Extracts a part of BLOB (10KB) from a file |
|
203 // --------------------------------------------------------------------------- |
|
204 // |
|
205 EXPORT_C void SenMtomUtils::FileDataPartL(TUint aPart, TUint aIndex, |
|
206 RArray<TXmlEngDataContainer>& aBinaryDataList, |
|
207 RBuf8& aBinaryData) |
|
208 { |
|
209 __ASSERT_ALWAYS(aBinaryDataList.Count(), User::Panic(KMtomNoBlobsPanicText, EMtomNoBlobs)); |
|
210 __ASSERT_ALWAYS((aIndex < aBinaryDataList.Count()), User::Panic(KMtomPanicText, KErrArgument)); |
|
211 |
|
212 aBinaryData.ReAllocL(KTenKBytes); |
|
213 |
|
214 RFile& file = aBinaryDataList[aIndex].AsFileContainer().File(); |
|
215 file.Flush(); |
|
216 file.Read(aPart*KTenKBytes, aBinaryData, KTenKBytes); |
|
217 } |
|
218 |
|
219 // --------------------------------------------------------------------------- |
|
220 // Extracts the rest of BLOB (less than 10KB) from a file |
|
221 // --------------------------------------------------------------------------- |
|
222 // |
|
223 EXPORT_C void SenMtomUtils::FileDataRestL(TUint aParts, TUint aRest, TUint aIndex, |
|
224 RArray<TXmlEngDataContainer>& aBinaryDataList, |
|
225 RBuf8& aBinaryData) |
|
226 { |
|
227 __ASSERT_ALWAYS(aBinaryDataList.Count(), User::Panic(KMtomNoBlobsPanicText, EMtomNoBlobs)); |
|
228 __ASSERT_ALWAYS((aIndex < aBinaryDataList.Count()), User::Panic(KMtomPanicText, KErrArgument)); |
|
229 |
|
230 aBinaryData.ReAllocL(aRest); |
|
231 RFile& file = aBinaryDataList[aIndex].AsFileContainer().File(); |
|
232 file.Flush(); |
|
233 file.Read(aParts*KTenKBytes, aBinaryData, aRest); |
|
234 } |
|
235 |
|
236 // --------------------------------------------------------------------------- |
|
237 // Extracts CIDs of BLOBs from response MTOM message |
|
238 // --------------------------------------------------------------------------- |
|
239 // |
|
240 EXPORT_C void SenMtomUtils::CidL(const RBuf8& aBlobHeader, RArray<RBuf8>& aCids) |
|
241 { |
|
242 _LIT8(KContentIDName, "Content-ID: <"); |
|
243 TInt offset = aBlobHeader.Find(KContentIDName); |
|
244 if (offset == KErrNotFound) |
|
245 { |
|
246 User::Panic(KMtomNoCidPanicText, EMtomNoCid); |
|
247 } |
|
248 TPtrC8 blobHeaderPtr; // to extract BLOB header from Response message |
|
249 blobHeaderPtr.Set(aBlobHeader.Right(aBlobHeader.Length()-offset-KContentIDName().Length())); |
|
250 |
|
251 offset = blobHeaderPtr.Find(_L8(">")); |
|
252 if (offset == KErrNotFound) |
|
253 { |
|
254 User::Panic(KMtomCidInvalidPanicText, EMtomCidInvalid); |
|
255 } |
|
256 RBuf8 cid; // CID of the BLOB |
|
257 cid.ReAllocL(offset); |
|
258 cid.Copy(blobHeaderPtr.Left(offset)); |
|
259 aCids.AppendL(cid); // collects CIDs of all BLOBs |
|
260 } |
|
261 |
|
262 // --------------------------------------------------------------------------- |
|
263 // Generates the file name for BLOB of response MTOM message |
|
264 // and collects it in array of file names for the all BLOBs |
|
265 // --------------------------------------------------------------------------- |
|
266 // |
|
267 void SenMtomUtils::FileNameL(TUint aIndex, RArray<RBuf8>& aFileNames) |
|
268 { |
|
269 RBuf8 fileName; |
|
270 fileName.ReAllocL(KFileName().Length()+7); |
|
271 fileName.Append(KFileName); |
|
272 fileName.AppendNum(aIndex); |
|
273 aFileNames.Append(fileName); |
|
274 } |
|
275 |
|
276 // --------------------------------------------------------------------------- |
|
277 // Extracts BLOB from response MTOM message and writes it in a file |
|
278 // --------------------------------------------------------------------------- |
|
279 // |
|
280 EXPORT_C TInt SenMtomUtils::SetFileL(TUint aIndex, TBool aFirst, TDesC8& aBlob, |
|
281 RArray<RBuf8>& aFileNames) |
|
282 { |
|
283 RFs rfs; |
|
284 RFile file; |
|
285 User::LeaveIfError(rfs.Connect()); |
|
286 CleanupClosePushL(rfs); |
|
287 TInt retVal = rfs.ShareProtected(); |
|
288 CleanupClosePushL(file); |
|
289 |
|
290 TInt sizeFile = 0; |
|
291 RBuf fileName; //fileName is necessary to convert from 8bites(aFileNames[aIndex]) to 16 |
|
292 |
|
293 if (aFirst) // check if is it the first part of a BLOB to write in a file |
|
294 { |
|
295 FileNameL(aIndex, aFileNames); // generates the new file |
|
296 fileName.ReAllocL(aFileNames[aIndex].Length()); |
|
297 fileName.Copy(aFileNames[aIndex]); |
|
298 User::LeaveIfError(file.Replace(rfs, fileName, EFileWrite)); // replases the old one to the new one |
|
299 } |
|
300 else // if it's not the first part of BLOB then only open the existing file and write a BLOB part in it |
|
301 { |
|
302 fileName.ReAllocL(aFileNames[aIndex].Length()); |
|
303 fileName.Copy(aFileNames[aIndex]); |
|
304 User::LeaveIfError(file.Open(rfs, fileName, EFileWrite)); |
|
305 } |
|
306 |
|
307 file.Size(sizeFile); |
|
308 User::LeaveIfError(file.Write(sizeFile, aBlob, aBlob.Length())); |
|
309 |
|
310 file.Flush(); |
|
311 file.Close(); |
|
312 |
|
313 User::LeaveIfError(file.Open(rfs, fileName, EFileRead)); |
|
314 fileName.Close(); |
|
315 CleanupStack::PopAndDestroy(&file); |
|
316 CleanupStack::PopAndDestroy(&rfs); |
|
317 return (sizeFile+aBlob.Length()); |
|
318 } |
|
319 |
|
320 // End of file |
|
321 |