fixing memory leaks & mem tracing false alerts
[wxWidgets.git] / src / common / mimecmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/mimecmn.cpp
3 // Purpose: classes and functions to manage MIME types
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 23.09.98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license (part of wxExtra library)
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "mimetypebase.h"
14 #endif
15
16 // for compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18 #include "wx/module.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/defs.h"
26 #endif
27
28 #if (wxUSE_FILE && wxUSE_TEXTFILE) || defined(__WXMSW__)
29
30 #ifndef WX_PRECOMP
31 #include "wx/string.h"
32 #if wxUSE_GUI
33 #include "wx/icon.h"
34 #endif
35 #endif //WX_PRECOMP
36
37 // Doesn't compile in WIN16 mode
38 #ifndef __WIN16__
39
40 #include "wx/log.h"
41 #include "wx/file.h"
42 #include "wx/intl.h"
43 #include "wx/dynarray.h"
44 #include "wx/confbase.h"
45
46 #ifdef __WXMSW__
47 #include "wx/msw/registry.h"
48 #include "windows.h"
49 #elif defined(__UNIX__) || defined(__WXPM__)
50 #include "wx/ffile.h"
51 #include "wx/textfile.h"
52 #include "wx/dir.h"
53 #include "wx/utils.h"
54 #include "wx/tokenzr.h"
55 #endif // OS
56
57 #include "wx/mimetype.h"
58
59 // other standard headers
60 #include <ctype.h>
61
62 // in case we're compiling in non-GUI mode
63 class WXDLLEXPORT wxIcon;
64
65
66 // implementation classes:
67
68 #if defined(__WXMSW__)
69 #include "wx/msw/mimetype.h"
70 #elif defined (__WXMAC__)
71 #include "wx/mac/mimetype.h"
72 #elif defined (__WXPM__)
73 #include "wx/os2/mimetype.h"
74 #else
75 #include "wx/unix/mimetype.h"
76 #endif
77
78 // ============================================================================
79 // common classes
80 // ============================================================================
81
82 // ----------------------------------------------------------------------------
83 // wxFileTypeInfo
84 // ----------------------------------------------------------------------------
85
86 wxFileTypeInfo::wxFileTypeInfo(const char *mimeType,
87 const char *openCmd,
88 const char *printCmd,
89 const char *desc,
90 ...)
91 : m_mimeType(mimeType),
92 m_openCmd(openCmd),
93 m_printCmd(printCmd),
94 m_desc(desc)
95 {
96 va_list argptr;
97 va_start(argptr, desc);
98
99 for ( ;; )
100 {
101 const char *ext = va_arg(argptr, const char *);
102 if ( !ext )
103 {
104 // NULL terminates the list
105 break;
106 }
107
108 m_exts.Add(ext);
109 }
110
111 va_end(argptr);
112 }
113
114 #include "wx/arrimpl.cpp"
115 WX_DEFINE_OBJARRAY(wxArrayFileTypeInfo);
116
117
118 // ============================================================================
119 // implementation of the wrapper classes
120 // ============================================================================
121
122 // ----------------------------------------------------------------------------
123 // wxFileType
124 // ----------------------------------------------------------------------------
125
126 wxString wxFileType::ExpandCommand(const wxString& command,
127 const wxFileType::MessageParameters& params)
128 {
129 bool hasFilename = FALSE;
130
131 wxString str;
132 for ( const wxChar *pc = command.c_str(); *pc != wxT('\0'); pc++ ) {
133 if ( *pc == wxT('%') ) {
134 switch ( *++pc ) {
135 case wxT('s'):
136 // '%s' expands into file name (quoted because it might
137 // contain spaces) - except if there are already quotes
138 // there because otherwise some programs may get confused
139 // by double double quotes
140 #if 0
141 if ( *(pc - 2) == wxT('"') )
142 str << params.GetFileName();
143 else
144 str << wxT('"') << params.GetFileName() << wxT('"');
145 #endif
146 str << params.GetFileName();
147 hasFilename = TRUE;
148 break;
149
150 case wxT('t'):
151 // '%t' expands into MIME type (quote it too just to be
152 // consistent)
153 str << wxT('\'') << params.GetMimeType() << wxT('\'');
154 break;
155
156 case wxT('{'):
157 {
158 const wxChar *pEnd = wxStrchr(pc, wxT('}'));
159 if ( pEnd == NULL ) {
160 wxString mimetype;
161 wxLogWarning(_("Unmatched '{' in an entry for "
162 "mime type %s."),
163 params.GetMimeType().c_str());
164 str << wxT("%{");
165 }
166 else {
167 wxString param(pc + 1, pEnd - pc - 1);
168 str << wxT('\'') << params.GetParamValue(param) << wxT('\'');
169 pc = pEnd;
170 }
171 }
172 break;
173
174 case wxT('n'):
175 case wxT('F'):
176 // TODO %n is the number of parts, %F is an array containing
177 // the names of temp files these parts were written to
178 // and their mime types.
179 break;
180
181 default:
182 wxLogDebug(wxT("Unknown field %%%c in command '%s'."),
183 *pc, command.c_str());
184 str << *pc;
185 }
186 }
187 else {
188 str << *pc;
189 }
190 }
191
192 // metamail(1) man page states that if the mailcap entry doesn't have '%s'
193 // the program will accept the data on stdin: so give it to it!
194 if ( !hasFilename && !str.IsEmpty() ) {
195 str << wxT(" < '") << params.GetFileName() << wxT('\'');
196 }
197
198 return str;
199 }
200
201 wxFileType::wxFileType()
202 {
203 m_impl = new wxFileTypeImpl;
204 }
205
206 wxFileType::~wxFileType()
207 {
208 delete m_impl;
209 }
210
211 bool wxFileType::GetExtensions(wxArrayString& extensions)
212 {
213 return m_impl->GetExtensions(extensions);
214 }
215
216 bool wxFileType::GetMimeType(wxString *mimeType) const
217 {
218 return m_impl->GetMimeType(mimeType);
219 }
220
221 bool wxFileType::GetMimeTypes(wxArrayString& mimeTypes) const
222 {
223 return m_impl->GetMimeTypes(mimeTypes);
224 }
225
226 bool wxFileType::GetIcon(wxIcon *icon) const
227 {
228 return m_impl->GetIcon(icon);
229 }
230
231 bool wxFileType::GetDescription(wxString *desc) const
232 {
233 return m_impl->GetDescription(desc);
234 }
235
236 bool
237 wxFileType::GetOpenCommand(wxString *openCmd,
238 const wxFileType::MessageParameters& params) const
239 {
240 return m_impl->GetOpenCommand(openCmd, params);
241 }
242
243 bool
244 wxFileType::GetPrintCommand(wxString *printCmd,
245 const wxFileType::MessageParameters& params) const
246 {
247 return m_impl->GetPrintCommand(printCmd, params);
248 }
249
250 // ----------------------------------------------------------------------------
251 // wxMimeTypesManager
252 // ----------------------------------------------------------------------------
253
254 void wxMimeTypesManager::EnsureImpl()
255 {
256 if (m_impl == NULL)
257 m_impl = new wxMimeTypesManagerImpl;
258 }
259
260 bool wxMimeTypesManager::IsOfType(const wxString& mimeType,
261 const wxString& wildcard)
262 {
263 wxASSERT_MSG( mimeType.Find(wxT('*')) == wxNOT_FOUND,
264 wxT("first MIME type can't contain wildcards") );
265
266 // all comparaisons are case insensitive (2nd arg of IsSameAs() is FALSE)
267 if ( wildcard.BeforeFirst(wxT('/')).IsSameAs(mimeType.BeforeFirst(wxT('/')), FALSE) )
268 {
269 wxString strSubtype = wildcard.AfterFirst(wxT('/'));
270
271 if ( strSubtype == wxT("*") ||
272 strSubtype.IsSameAs(mimeType.AfterFirst(wxT('/')), FALSE) )
273 {
274 // matches (either exactly or it's a wildcard)
275 return TRUE;
276 }
277 }
278
279 return FALSE;
280 }
281
282 wxMimeTypesManager::wxMimeTypesManager()
283 {
284 m_impl = NULL;
285 }
286
287 wxMimeTypesManager::~wxMimeTypesManager()
288 {
289 if (m_impl != NULL)
290 delete m_impl;
291 }
292
293 wxFileType *
294 wxMimeTypesManager::GetFileTypeFromExtension(const wxString& ext)
295 {
296 EnsureImpl();
297 return m_impl->GetFileTypeFromExtension(ext);
298 }
299
300 wxFileType *
301 wxMimeTypesManager::GetFileTypeFromMimeType(const wxString& mimeType)
302 {
303 EnsureImpl();
304 return m_impl->GetFileTypeFromMimeType(mimeType);
305 }
306
307 bool wxMimeTypesManager::ReadMailcap(const wxString& filename, bool fallback)
308 {
309 EnsureImpl();
310 return m_impl->ReadMailcap(filename, fallback);
311 }
312
313 bool wxMimeTypesManager::ReadMimeTypes(const wxString& filename)
314 {
315 EnsureImpl();
316 return m_impl->ReadMimeTypes(filename);
317 }
318
319 void wxMimeTypesManager::AddFallbacks(const wxFileTypeInfo *filetypes)
320 {
321 EnsureImpl();
322 for ( const wxFileTypeInfo *ft = filetypes; ft->IsValid(); ft++ ) {
323 m_impl->AddFallback(*ft);
324 }
325 }
326
327 size_t wxMimeTypesManager::EnumAllFileTypes(wxArrayString& mimetypes)
328 {
329 EnsureImpl();
330 return m_impl->EnumAllFileTypes(mimetypes);
331 }
332
333
334 // ----------------------------------------------------------------------------
335 // global data
336 // ----------------------------------------------------------------------------
337
338 // private object
339 static wxMimeTypesManager gs_mimeTypesManager;
340
341 // and public pointer
342 wxMimeTypesManager * wxTheMimeTypesManager = &gs_mimeTypesManager;
343
344
345
346
347
348 class wxMimeTypeCmnModule: public wxModule
349 {
350 DECLARE_DYNAMIC_CLASS(wxMimeTypeCmnModule)
351 public:
352 wxMimeTypeCmnModule() : wxModule() {}
353 bool OnInit() { return TRUE; }
354 void OnExit()
355 { // this avoids false memory leak allerts:
356 if (gs_mimeTypesManager.m_impl != NULL)
357 {
358 delete gs_mimeTypesManager.m_impl;
359 gs_mimeTypesManager.m_impl = NULL;
360 }
361 }
362 };
363
364 IMPLEMENT_DYNAMIC_CLASS(wxMimeTypeCmnModule, wxModule)
365
366
367
368 #endif
369 // wxUSE_FILE && wxUSE_TEXTFILE
370
371 #endif
372 // __WIN16__