1//
2// This file is part of the aMule Project.
3//
4// Copyright (c) 2003-2011 aMule Team ( admin@amule.org / http://www.amule.org )
5// Copyright (c) 2002-2011 Merkur ( devs@emule-project.net / http://www.emule-project.net )
6//
7// Any parts of this program derived from the xMule, lMule or eMule project,
8// or contributed by third-party developers are copyrighted by their
9// respective authors.
10//
11// This program is free software; you can redistribute it and/or modify
12// it under the terms of the GNU General Public License as published by
13// the Free Software Foundation; either version 2 of the License, or
14// (at your option) any later version.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
24//
25
26#ifndef OTHERFUNCTIONS_H
27#define OTHERFUNCTIONS_H
28
29#include <wx/intl.h>		// Needed for wxLANGUAGE_ constants
30
31#include "Types.h"		// Needed for uint16, uint32 and uint64
32#include "Preferences.h"	// Needed for AllCategoryFilter enumeration
33
34#include <algorithm>		// Needed for std::for_each	// Do_not_auto_remove (mingw-gcc-3.4.5)
35
36
37class CPath;
38
39
40/**
41 * Helper function.
42 *
43 * @param ArgA The base value.
44 * @param ArgB The value to compare ArgA against.
45 * @return See below.
46 *
47 * Use this function to safely compare two arguments of a type that supports
48 * the "<" operator. It works like strcmp and returns a negative value if ArgA
49 * is less than ArgB, zero if ArgA is equal to ArgB and a positive value if
50 * ArgA is greater than ArgB.
51 */
52template <class TYPE>
53int CmpAny(const TYPE& ArgA, const TYPE& ArgB)
54{
55	if ( ArgA < ArgB ) {
56		return -1;
57	} else if ( ArgB < ArgA ) {
58		return  1;
59	} else {
60		return  0;
61	}
62}
63
64//! Overloaded version of CmpAny for use with wxStrings.
65inline int CmpAny(const wxString& ArgA, const wxString& ArgB)
66{
67	if (ArgA.IsEmpty() && !ArgB.IsEmpty()) {
68		return -1;
69	} else if (!ArgA.IsEmpty() && ArgB.IsEmpty()) {
70		return 1;
71	} else if (ArgA.IsEmpty() && ArgB.IsEmpty()) {
72		return 0;
73	} else {
74		return ArgA.CmpNoCase( ArgB );
75	}
76}
77
78//! Overloaded version of CmpAny for use with C-Strings (Unicoded).
79inline int CmpAny(const wxChar* ArgA, const wxChar* ArgB)
80{
81	return CmpAny(wxString( ArgA ), wxString( ArgB ));
82}
83
84
85/**
86 * Removes the first instance of a value from a STL-like list: list, vector or deque.
87 *
88 * @param list The list to manipulate.
89 * @param item The value to search for and remove.
90 * @return The number of instances removed.
91 */
92template <typename LIST, typename ITEM>
93unsigned int EraseFirstValue( LIST& list, const ITEM& item )
94{
95	typename LIST::iterator it = list.begin();
96
97	for (; it != list.end(); ++it) {
98		if (*it == item) {
99			list.erase(it);
100
101			return true;
102		}
103	}
104
105	return false;
106}
107
108
109/**
110 * Removes all instances of a value from a STL-like list: list, vector or deque.
111 *
112 * @param list The list to manipulate.
113 * @param item The value to search for and remove.
114 * @return The number of instances removed.
115 */
116template <typename LIST, typename ITEM>
117unsigned int EraseValue( LIST& list, const ITEM& item )
118{
119	typename LIST::iterator it = list.begin();
120	unsigned int count = 0;
121
122	for ( ; it != list.end(); ) {
123		if ( *it == item ) {
124			it = list.erase( it );
125			count++;
126		} else {
127			++it;
128		}
129	}
130
131	return count;
132}
133
134
135//! Used by DeleteContents
136struct SDoDelete
137{
138	// Used for lists, vectors, deques, etc.
139	template <typename TYPE>
140	void operator()(TYPE* ptr) {
141		delete ptr;
142	}
143
144	// Used for maps, hashmaps, rangemaps, etc.
145	template <typename FIRST, typename SECOND>
146	void operator()(const std::pair<FIRST, SECOND>& pair) {
147		delete pair.second;
148	}
149};
150
151
152/** Frees the contents of a list or map like stl container, clearing it afterwards. */
153template <typename STL_CONTAINER>
154void DeleteContents(STL_CONTAINER& container)
155{
156	// Ensure that the actual container wont contain dangling pointers during
157	// this operation, to ensure that the destructors cant access them.
158	STL_CONTAINER copy;
159
160	std::swap(copy, container);
161	std::for_each(copy.begin(), copy.end(), SDoDelete());
162}
163
164
165/**
166 * Copies elements from the range [first, first + n) to the range [result, result + n).
167 */
168template <class InputIterator, class OutputIterator>
169OutputIterator STLCopy_n(InputIterator first, size_t n, OutputIterator result)
170{
171	return std::copy(first, first + n, result);
172}
173
174
175/**
176 * Returns a description of the version of aMule being used.
177 *
178 * @return A detailed description of the aMule version, including wx information.
179 *
180 * Use this rather than just using the VERSION or CURRENT_VERSION_LONG
181 * constants, when displaying information to the user. The purpose is to
182 * help with debugging.
183 */
184wxString GetMuleVersion();
185
186
187/**
188 * Helperfunction for accessing a child of the calling widget.
189 *
190 * @param IdOrName The ID or the Name of the widget to find.
191 * @param type The widget-type to cast the found widget to.
192 *
193 * Use this function as a replacement for the following constructs:
194 *  - wxStaticCast( FindWindow( <IdOrName> ), <type> )
195 *  - (<type>*)FindWindow( <IdOrName> )
196 *
197 * It has the advantage of validating the cast in debug builds and being much
198 * shorter than than manually typing wxStaticCast + FindWindow. This mean that
199 * we will be alerted in case of widget changing type, instead of getting just
200 * getting bad mojo due to casting a pointer to the wrong type.
201 */
202#define CastChild( IdOrName, type )			dynamic_cast<type*>( FindWindow( IdOrName ) )
203
204
205/**
206 * Helperfunction for accessing the child of a any widget by ID.
207 *
208 * @param ID The ID of the widget to find.
209 * @param parent The parent of the widget to find, or NULL to search from the top.
210 * @param type The type to cast the widget to.
211 *
212 * @see CastChild()
213 */
214#define CastByID( ID, parent, type )		dynamic_cast<type*>( wxWindow::FindWindowById( (ID), (parent) ) )
215
216
217/**
218 * Helperfunction for accessing the child of a any widget by Name.
219 *
220 * @param Name The Name of the widget to find.
221 * @param parent The parent of the widget to find, or NULL to search from the top.
222 * @param type The type to cast the widget to.
223 *
224 * @see CastChild()
225 */
226#define CastByName( Name, parent, type )	dynamic_cast<type*>( wxWindow::FindWindowByName( (Name), (parent) ) )
227
228
229// From Gnucleus project [found by Tarod]
230// Base16/Base32/Base64 Encode/Decode functions
231wxString EncodeBase16(const unsigned char* buffer, unsigned int bufLen);
232unsigned int DecodeBase16(const wxString &base16Buffer, unsigned int base16BufLen, unsigned char *buffer);
233wxString EncodeBase32(const unsigned char* buffer, unsigned int bufLen);
234unsigned int DecodeBase32(const wxString &base32Buffer, unsigned int base32BufLen, unsigned char *buffer);
235wxString EncodeBase64(const char* buffer, unsigned int bufLen);
236unsigned int DecodeBase64(const wxString &base64Buffer, unsigned int base64BufLen, unsigned char *buffer);
237
238// Converts the number of bytes to human readable form.
239wxString CastItoXBytes(uint64 count);
240// Converts the number to human readable form, abbreviating when nessecary.
241wxString CastItoIShort(uint64 number);
242// Converts a number of bytes to a human readable speed value.
243wxString CastItoSpeed(uint32 bytes);
244// Converts an amount of seconds to human readable time.
245wxString CastSecondsToHM(uint32 seconds, uint16 msecs = 0);
246// Returns the amount of Bytes the provided size-type represents
247uint32 GetTypeSize(uint8 type);
248// Returns the string associated with a file-rating value.
249wxString GetRateString(uint16 rate);
250
251
252// The following functions are used to identify and/or name the type of a file
253enum FileType { ftAny, ftVideo, ftAudio, ftArchive, ftCDImage, ftPicture, ftText, ftProgram };
254// Examins a filename and returns the enumerated value assosiated with it, or ftAny if unknown extension
255FileType GetFiletype(const CPath& filename);
256// Returns the description of a filetype: Movies, Audio, Pictures and so on...
257wxString GetFiletypeDesc(FileType type, bool translated = true);
258// Shorthand for GetFiletypeDesc(GetFiletype(filename))
259wxString GetFiletypeByName(const CPath& filename, bool translated = true);
260
261
262// Returns the name associated with a category value.
263wxString GetCatTitle(AllCategoryFilter cat);
264
265/* Other */
266
267
268//! Returns the number of items in an array.
269#define itemsof(x) (sizeof(x)/sizeof(x[0]))
270
271
272///////////////////////////////////////////////////////////////////////////////
273// ED2K File Type
274//
275
276enum EED2KFileType
277{
278	ED2KFT_ANY,
279	ED2KFT_AUDIO,
280	ED2KFT_VIDEO,
281	ED2KFT_IMAGE,
282	ED2KFT_PROGRAM,
283	ED2KFT_DOCUMENT,
284	ED2KFT_ARCHIVE,
285	ED2KFT_CDIMAGE
286};
287
288class EED2KFileTypeClass
289{
290public:
291	EED2KFileTypeClass()
292	{
293		s_t = ED2KFT_ANY;
294	}
295	EED2KFileTypeClass(EED2KFileType t)
296	{
297		s_t = t;
298	}
299	EED2KFileType GetType() const
300	{
301		return s_t;
302	}
303
304private:
305	EED2KFileType s_t;
306};
307
308EED2KFileType GetED2KFileTypeID(const CPath& fileName);
309wxString GetED2KFileTypeSearchTerm(EED2KFileType iFileID);
310wxString GetFileTypeByName(const CPath& fileName);
311EED2KFileType GetED2KFileTypeSearchID(EED2KFileType iFileID);
312///////////////////////////////////////////////////////////////////////////////
313
314// md4cmp -- replacement for memcmp(hash1,hash2,16)
315// Like 'memcmp' this function returns 0, if hash1==hash2, and !0, if hash1!=hash2.
316// NOTE: Do *NOT* use that function for determining if hash1<hash2 or hash1>hash2.
317inline int md4cmp(const void* hash1, const void* hash2)
318{
319	return memcmp(hash1, hash2, 16);
320}
321
322
323// md4clr -- replacement for memset(hash,0,16)
324inline void md4clr(void* hash)
325{
326	memset(hash, 0, 16);
327}
328
329
330// md4cpy -- replacement for memcpy(dst,src,16)
331inline void md4cpy(void* dst, const void* src)
332{
333	memcpy(dst, src, 16);
334}
335
336
337// DumpMem ... Dumps mem ;)
338wxString DumpMemToStr(const void *buff, int n, const wxString& msg = wxEmptyString, bool ok = true);
339void DumpMem(const void *buff, int n, const wxString& msg = wxEmptyString, bool ok = true);
340void DumpMem_DW(const uint32 *ptr, int count);
341
342// Returns special source ID for GUI.
343// It's actually IP<<16+Port
344#define GUI_ID(x,y) (uint64)((((uint64)x)<<16) + (uint64)y)
345// And so...
346#define PORT_FROM_GUI_ID(x) (x & 0xFFFF)
347#define IP_FROM_GUI_ID(x) (x >> 16)
348
349
350
351inline long int make_full_ed2k_version(int a, int b, int c) {
352	return ((a << 17) | (b << 10) | (c << 7));
353}
354
355
356wxString GetConfigDir(const wxString &configFile = wxT("amule.conf"));
357
358#if !wxCHECK_VERSION(2, 9, 0)
359enum {
360	wxLANGUAGE_ASTURIAN	= wxLANGUAGE_USER_DEFINED + 1
361};
362#endif
363
364/**
365 * Adds aMule's custom languages to db.
366 */
367void InitCustomLanguages();
368
369/**
370 * Initializes locale
371 */
372void InitLocale(wxLocale& locale, int language);
373
374/**
375 * Converts a string locale definition to a wxLANGUAGE id.
376 */
377int StrLang2wx(const wxString& language);
378
379/**
380 * Converts a wxLANGUAGE id to a string locale name.
381 */
382wxString wxLang2Str(const int lang);
383
384/**
385 * Generate MD5Hash of prompt input
386 */
387wxString GetPassword();
388
389
390#if wxUSE_THREADS
391
392#include <wx/thread.h>
393
394/**
395 * Automatically unlocks a mutex on construction and locks it on destruction.
396 *
397 * This class is the complement of wxMutexLocker.  It is intended to be used
398 * when a mutex, which is locked for a period of time, needs to be
399 * temporarily unlocked for a bit.  For example:
400 *
401 *	wxMutexLocker lock(mutex);
402 *
403 *	// ... do stuff that requires that the mutex is locked ...
404 *
405 *	{
406 *		CMutexUnlocker unlocker(mutex);
407 *		// ... do stuff that requires that the mutex is unlocked ...
408 *	}
409 *
410 *	// ... do more stuff that requires that the mutex is locked ...
411 *
412 */
413class CMutexUnlocker
414{
415public:
416    // unlock the mutex in the ctor
417    CMutexUnlocker(wxMutex& mutex)
418        : m_isOk(false), m_mutex(mutex)
419        { m_isOk = ( m_mutex.Unlock() == wxMUTEX_NO_ERROR ); }
420
421    // returns true if mutex was successfully unlocked in ctor
422    bool IsOk() const
423        { return m_isOk; }
424
425    // lock the mutex in dtor
426    ~CMutexUnlocker()
427        { if ( IsOk() ) m_mutex.Lock(); }
428
429private:
430    // no assignment operator nor copy ctor
431    CMutexUnlocker(const CMutexUnlocker&);
432    CMutexUnlocker& operator=(const CMutexUnlocker&);
433
434    bool     m_isOk;
435    wxMutex& m_mutex;
436};
437#endif /* wxUSE_THREADS */
438
439
440#endif // OTHERFUNCTIONS_H
441// File_checked_for_headers
442