|
1 // Copyright (c) 2005-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 /** @file |
|
17 @internalComponent */ |
|
18 #include "ImageDisplayFramework.h" |
|
19 |
|
20 #include "ImageDisplay.hrh" |
|
21 #include "../../src/ImageUtils.h" |
|
22 #include "ImageDisplayResolvrUtils.h" |
|
23 |
|
24 #include "ImageDisplayRecognizer.h" |
|
25 |
|
26 NONSHARABLE_CLASS( CImgDisplayMimeTypeRecognizer::CBody) : public CActive |
|
27 { |
|
28 public: |
|
29 static CBody* NewL(); |
|
30 ~CBody(); |
|
31 TBool GetTypeByFileDataL(const TDesC8& aImageData, TDes8& aMimeType); |
|
32 TBool GetTypeByFileNameL(const TDesC& aFileName, TDes8& aMimeType); |
|
33 void GetFileTypesL(RFileExtensionMIMETypeArray& aExtArray); |
|
34 |
|
35 protected: |
|
36 |
|
37 //from CActive |
|
38 virtual void DoCancel(); |
|
39 virtual void RunL(); |
|
40 private: |
|
41 CBody(); |
|
42 void ConstructL(); |
|
43 void StartNotification(); |
|
44 void BuildPluginListL(); |
|
45 |
|
46 private: |
|
47 /** an array of pointers to CImplementationInformation objects */ |
|
48 RImplInfoPtrArray iPluginArray; |
|
49 /** for opening a session to the ECom server */ |
|
50 REComSession iEcomSession; |
|
51 /** used when creating decoders */ |
|
52 RFs iFs; |
|
53 }; |
|
54 |
|
55 /** |
|
56 object factory function |
|
57 @return class instance pointer |
|
58 */ |
|
59 EXPORT_C CImgDisplayMimeTypeRecognizer* CImgDisplayMimeTypeRecognizer::NewL() |
|
60 { |
|
61 CImgDisplayMimeTypeRecognizer* self=new (ELeave) CImgDisplayMimeTypeRecognizer(); |
|
62 CleanupStack::PushL(self); |
|
63 self->ConstructL(); |
|
64 CleanupStack::Pop(self); |
|
65 return self; |
|
66 } |
|
67 |
|
68 CImgDisplayMimeTypeRecognizer::CImgDisplayMimeTypeRecognizer() |
|
69 { |
|
70 } |
|
71 |
|
72 /** |
|
73 destructor |
|
74 */ |
|
75 CImgDisplayMimeTypeRecognizer::~CImgDisplayMimeTypeRecognizer() |
|
76 { |
|
77 delete iBody; |
|
78 } |
|
79 |
|
80 void CImgDisplayMimeTypeRecognizer::ConstructL() |
|
81 { |
|
82 iBody = CBody::NewL(); |
|
83 } |
|
84 |
|
85 /** |
|
86 @param aExtArray array that will be filled with supported file extension information. Information is appended to existing array. |
|
87 */ |
|
88 EXPORT_C void CImgDisplayMimeTypeRecognizer::GetFileTypesL(RFileExtensionMIMETypeArray& aExtArray) |
|
89 { |
|
90 iBody->GetFileTypesL(aExtArray); |
|
91 } |
|
92 |
|
93 /** |
|
94 determines Mime type by using filename and its content |
|
95 @param aImageData file data |
|
96 @param aFileName file name |
|
97 @param aMimeType reference to a buffer that would be given mime type value upon successfull recognition |
|
98 @return ETrue if Mime type has been recognized |
|
99 */ |
|
100 EXPORT_C TBool CImgDisplayMimeTypeRecognizer::GetMimeTypeL(const TDesC8& aImageData, const TDesC& aFileName, TDes8& aMimeType) |
|
101 { |
|
102 TBool gotType=EFalse; |
|
103 aMimeType.SetLength(0); |
|
104 if (aImageData.Length()!=0) |
|
105 { |
|
106 gotType=iBody->GetTypeByFileDataL(aImageData, aMimeType); |
|
107 } |
|
108 if (!gotType && aFileName.Length()!=0) |
|
109 { |
|
110 gotType=iBody->GetTypeByFileNameL(aFileName, aMimeType); |
|
111 } |
|
112 return gotType; |
|
113 } |
|
114 |
|
115 CImgDisplayMimeTypeRecognizer::CBody* CImgDisplayMimeTypeRecognizer::CBody::NewL() |
|
116 { |
|
117 CImgDisplayMimeTypeRecognizer::CBody* self=new (ELeave) CImgDisplayMimeTypeRecognizer::CBody(); |
|
118 CleanupStack::PushL(self); |
|
119 self->ConstructL(); |
|
120 CleanupStack::Pop(self); |
|
121 return self; |
|
122 } |
|
123 |
|
124 CImgDisplayMimeTypeRecognizer::CBody::CBody(): |
|
125 CActive(CActive::EPriorityStandard) |
|
126 { |
|
127 } |
|
128 |
|
129 CImgDisplayMimeTypeRecognizer::CBody::~CBody() |
|
130 { |
|
131 Cancel(); |
|
132 iEcomSession.Close(); |
|
133 iFs.Close(); |
|
134 iPluginArray.ResetAndDestroy(); |
|
135 } |
|
136 |
|
137 // Request ECom to be notified when interface implementation registration |
|
138 // data changes so that we can refresh the list of interface implementations. |
|
139 void CImgDisplayMimeTypeRecognizer::CBody::StartNotification() |
|
140 { |
|
141 iEcomSession.NotifyOnChange(iStatus); |
|
142 SetActive(); |
|
143 } |
|
144 |
|
145 // build a list of interface implementation objects |
|
146 void CImgDisplayMimeTypeRecognizer::CBody::BuildPluginListL() |
|
147 { |
|
148 iPluginArray.ResetAndDestroy(); |
|
149 REComSession::ListImplementationsL( |
|
150 TUid::Uid(KUidDisplayInterface), |
|
151 iPluginArray); |
|
152 } |
|
153 |
|
154 inline |
|
155 TBool IsExtAlreadyAdded(const RFileExtensionMIMETypeArray& aExtArray, const TDesC8& aExt) |
|
156 { |
|
157 TFileName extU; |
|
158 extU.Copy(aExt); |
|
159 for (TInt i=aExtArray.Count(); i--;) |
|
160 { |
|
161 const TDesC& ext=(*aExtArray[i]).FileExtension(); |
|
162 if (ext.Length()==extU.Length() && extU.CompareF(ext)==0) |
|
163 { |
|
164 return ETrue; |
|
165 } |
|
166 } |
|
167 return EFalse; |
|
168 } |
|
169 |
|
170 inline |
|
171 TBool IsMimeAlreadyAdded(const RFileExtensionMIMETypeArray& aExtArray, const TDesC8& aMime) |
|
172 { |
|
173 for (TInt i=aExtArray.Count(); i--;) |
|
174 { |
|
175 const TDesC8& mime=(*aExtArray[i]).MIMEType(); |
|
176 if (mime.Length()==aMime.Length() && aMime.CompareF(mime)==0) |
|
177 { |
|
178 return ETrue; |
|
179 } |
|
180 } |
|
181 return EFalse; |
|
182 } |
|
183 |
|
184 void CImgDisplayMimeTypeRecognizer::CBody::GetFileTypesL(RFileExtensionMIMETypeArray& aExtArray) |
|
185 { |
|
186 for (TInt i=iPluginArray.Count(); i--;) |
|
187 { |
|
188 const CImplementationInformation& impData = *(iPluginArray[i]); |
|
189 COpaqueDataParse* parse = COpaqueDataParse::NewLC(impData.OpaqueData()); |
|
190 |
|
191 parse->EnsureMIMETypesReadL(); |
|
192 |
|
193 if (parse->MIMEType(0).Length() && !IsMimeAlreadyAdded(aExtArray, parse->MIMEType(0))) |
|
194 { |
|
195 parse->EnsureExtnsReadL(); |
|
196 for (TInt extN=parse->ExtnsCount(); extN--;) |
|
197 { |
|
198 if (parse->Extn(extN).Length()==0 || IsExtAlreadyAdded(aExtArray, parse->Extn(extN))) |
|
199 { |
|
200 continue; |
|
201 } |
|
202 CFileExtensionMIMEType* ext=CFileExtensionMIMEType::NewLC( |
|
203 parse->Extn(extN), |
|
204 parse->MIMEType(0), // we always use the FIRST MIME type |
|
205 impData.DisplayName(), |
|
206 parse->ImageTypeUid(), |
|
207 parse->ImageSubTypeUid(), |
|
208 impData.ImplementationUid() |
|
209 ); |
|
210 User::LeaveIfError( aExtArray.Append(ext) ); |
|
211 CleanupStack::Pop(ext); |
|
212 } |
|
213 } |
|
214 CleanupStack::PopAndDestroy(parse); |
|
215 } |
|
216 } |
|
217 |
|
218 void CImgDisplayMimeTypeRecognizer::CBody::ConstructL() |
|
219 { |
|
220 BuildPluginListL(); |
|
221 CActiveScheduler::Add(this); |
|
222 User::LeaveIfError(iFs.Connect()); |
|
223 iEcomSession = REComSession::OpenL(); |
|
224 // request notification from ECOM of any file system changes |
|
225 StartNotification(); |
|
226 } |
|
227 |
|
228 void CImgDisplayMimeTypeRecognizer::CBody::RunL() |
|
229 { |
|
230 BuildPluginListL(); |
|
231 StartNotification(); |
|
232 } |
|
233 |
|
234 void CImgDisplayMimeTypeRecognizer::CBody::DoCancel() |
|
235 { |
|
236 if (iStatus == KRequestPending) |
|
237 { |
|
238 iEcomSession.CancelNotifyOnChange(iStatus); |
|
239 } |
|
240 } |
|
241 |
|
242 TBool CImgDisplayMimeTypeRecognizer::CBody::GetTypeByFileNameL( |
|
243 const TDesC& aFileName, |
|
244 TDes8& aMimeType) |
|
245 { |
|
246 aMimeType.SetLength(0); |
|
247 TParse fileName; |
|
248 fileName.Set(aFileName,NULL,NULL); |
|
249 |
|
250 //No file extension |
|
251 if (!fileName.ExtPresent()) |
|
252 { |
|
253 return EFalse; |
|
254 } |
|
255 const TPtrC suffix(fileName.Ext()); |
|
256 |
|
257 for (TInt i=iPluginArray.Count(); i--;) |
|
258 { |
|
259 const CImplementationInformation& impData = *(iPluginArray[i]); |
|
260 COpaqueDataParse* parse = COpaqueDataParse::NewLC(impData.OpaqueData()); |
|
261 parse->EnsureExtnsReadL(); |
|
262 TFileName ext; |
|
263 TBool match=EFalse; |
|
264 for (TInt extN=0; !match && extN<parse->ExtnsCount(); ++extN) |
|
265 { |
|
266 ext.Copy(parse->Extn(extN)); |
|
267 match=(ext.Length()==suffix.Length() && ext.CompareF(suffix)==0); |
|
268 } |
|
269 if (match) |
|
270 { |
|
271 parse->EnsureMIMETypesReadL(); |
|
272 aMimeType.Copy(parse->MIMEType(0)); // we always use the FIRST MIME type |
|
273 } |
|
274 CleanupStack::PopAndDestroy(parse); |
|
275 if (match) |
|
276 { |
|
277 return ETrue; |
|
278 } |
|
279 } |
|
280 return EFalse; |
|
281 } |
|
282 |
|
283 TBool CImgDisplayMimeTypeRecognizer::CBody::GetTypeByFileDataL(const TDesC8& aImageData, TDes8& aMimeType) |
|
284 { |
|
285 aMimeType.SetLength(0); |
|
286 for (TInt i=iPluginArray.Count(); i--;) |
|
287 { |
|
288 const CImplementationInformation& impData = *(iPluginArray[i]); |
|
289 TInt bytesMatched=0; |
|
290 TBool match=CImageDisplayResolverUtils::Match(aImageData, impData.DataType(), bytesMatched); |
|
291 if (match && bytesMatched==impData.DataType().Length()) |
|
292 { |
|
293 COpaqueDataParse* parse = COpaqueDataParse::NewLC(impData.OpaqueData()); |
|
294 parse->EnsureMIMETypesReadL(); |
|
295 aMimeType.Copy(parse->MIMEType(0)); // we always use the FIRST MIME type |
|
296 CleanupStack::PopAndDestroy(parse); |
|
297 if (aMimeType.Length()==0) |
|
298 { |
|
299 // we've got plug-in with empty MIME type i.e. generic one, so |
|
300 // it doesn't have MIME type and can't be used to recognize data |
|
301 continue; |
|
302 } |
|
303 return ETrue; |
|
304 } |
|
305 } |
|
306 return EFalse; |
|
307 } |
|
308 |
|
309 |
|
310 |
|
311 |
|
312 |