OSDN Git Service

cd20c1198dcc4c5b71d48665c333a757a54348c6
[mutilities/MUtilities.git] / include / MUtils / Global.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2016 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
21
22 /**
23 * @file
24 * @brief This file contains miscellaneous functions that are generally useful for Qt-based applications
25 */
26
27 #pragma once
28
29 #include <QString>
30
31 //Forward Declarations
32 class QProcess;
33
34 ///////////////////////////////////////////////////////////////////////////////
35
36 //MUtils API
37 #ifdef _MSC_VER
38 #       ifdef MUTILS_DLL_EXPORT
39 #               define MUTILS_API __declspec(dllexport)
40 #       else
41 #               ifndef MUTILS_STATIC_LIB
42 #                       define MUTILS_API __declspec(dllimport)
43 #               else
44 #                       define MUTILS_API /*static lib*/
45 #               endif
46 #       endif
47 #else
48 #       define MUTILS_API
49 #endif
50
51 //Helper Macros
52 #define MUTILS_MAKE_STRING_HELPER(X) #X
53 #define MUTILS_MAKE_STRING(X) MUTILS_MAKE_STRING_HELPER(X)
54 #define MUTILS_COMPILER_WARNING(TXT) __pragma(message(__FILE__ "(" MUTILS_MAKE_STRING(__LINE__) ") : warning: " TXT))
55
56 //Check Debug Flags
57 #if defined(_DEBUG) || defined(DEBUG) || (!defined(NDEBUG))
58 #       define MUTILS_DEBUG (1)
59 #       if defined(NDEBUG) || defined(QT_NO_DEBUG) || (!defined(QT_DEBUG))
60 #               error Inconsistent DEBUG flags have been detected!
61 #       endif
62 #else
63 #       define MUTILS_DEBUG (0)
64 #       if (!defined(NDEBUG)) || (!defined(QT_NO_DEBUG)) || defined(QT_DEBUG)
65 #               error Inconsistent DEBUG flags have been detected!
66 #       endif
67 #endif
68
69 //Check CPU options
70 #if defined(_MSC_VER) && (!defined(__INTELLISENSE__)) && (!defined(_M_X64)) && defined(_M_IX86_FP)
71         #if (_M_IX86_FP != 0)
72                 #error We should not enabled SSE or SSE2 in release builds!
73         #endif
74 #endif
75
76 ///////////////////////////////////////////////////////////////////////////////
77
78 /**
79 * \mainpage MuldeR's Utilities for Qt
80
81 * The **MUtilities** library is a collection of routines and classes to extend the [*Qt cross-platform framework*](http://qt-project.org/). It contains various convenience and utility functions as well as wrappers for OS-specific functionalities. The library was originally created as a "side product" of the [**LameXP**](http://lamexp.sourceforge.net/) application: Over the years, a lot of code, **not** really specific to *LameXP*, had accumulated in the *LameXP* code base. Some of that code even had been used in other projects too, in a "copy & paste" fashion &ndash; which had lead to redundancy and much complicated maintenance. In order to clean-up the LameXP code base, to eliminate the ugly redundancy and to simplify maintenance, the code in question has finally been refactored into the **MUtilities** (aka "MuldeR's Utilities for Qt") library. This library now forms the foundation of *LameXP* and [*other OpenSource projects*](https://github.com/lordmulder).
82
83
84 * ### API-Documentation
85
86 * The public API of the *MUtilities* library is defined in the following header files:
87 * - **Global.h** &ndash; miscellaneous useful functions
88
89
90 * ### License
91
92 * This library is free software. It is released under the terms of the [GNU Lesser General Public License (LGPL), Version 2.1](https://www.gnu.org/licenses/lgpl-2.1.html).
93
94 * ```
95 * MUtilities - MuldeR's Utilities for Qt
96 * Copyright (C) 2004-2016 LoRd_MuldeR <MuldeR2@GMX.de>. Some rights reserved.
97
98 * This library is free software; you can redistribute it and/or
99 * modify it under the terms of the GNU Lesser General Public
100 * License as published by the Free Software Foundation; either
101 * version 2.1 of the License, or (at your option) any later version.
102
103 * This library is distributed in the hope that it will be useful,
104 * but WITHOUT ANY WARRANTY; without even the implied warranty of
105 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
106 * Lesser General Public License for more details.
107
108 * You should have received a copy of the GNU Lesser General Public
109 * License along with this library; if not, write to the Free Software
110 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
111 * ```
112 */
113
114 namespace MUtils
115 {
116         /**
117         * \brief Rerieves the full path of the application's *Temp* folder.
118         *
119         * The application's *Temp* folder is a unique application-specific folder, intended to store any temporary files that the application may need. It will be created when this function is called for the first time (lazy initialization); subsequent calls are guaranteed to return the same path. Usually the application's *Temp* folder will be created as a sub-folder of the system's global *Temp* folder, as indicated by the `TMP` or `TEMP` environment variables. However, it may be created at a different place (e.g. in the users *Profile* directory), if those environment variables don't point to a usable directory. In any case, this function makes sure that the application's *Temp* folder exists for the whole lifetime of the application and that it is writable. When the application is about to terminate, the application's *Temp* folder and all files or sub-directories thereof will be *removed* automatically!
120         *
121         * \return If the function succeeds, it returns a read-only reference to a QString holding the full path of the application's *Temp* folder; otherwise a read-only reference to a default-constructed QString is returned.
122         */
123         MUTILS_API const QString& temp_folder(void);
124
125         //Process Utils
126         MUTILS_API void init_process(QProcess &process, const QString &wokringDir, const bool bReplaceTempDir = true, const QStringList *const extraPaths = NULL);
127
128         /**
129         * \brief Generates a *random* unsigned 32-Bit value.
130         *
131         * The *random* value is created using a "strong" PRNG of the underlying system, if possible. Otherwise a fallback PRNG is used. It is **not** required or useful to call `srand()` or `qsrand()` prior to using this function. If necessary, the seeding of the PRNG happen *automatically* on the first call.
132         *
133         * \return The function retruns a *random* unsigned 32-Bit value.
134         */
135         MUTILS_API quint32 next_rand_u32(void);
136         
137         /**
138         * \brief Generates a *random* unsigned 64-Bit value.
139         *
140         * The *random* value is created using a "strong" PRNG of the underlying system, if possible. Otherwise a fallback PRNG is used. It is **not** required or useful to call `srand()` or `qsrand()` prior to using this function. If necessary, the seeding of the PRNG happen *automatically* on the first call.
141         *
142         * \return The function retruns a *random* unsigned 64-Bit value.
143         */
144         MUTILS_API quint64 next_rand_u64(void);
145         
146         /**
147         * \brief Generates a *random* string.
148         *
149         * The random string is generated using the same PRNG as the `next_rand_u64()` function. The *random* bytes are converted to a hexadecimal string and, if necessary, zero-padded to a toal length of 16 or 32 characters. There is **no** `0x`-prefix included in the result.
150         *
151         * \param bLong If set to `true`, a "long" random string (32 characters) will be generated; if set to `false`, a "short" random string (16 characters) is generated.
152         *
153         * \return The function retruns a QString holding a *random* hexadecimal string
154         */
155         MUTILS_API QString next_rand_str(const bool &bLong = false);
156
157         /**
158         * \brief Generates a temporary file name.
159         *
160         * The function generates a file name that contains a *random* component and that is guaranteed to **not** exist yet. The generated file name follows a `"<basedir>/<random>.<ext>"` pattern. This is useful (not only) for creating temporary files.
161         *
162         * \param basePath Specifies the "base" directory where the temporary file is supposed to be created. This must be a valid *existing* directory.
163         *
164         * \param extension Specifies the desired file extensions of the temporary file. Do **not** include a leading dot (`.`) character.
165         *
166         * \param placeholder If set to `true`, the function creates an empty "placeholder" file under the returned file name; if set to `false`, it does *not*.
167         *
168         * \return If the function succeeds, it returns a QString holding the full path of the temporary file; otherwise it returns a default-constructed QString.
169         */
170         MUTILS_API QString make_temp_file(const QString &basePath, const QString &extension, const bool placeholder = false);
171
172         /**
173         * \brief Generates a unique file name.
174         *
175         * The function generates a unique file name in the specified directory. The function guarantees that the returned file name does *not* exist yet. If necessary, a *counter* will be included in the file name in order to ensure its uniqueness.
176         *
177         * \param basePath Specifies the "base" directory where the unique file is supposed to be created. This must be a valid *existing* directory.
178         *
179         * \param baseName Specifies the desired "base" file name of the unqiue file. Do **not** include a file extension.
180         *
181         * \param extension Specifies the desired file extensions of the unqiue file. Do **not** include a leading dot (`.`) character.
182         *
183         * \param fancy If set to `true`, the file name is generated according to the `"<basedir>/<basename> (N).<ext>"` pattern; if set to `false`, the file name is generated according to the `"<basedir>/<basename>.XXXX.<ext>"` pattern.
184         *
185         * \return If the function succeeds, it returns a QString holding the full path of the unique file; otherwise it returns a default-constructed QString.
186         */
187         MUTILS_API QString make_unique_file(const QString &basePath, const QString &baseName, const QString &extension, const bool fancy = false);
188
189         /**
190         * \brief Computes the *parity* of the given unsigned 32-Bit value
191         *
192         * \param value The 32-Bit unsigned value from which the parity is to be computed.
193         *
194         * \return The function returns `true`, if the number of **1** bits in the given value is *odd*; it returns `false`, if the number of **1** bits in the given value is *even*.
195         */
196         MUTILS_API bool parity(quint32 value);
197
198         /**
199         * \brief Deletes the specified file
200         *
201         * The function deletes the specified file, even if it has the "read only" flag set. If the file is currently locked (e.g. by another process), the function retries multiple times to delete the file before it fails.
202         *
203         * \param fileName The path to the file to be deleted. This should be a full path.
204         *
205         * \return The function returns `true`, if the file was deleted successfully or if the file doesn't exist; it returns `false`, if the file could *not* be deleted.
206         */
207         MUTILS_API bool remove_file(const QString &fileName);
208
209         /**
210         * \brief Recursively deletes the specified directory
211         *
212         * The function deletes the specified directory. In *recusive* mode, the directory will be removed including all of its files and sub-directories. Files are deleted using the `remove_file()` function.
213         *
214         * \param folderPath The path to the directory to be deleted. This should be a full path.
215         *
216         * \param recursive If set to `true` the function removes all files and sub-directories in the specified directory; if set to `false`, the function will *not* try to delete any files or sub-directories, which means that it will fail on non-empty directories.
217         *
218         * \return The function returns `true`, if the directory was deleted successfully or if the directory doesn't exist; it returns `false`, if the directory could *not* be deleted.
219         */
220         MUTILS_API bool remove_directory(const QString &folderPath, const bool &recursive);
221
222         /**
223         * \brief Remove *trailing* white-space characters
224         *
225         * The function removes all *trailing* white-space characters from the specified string. Leading white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
226         *
227         * \param str A reference to the QString object to be trimmed. This QString object will be modified directly.
228         *
229         * \return A reference to the trimmed QString object. This is the same QString object that was specified in the `str` parameter.
230         */
231         MUTILS_API QString& trim_right(QString &str);
232
233         /**
234         * \brief Remove *leading* white-space characters
235         *
236         * The function removes all *leading* white-space characters from the specified string. Trailing white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
237         *
238         * \param str A reference to the QString object to be trimmed. This QString object will be modified directly.
239         *
240         * \return A reference to the trimmed QString object. This is the same QString object that was specified in the `str` parameter.
241         */
242         MUTILS_API QString& trim_left(QString &str);
243
244         /**
245         * \brief Remove *trailing* white-space characters
246         *
247         * The function removes all *trailing* white-space characters from the specified string. Leading white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
248         *
249         * \param str A read-only reference to the QString object to be trimmed. The original QString object is *not* modified.
250         *
251         * \return A new QString object that equals the original QString object, except that it has all *trailing* white-space characters removed.
252         */
253         MUTILS_API QString trim_right(const QString &str);
254
255         /**
256         * \brief Remove *trailing* white-space characters
257         *
258         * The function removes all *leading* white-space characters from the specified string. Trailing white-space characters are *not* removed. White-space characters are defined by the `\s` character class.
259         *
260         * \param str A read-only reference to the QString object to be trimmed. The original QString object is *not* modified.
261         *
262         * \return A new QString object that equals the original QString object, except that it has all *leading* white-space characters removed.
263         */
264         MUTILS_API QString trim_left(const QString &str);
265
266         /**
267         * \brief Sort a list of strings using "natural ordering" algorithm
268         *
269         * This function implements a sort algorithm that orders alphanumeric strings in the way a human being would. See [*Natural Order String Comparison*](http://sourcefrog.net/projects/natsort/) for details!
270         *
271         * \param list A reference to the QStringList object to be sorted. The list will be sorted "in place".
272         */
273         MUTILS_API void natural_string_sort(QStringList &list, const bool bIgnoreCase);
274
275         //Clean file path
276         MUTILS_API QString clean_file_name(const QString &name);
277         MUTILS_API QString clean_file_path(const QString &path);
278
279         //Regular expressions
280         MUTILS_API bool regexp_parse_uint32(const QRegExp &regexp, quint32 &value);
281         MUTILS_API bool regexp_parse_uint32(const QRegExp &regexp, quint32 *values, const size_t &count);
282
283         //Internationalization
284         MUTILS_API QStringList available_codepages(const bool &noAliases = true);
285
286         //Internal
287         namespace Internal
288         {
289                 MUTILS_API int selfTest(const char *const buildKey, const bool debug);
290                 static const int s_selfTest = selfTest(__DATE__ "@" __TIME__, MUTILS_DEBUG);
291         }
292 }
293
294 ///////////////////////////////////////////////////////////////////////////////
295
296 //Delete helper
297 #define MUTILS_DELETE(PTR) do { if((PTR)) { delete (PTR); (PTR) = NULL; } } while(0)
298 #define MUTILS_DELETE_ARRAY(PTR) do { if((PTR)) { delete [] (PTR); (PTR) = NULL; } } while(0)
299
300 //Zero memory
301 #define MUTILS_ZERO_MEMORY(PTR) memset(&(PTR), 0, sizeof((PTR)))
302
303 //String conversion macros
304 #define MUTILS_WCHR(STR) (reinterpret_cast<const wchar_t*>((STR).utf16()))
305 #define MUTILS_UTF8(STR) ((STR).toUtf8().constData())
306 #define MUTILS_QSTR(STR) (QString::fromUtf16(reinterpret_cast<const unsigned short*>((STR))))
307
308 //Boolean helper
309 #define MUTILS_BOOL2STR(X) ((X) ? "1" : "0")