12#if (!defined(Q_OS_WIN) && (defined(__cpp_lib_format) || __has_include(<format>))) || (defined(_MSC_VER) && _MSC_VER >= 1930)
13#define TF_HAVE_STD_FORMAT
16#define T_DEFINE_CONTROLLER(TYPE) T_DEFINE_TYPE(TYPE)
17#define T_DEFINE_VIEW(TYPE) T_DEFINE_TYPE(TYPE)
18#define T_DEFINE_TYPE(TYPE) \
19 class Static##TYPE##Definition { \
21 Static##TYPE##Definition() noexcept \
23 Tf::objectFactories()->insert(QByteArray(#TYPE).toLower(), []() { return new TYPE(); }); \
26 static Static##TYPE##Definition _static##TYPE##Definition;
29#define T_REGISTER_STREAM_OPERATORS(TYPE)
31#define T_DEFINE_PROPERTY(TYPE, PROPERTY) \
32 inline void set##PROPERTY(const TYPE &v__) noexcept { PROPERTY = v__; } \
33 inline TYPE get##PROPERTY() const noexcept { return PROPERTY; }
36#if defined(Q_CC_GNU) && !defined(__INSURE__)
37#if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
38#define T_ATTRIBUTE_FORMAT(A, B) __attribute__((format(gnu_printf, (A), (B))))
40#define T_ATTRIBUTE_FORMAT(A, B) __attribute__((format(printf, (A), (B))))
43#define T_ATTRIBUTE_FORMAT(A, B)
47#define T_EXPORT(VAR) \
49 QVariant ___##VAR##_; \
50 ___##VAR##_.setValue(VAR); \
51 Tf::currentController()->exportVariant(QLatin1String(#VAR), (___##VAR##_), true); \
53#define texport(VAR) T_EXPORT(VAR)
55#define T_EXPORT_UNLESS(VAR) \
57 QVariant ___##VAR##_; \
58 ___##VAR##_.setValue(VAR); \
59 Tf::currentController()->exportVariant(QLatin1String(#VAR), (___##VAR##_), false); \
61#define texportUnless(VAR) T_EXPORT_UNLESS(VAR)
63#define T_FETCH(TYPE, VAR) TYPE VAR = variant(QLatin1String(#VAR)).value<TYPE>()
64#define tfetch(TYPE, VAR) T_FETCH(TYPE, VAR)
66#define T_FETCH_V(TYPE, VAR, DEFAULT) TYPE VAR = (hasVariant(QLatin1String(#VAR))) ? (variant(QLatin1String(#VAR)).value<TYPE>()) : (DEFAULT)
67#define tfetchv(TYPE, VAR, DEFAULT) T_FETCH_V(TYPE, VAR, DEFAULT)
71 auto ___##VAR##_ = variant(QLatin1String(#VAR)); \
72 int ___##VAR##_type = (___##VAR##_).typeId(); \
73 switch (___##VAR##_type) { \
74 case QMetaType::QJsonValue: \
75 eh((___##VAR##_).toJsonValue()); \
77 case QMetaType::QJsonObject: \
78 eh((___##VAR##_).toJsonObject()); \
80 case QMetaType::QJsonArray: \
81 eh((___##VAR##_).toJsonArray()); \
83 case QMetaType::QJsonDocument: \
84 eh((___##VAR##_).toJsonDocument()); \
86 case QMetaType::QVariantMap: \
87 eh((___##VAR##_).toMap()); \
94#define tehex(VAR) T_EHEX(VAR)
96#define T_EHEX_V(VAR, DEFAULT) \
98 auto ___##VAR##_ = variant(QLatin1String(#VAR)); \
99 if ((___##VAR##_).isNull()) { \
106#define tehexv(VAR, DEFAULT) T_EHEX_V(VAR, DEFAULT)
109#define T_EHEX2(VAR, DEFAULT) T_EHEX_V(VAR, DEFAULT)
110#define tehex2(VAR, DEFAULT) T_EHEX2(VAR, DEFAULT)
112#define T_ECHOEX(VAR) \
114 auto ___##VAR##_ = variant(QLatin1String(#VAR)); \
115 int ___##VAR##_type = (___##VAR##_).typeId(); \
116 switch (___##VAR##_type) { \
117 case QMetaType::QJsonValue: \
118 echo((___##VAR##_).toJsonValue()); \
120 case QMetaType::QJsonObject: \
121 echo((___##VAR##_).toJsonObject()); \
123 case QMetaType::QJsonArray: \
124 echo((___##VAR##_).toJsonArray()); \
126 case QMetaType::QJsonDocument: \
127 echo((___##VAR##_).toJsonDocument()); \
129 case QMetaType::QVariantMap: \
130 echo((___##VAR##_).toMap()); \
138#define techoex(VAR) T_ECHOEX(VAR)
140#define T_ECHOEX_V(VAR, DEFAULT) \
142 auto ___##VAR##_ = variant(QLatin1String(#VAR)); \
143 if ((___##VAR##_).isNull()) { \
150#define techoexv(VAR, DEFAULT) T_ECHOEX_V(VAR, DEFAULT)
153#define T_ECHOEX2(VAR, DEFAULT) T_ECHOEX_V(VAR, DEFAULT)
154#define techoex2(VAR, DEFAULT) T_ECHOEX2(VAR, DEFAULT)
156#define T_FLASH(VAR) \
158 QVariant ___##VAR##_; \
159 ___##VAR##_.setValue(VAR); \
160 Tf::currentController()->setFlash(QLatin1String(#VAR), (___##VAR##_)); \
163#define tflash(VAR) T_FLASH(VAR)
165#define T_VARIANT(VAR) (variant(QLatin1String(#VAR)).toString())
168#define tFatal TDebug(Tf::FatalLevel).fatal
169#define tError TDebug(Tf::ErrorLevel).error
170#define tWarn TDebug(Tf::WarnLevel).warn
171#define tInfo TDebug(Tf::InfoLevel).info
172#define tDebug TDebug(Tf::DebugLevel).debug
173#define tTrace TDebug(Tf::TraceLevel).trace
184#ifdef TF_HAVE_STD_FORMAT
191class TAbstractActionContext;
223inline
bool strcmp(const QByteArray &str1, const QByteArray &str2)
225 return str1.length() == str2.length() && !std::strncmp(str1.data(), str2.data(), str1.length());
228#ifdef TF_HAVE_STD_FORMAT
236template<
typename... Args>
237void fatal(
const std::format_string<Args...> &fmt, Args&&... args)
239 std::string msg = std::format(fmt, std::forward<Args>(args)...);
247template<
typename... Args>
248void error(
const std::format_string<Args...> &fmt, Args&&... args)
250 std::string msg = std::format(fmt, std::forward<Args>(args)...);
258template<
typename... Args>
259void warn(
const std::format_string<Args...> &fmt, Args&&... args)
261 std::string msg = std::format(fmt, std::forward<Args>(args)...);
269template<
typename... Args>
270void info(
const std::format_string<Args...> &fmt, Args&&... args)
272 std::string msg = std::format(fmt, std::forward<Args>(args)...);
280template<
typename... Args>
281void debug(
const std::format_string<Args...> &fmt, Args&&... args)
283 std::string msg = std::format(fmt, std::forward<Args>(args)...);
291template<
typename... Args>
292void trace(
const std::format_string<Args...> &fmt, Args&&... args)
294 std::string msg = std::format(fmt, std::forward<Args>(args)...);
300template<
typename... Args>
301QByteArray simple_format(
const std::string &format, Args&&... args)
304 const size_t len = format.size();
305 constexpr int cnt =
sizeof...(args);
306 QVariantList vars = { QVariant(args)... };
310 res.reserve(len * 2);
313 if (format[pos] ==
'{') {
314 if (pos + 1 < len && format[pos + 1] ==
'}') {
316 res += vars[argidx].toByteArray();
322 auto e = format.find(
'}', pos + 2);
323 if (e != std::string::npos && argidx < cnt) {
324 auto sz = e - pos - 1;
325 auto subs = format.substr(pos + 1, sz);
327 auto num = vars[argidx].toULongLong();
328 res += QString::number(num, 16).toLatin1();
329 }
else if (subs ==
":#x") {
330 auto num = vars[argidx].toULongLong();
332 res += QString::number(num, 16).toLatin1();
335 res += vars[argidx].toByteArray();
343 res += format[pos++];
349template<
typename... Args>
350void fatal(
const std::string &fmt, Args&&... args)
352 auto msg = simple_format(std::string(fmt), std::forward<Args>(args)...);
356template<
typename... Args>
357void error(
const std::string &fmt, Args&&... args)
359 auto msg = simple_format(std::string(fmt), std::forward<Args>(args)...);
363template<
typename... Args>
364void warn(
const std::string &fmt, Args&&... args)
366 auto msg = simple_format(std::string(fmt), std::forward<Args>(args)...);
370template<
typename... Args>
371void info(
const std::string &fmt, Args&&... args)
373 auto msg = simple_format(std::string(fmt), std::forward<Args>(args)...);
377template<
typename... Args>
378void debug(
const std::string &fmt, Args&&... args)
380 auto msg = simple_format(std::string(fmt), std::forward<Args>(args)...);
384template<
typename... Args>
385void trace(
const std::string &fmt, Args&&... args)
387 auto msg = simple_format(std::string(fmt), std::forward<Args>(args)...);
393constexpr auto CR =
"\x0d";
394constexpr auto LF =
"\x0a";
395constexpr auto CRLF =
"\x0d\x0a";
The TAbstractController class is the abstract base class of controllers, providing functionality comm...
Definition tabstractcontroller.h:13
The TCache class stores items so that can be served faster.
Definition tcache.h:7
The TDatabaseContext class is the base class of contexts for database access.
Definition tdatabasecontext.h:11
The TWebApplication class provides an event loop for TreeFrog applications.
Definition twebapplication.h:23
The Tf namespace contains miscellaneous identifiers used throughout the library of TreeFrog Framework...
Definition tdebug.h:10
constexpr auto CRLF
Definition tglobal.h:395
T_CORE_EXPORT QByteArray lz4Compress(const char *data, int nbytes, int compressionLevel=1) noexcept
Definition tglobal.cpp:190
void debug(const std::format_string< Args... > &fmt, Args &&... args)
Outputs the debug message to the log file, formatting args according to the format string fmt.
Definition tglobal.h:281
constexpr auto CRLFCRLF
Definition tglobal.h:396
T_CORE_EXPORT const QVariantMap & conf(const QString &configName) noexcept
Returns the map associated with config file configName in 'conf' directory.
Definition tglobal.cpp:57
void error(const std::format_string< Args... > &fmt, Args &&... args)
Outputs the error message to the log file, formatting args according to the format string fmt.
Definition tglobal.h:248
T_CORE_EXPORT uint64_t random(uint64_t min, uint64_t max) noexcept
Random number generator in the range from min to max.
Definition tglobal.cpp:98
T_CORE_EXPORT TWebApplication * app() noexcept
Returns a global pointer referring to the unique application object.
Definition tglobal.cpp:40
bool strcmp(const QByteArray &str1, const QByteArray &str2)
Definition tglobal.h:223
T_CORE_EXPORT TDatabaseContext * currentDatabaseContext()
Definition tglobal.cpp:143
void fatal(const std::format_string< Args... > &fmt, Args &&... args)
Outputs the fatal message to the log file, formatting args according to the format string fmt.
Definition tglobal.h:237
void info(const std::format_string< Args... > &fmt, Args &&... args)
Outputs the infomation message to the log file, formatting args according to the format string fmt.
Definition tglobal.h:270
constexpr auto CR
Definition tglobal.h:393
T_CORE_EXPORT QByteArray lz4Uncompress(const char *data, int nbytes) noexcept
Definition tglobal.cpp:246
T_CORE_EXPORT QMap< QByteArray, std::function< QObject *()> > * objectFactories() noexcept
Definition tglobal.cpp:183
T_CORE_EXPORT uint32_t rand32_r() noexcept
Definition tglobal.cpp:78
@ TraceLevel
Finer-grained informational events than the DEBUG.
Definition tfnamespace.h:236
@ WarnLevel
Potentially harmful situations.
Definition tfnamespace.h:233
@ DebugLevel
Informational events that are most useful to debug the app.
Definition tfnamespace.h:235
@ InfoLevel
Informational messages that highlight the progress of the app.
Definition tfnamespace.h:234
@ FatalLevel
Severe error events that will presumably lead the app to abort.
Definition tfnamespace.h:231
@ ErrorLevel
Error events that might still allow the app to continue running.
Definition tfnamespace.h:232
T_CORE_EXPORT int64_t getMSecsSinceEpoch()
Definition tglobal.cpp:295
void trace(const std::format_string< Args... > &fmt, Args &&... args)
Outputs the trace message to the log file, formatting args according to the format string fmt.
Definition tglobal.h:292
T_CORE_EXPORT void msleep(int64_t msecs) noexcept
Causes the current thread to sleep for msecs milliseconds.
Definition tglobal.cpp:65
constexpr auto LF
Definition tglobal.h:394
T_CORE_EXPORT QSqlDatabase & currentSqlDatabase(int id) noexcept
Definition tglobal.cpp:177
T_CORE_EXPORT TAbstractController * currentController()
Definition tglobal.cpp:122
T_CORE_EXPORT TAppSettings * appSettings() noexcept
Returns a global pointer referring to the unique application settings object.
Definition tglobal.cpp:48
void warn(const std::format_string< Args... > &fmt, Args &&... args)
Outputs the warning message to the log file, formatting args according to the format string fmt.
Definition tglobal.h:259
T_CORE_EXPORT uint64_t rand64_r() noexcept
Definition tglobal.cpp:87
T_CORE_EXPORT TCache * cache() noexcept
Definition tglobal.cpp:116
T_CORE_EXPORT void logging(int priority, const QByteArray &msg)
Definition tdebug.cpp:99
const TAbstractController * constCurrentController()
Definition tglobal.h:212
#define T_CORE_EXPORT
Definition tdeclexport.h:28
constexpr auto TF_SRC_REVISION
Definition tglobal.h:4
constexpr auto TF_VERSION_NUMBER
Definition tglobal.h:3
constexpr auto TF_VERSION_STR
Definition tglobal.h:2