From 3cae7a197e9d1686165408cc8322eb24cf4eefcb Mon Sep 17 00:00:00 2001 From: Stephen Webb Date: Fri, 4 Aug 2023 12:48:30 +1000 Subject: [PATCH] Restore CFString code --- src/main/cpp/file.cpp | 13 +++++ src/main/cpp/level.cpp | 19 +++++++ src/main/cpp/logger.cpp | 4 +- src/main/cpp/logmanager.cpp | 21 +++++++ src/main/cpp/logstream.cpp | 9 ++- src/main/cpp/mdc.cpp | 48 ++++++++++++++++ src/main/cpp/messagebuffer.cpp | 43 ++++++--------- src/main/cpp/ndc.cpp | 55 +++++++++++++++++++ src/main/cpp/transcoder.cpp | 8 ++- src/main/include/log4cxx/file.h | 6 ++ .../include/log4cxx/helpers/messagebuffer.h | 10 ++++ src/main/include/log4cxx/helpers/transcoder.h | 21 +++++-- src/main/include/log4cxx/level.h | 24 ++++++++ src/main/include/log4cxx/logmanager.h | 26 +++++++++ src/main/include/log4cxx/logstring.h | 8 +++ src/main/include/log4cxx/mdc.h | 34 ++++++++++++ src/main/include/log4cxx/ndc.h | 25 +++++++++ src/main/include/log4cxx/stream.h | 5 ++ 18 files changed, 341 insertions(+), 38 deletions(-) diff --git a/src/main/cpp/file.cpp b/src/main/cpp/file.cpp index 5d0d13a4f..325abb724 100644 --- a/src/main/cpp/file.cpp +++ b/src/main/cpp/file.cpp @@ -120,6 +120,19 @@ File::File(const QString& name) } #endif +#if LOG4CXX_CFSTRING_API +static LogString decodeLS(const CFStringRef& src) +{ + LogString dst; + Transcoder::decode(src, dst); + return dst; +} +File::File(const CFStringRef& name) + : m_priv(std::make_unique(decodeLS(name))) +{ +} +#endif + File::File(const File& src) : m_priv(std::make_unique(src.m_priv->path, src.m_priv->autoDelete)) { diff --git a/src/main/cpp/level.cpp b/src/main/cpp/level.cpp index 1317bbd86..b80f99ebc 100644 --- a/src/main/cpp/level.cpp +++ b/src/main/cpp/level.cpp @@ -192,6 +192,25 @@ void Level::toString(std::basic_string& dst) const #endif +#if LOG4CXX_CFSTRING_API +LevelPtr Level::toLevel(const CFStringRef& sArg) +{ + return toLevel(sArg, Level::getDebug()); +} + +LevelPtr Level::toLevel(const CFStringRef& sArg, const LevelPtr& defaultLevel) +{ + LogString s; + Transcoder::decode(sArg, s); + return toLevelLS(s, defaultLevel); +} + +void Level::toString(CFStringRef& dst) const +{ + dst = Transcoder::encode(name); +} +#endif + LevelPtr Level::toLevelLS(const LogString& sArg, const LevelPtr& defaultLevel) { const LogString trimmed(StringHelper::trim(sArg)); diff --git a/src/main/cpp/logger.cpp b/src/main/cpp/logger.cpp index 9f6a81a2f..7d8ab1f44 100644 --- a/src/main/cpp/logger.cpp +++ b/src/main/cpp/logger.cpp @@ -1058,9 +1058,7 @@ void Logger::addEvent(const LevelPtr& level, QString&& message, const LocationIn void Logger::getName(QString& rv) const { - LOG4CXX_DECODE_QSTRING(msg, message); - auto event = std::make_shared(m_priv->name, level, location, std::move(msg)); - callAppenders(event, p); + rv = Transcoder::encode(m_priv->name); } void Logger::qtrace(const QString& msg, const spi::LocationInfo& location) const diff --git a/src/main/cpp/logmanager.cpp b/src/main/cpp/logmanager.cpp index e6bef3af9..1d4d957ed 100644 --- a/src/main/cpp/logmanager.cpp +++ b/src/main/cpp/logmanager.cpp @@ -169,6 +169,27 @@ LoggerPtr LogManager::exists(const std::basic_string& name) } #endif +#if LOG4CXX_CFSTRING_API +LoggerPtr LogManager::getLogger(const CFStringRef& name) +{ + LOG4CXX_DECODE_CFSTRING(n, name); + return getLoggerLS(n); +} + +LoggerPtr LogManager::getLogger(const CFStringRef& name, + const spi::LoggerFactoryPtr& factory) +{ + LOG4CXX_DECODE_CFSTRING(n, name); + return getLoggerLS(n, factory); +} + +LoggerPtr LogManager::exists(const CFStringRef& name) +{ + LOG4CXX_DECODE_CFSTRING(n, name); + return existsLS(n); +} +#endif + LoggerPtr LogManager::existsLS(const LogString& name) { return getLoggerRepository()->exists(name); diff --git a/src/main/cpp/logstream.cpp b/src/main/cpp/logstream.cpp index e6a8b6094..1df055fe0 100644 --- a/src/main/cpp/logstream.cpp +++ b/src/main/cpp/logstream.cpp @@ -480,9 +480,14 @@ ulogstream::ulogstream(const std::basic_string& loggerName, const log4cxx::LevelPtr& level) : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) { } -#endif -#if LOG4CXX_UNICHAR_API +#if LOG4CXX_CFSTRING_API +ulogstream::ulogstream(const CFStringRef& loggerName, + const log4cxx::LevelPtr& level) + : logstream_base(log4cxx::Logger::getLogger(loggerName), level), stream(0) +{ +} +#endif ulogstream::ulogstream(const log4cxx::LoggerPtr& logger, const log4cxx::LevelPtr& level) : logstream_base(logger, level), stream(0) diff --git a/src/main/cpp/mdc.cpp b/src/main/cpp/mdc.cpp index b7083cd44..cfd4d9e14 100644 --- a/src/main/cpp/mdc.cpp +++ b/src/main/cpp/mdc.cpp @@ -19,6 +19,10 @@ #include #include +#if LOG4CXX_CFSTRING_API + #include +#endif + using namespace log4cxx; using namespace log4cxx::helpers; @@ -222,3 +226,47 @@ std::basic_string MDC::remove(const std::basic_string #include +#if LOG4CXX_UNICHAR_API UniCharMessageBuffer& UniCharMessageBuffer::operator<<(const CFStringRef& msg) { - if (m_priv->stream == 0) - { - m_priv->buf.append(msg.toUtf8().constData()); - } - else - { - *m_priv->stream << msg.toUtf8().constData(); - } - - return *this; -} - -UniCharMessageBuffer& UniCharMessageBuffer::operator<<(const QString& msg) -{ - const UniChar* chars = msg.utf16(); - - if (chars != 0) + size_t length = CFStringGetLength(msg); + if (0 < length) { - return operator<<(chars); + std::vector tmp(length); + CFStringGetCharacters(msg, CFRangeMake(0, length), &tmp[0]); + if (m_priv->stream) + { + *m_priv->stream << std::basic_string(&tmp[0], tmp.size()); + } + else + { + m_priv->buf.append(&tmp[0], tmp.size()); + } } - return *this; } -elif LOG4CXX_CFSTRING_API -#include -#include - +#else CharMessageBuffer& CharMessageBuffer::operator<<(const CFStringRef& msg) { LOG4CXX_DECODE_CFSTRING(tmp, msg); @@ -819,7 +810,5 @@ CharMessageBuffer& MessageBuffer::operator<<(const CFStringRef& msg) return m_priv->cbuf << tmp; } #endif // LOG4CXX_WCHAR_T_API - +#endif // LOG4CXX_UNICHAR_API #endif // LOG4CXX_CFSTRING_API - - diff --git a/src/main/cpp/ndc.cpp b/src/main/cpp/ndc.cpp index cf048344e..077713519 100644 --- a/src/main/cpp/ndc.cpp +++ b/src/main/cpp/ndc.cpp @@ -356,4 +356,59 @@ bool NDC::peek(std::basic_string& dst) #endif +#if LOG4CXX_CFSTRING_API +NDC::NDC(const CFStringRef& message) +{ + push(message); +} + +void NDC::push(const CFStringRef& message) +{ + LOG4CXX_DECODE_CFSTRING(msg, message); + pushLS(msg); +} + +bool NDC::pop(CFStringRef& dst) +{ + ThreadSpecificData* data = ThreadSpecificData::getCurrentData(); + + if (data != 0) + { + Stack& stack = data->getStack(); + + if (!stack.empty()) + { + dst = Transcoder::encode(getMessage(stack.top())); + stack.pop(); + data->recycle(); + return true; + } + + data->recycle(); + } + + return false; +} + +bool NDC::peek(CFStringRef& dst) +{ + ThreadSpecificData* data = ThreadSpecificData::getCurrentData(); + + if (data != 0) + { + Stack& stack = data->getStack(); + + if (!stack.empty()) + { + dst = Transcoder::encode(getMessage(stack.top())); + return true; + } + + data->recycle(); + } + + return false; +} + +#endif diff --git a/src/main/cpp/transcoder.cpp b/src/main/cpp/transcoder.cpp index 485064e2a..e66d5533f 100644 --- a/src/main/cpp/transcoder.cpp +++ b/src/main/cpp/transcoder.cpp @@ -32,6 +32,10 @@ #endif #include +#if LOG4CXX_CFSTRING_API + #include +#endif + using namespace log4cxx; using namespace log4cxx::helpers; @@ -650,7 +654,7 @@ QString Transcoder::encode(const LogString& src) #if LOG4CXX_CFSTRING_API void Transcoder::decode(const CFStringRef& src, LogString& dst) { - auto length = CFStringGetLength(src); + auto length = CFStringGetLength(src); #if defined(_DEBUG) Pool pool; LogString msg(LOG4CXX_STR("Transcoder::decodeCFString")); @@ -673,7 +677,7 @@ void Transcoder::decode(const CFStringRef& src, LogString& dst) CFStringRef Transcoder::encode(const LogString& src) { - std::basic_string tmp; + std::basic_string tmp; for (auto ch : src) encodeUTF16(ch, tmp); return CFStringCreateWithCharacters(kCFAllocatorDefault, tmp.data(), tmp.size()); diff --git a/src/main/include/log4cxx/file.h b/src/main/include/log4cxx/file.h index 3607bf5aa..31a5f8806 100644 --- a/src/main/include/log4cxx/file.h +++ b/src/main/include/log4cxx/file.h @@ -85,7 +85,13 @@ class LOG4CXX_EXPORT File */ File(const QString& path); #endif +#if LOG4CXX_CFSTRING_API /** + * Construct a new instance. Use setPath to specify path using a LogString. + * @param path file path. + */ + File(const CFStringRef& path); +#endif /** * Copy constructor. */ File(const File& src); diff --git a/src/main/include/log4cxx/helpers/messagebuffer.h b/src/main/include/log4cxx/helpers/messagebuffer.h index fedecffbd..435626f83 100644 --- a/src/main/include/log4cxx/helpers/messagebuffer.h +++ b/src/main/include/log4cxx/helpers/messagebuffer.h @@ -277,6 +277,16 @@ class LOG4CXX_EXPORT UniCharMessageBuffer UniCharMessageBuffer& operator<<(const QString& msg); #endif +#if LOG4CXX_CFSTRING_API + /** + * Appends a string into the buffer and + * fixes the buffer to use char characters. + * @param msg message to append. + * @return encapsulated CharMessageBuffer. + */ + UniCharMessageBuffer& operator<<(const CFStringRef& msg); +#endif + /** * Insertion operator for STL manipulators such as std::fixed. * @param manip manipulator. diff --git a/src/main/include/log4cxx/helpers/transcoder.h b/src/main/include/log4cxx/helpers/transcoder.h index 3f35cc1bc..04746b5d2 100644 --- a/src/main/include/log4cxx/helpers/transcoder.h +++ b/src/main/include/log4cxx/helpers/transcoder.h @@ -133,10 +133,6 @@ class LOG4CXX_EXPORT Transcoder #endif -#if LOG4CXX_QSTRING_API - static void decode(const QString& src, LogString& dst); - static QString encode(const LogString& src); -#endif #if LOG4CXX_UNICHAR_API || LOG4CXX_LOGCHAR_IS_UNICHAR static void decode(const std::basic_string& src, LogString& dst); @@ -161,6 +157,16 @@ class LOG4CXX_EXPORT Transcoder #endif +#if LOG4CXX_QSTRING_API + static void decode(const QString& src, LogString& dst); + static QString encode(const LogString& src); +#endif + +#if LOG4CXX_CFSTRING_API + static void decode(const CFStringRef& src, LogString& dst); + static CFStringRef encode(const LogString& src); +#endif + enum { LOSSCHAR = 0x3F }; @@ -221,6 +227,13 @@ class LOG4CXX_EXPORT Transcoder #define LOG4CXX_ENCODE_QSTRING(var, src) \ QString var = log4cxx::helpers::Transcoder::encode(src) +#define LOG4CXX_DECODE_CFSTRING(var, src) \ + log4cxx::LogString var; \ + log4cxx::helpers::Transcoder::decode(src, var) + +#define LOG4CXX_ENCODE_CFSTRING(var, src) \ + CFStringRef var = log4cxx::helpers::Transcoder::encode(src) + #if LOG4CXX_LOGCHAR_IS_WCHAR diff --git a/src/main/include/log4cxx/level.h b/src/main/include/log4cxx/level.h index 94dcaceab..737587d14 100644 --- a/src/main/include/log4cxx/level.h +++ b/src/main/include/log4cxx/level.h @@ -149,6 +149,30 @@ class LOG4CXX_EXPORT Level : public helpers::Object */ void toString(std::basic_string& name) const; #endif + +#if LOG4CXX_CFSTRING_API + /** + Convert the string passed as argument to a level. If the + conversion fails, then this method returns DEBUG. + * @param sArg level name. + */ + static LevelPtr toLevel(const CFStringRef& sArg); + /** + Convert the string passed as argument to a level. If the + conversion fails, then this method returns the value of + defaultLevel. + * @param sArg level name. + * @param defaultLevel level to return if no match. + * @return + */ + static LevelPtr toLevel(const CFStringRef& sArg, + const LevelPtr& defaultLevel); + /** + * Get the name of the level. + * @param name buffer to which name is appended. + */ + void toString(CFStringRef& name) const; +#endif /** Convert the string passed as argument to a level. If the conversion fails, then this method returns DEBUG. diff --git a/src/main/include/log4cxx/logmanager.h b/src/main/include/log4cxx/logmanager.h index d9ef4046c..444208c91 100644 --- a/src/main/include/log4cxx/logmanager.h +++ b/src/main/include/log4cxx/logmanager.h @@ -154,6 +154,32 @@ class LOG4CXX_EXPORT LogManager static LoggerPtr exists(const std::basic_string& name); #endif +#if LOG4CXX_CFSTRING_API + /** + Retrieve the \c name Logger instance from the + {@link spi::LoggerRepository LoggerRepository} + using DefaultLoggerFactory to create it if required. + Calls {@link spi::LoggerRepository::ensureIsConfigured ensureIsConfigured} + passing {@link DefaultConfigurator::configure} to ensure + the repository is configured. + */ + static LoggerPtr getLogger(const CFStringRef& name); + /** + Retrieve the \c name Logger instance from the + {@link spi::LoggerRepository LoggerRepository} + using \c factory to create it if required. + Calls {@link spi::LoggerRepository::ensureIsConfigured ensureIsConfigured} + passing {@link DefaultConfigurator::configure} to ensure + the repository is configured. + */ + static LoggerPtr getLogger(const CFStringRef& name, + const spi::LoggerFactoryPtr& factory); + /** + Does the logger \c name exist in the hierarchy? + */ + static LoggerPtr exists(const CFStringRef& name); +#endif + /** Retrieve the \c name Logger instance from the {@link spi::LoggerRepository LoggerRepository} diff --git a/src/main/include/log4cxx/logstring.h b/src/main/include/log4cxx/logstring.h index 3dfd2d688..6bd9c89bd 100644 --- a/src/main/include/log4cxx/logstring.h +++ b/src/main/include/log4cxx/logstring.h @@ -24,9 +24,17 @@ #if (LOG4CXX_LOGCHAR_IS_WCHAR + LOG4CXX_LOGCHAR_IS_UTF8 + LOG4CXX_LOGCHAR_IS_UNICHAR)>1 #error only one of LOG4CXX_LOGCHAR_IS_WCHAR, LOG4CXX_LOGCHAR_IS_UTF8 or LOG4CXX_LOGCHAR_IS_UNICHAR may be true #endif + #if LOG4CXX_QSTRING_API #include #endif + +#if LOG4CXX_CFSTRING_API +extern "C" { + typedef const struct __CFString* CFStringRef; +} +#endif + namespace log4cxx { diff --git a/src/main/include/log4cxx/mdc.h b/src/main/include/log4cxx/mdc.h index 58eb05986..a73c609a2 100644 --- a/src/main/include/log4cxx/mdc.h +++ b/src/main/include/log4cxx/mdc.h @@ -166,6 +166,40 @@ class LOG4CXX_EXPORT MDC * @return value if key had been set, empty if not. */ static std::basic_string remove(const std::basic_string& key); +#endif +#if LOG4CXX_CFSTRING_API + /** + * Places a key/value pair in the MDC for the current thread + * which will be removed during the corresponding destructor. Both + * construction and destruction are expected to be on the same thread. + * @param key context identifier + * @param value a string that distinguishes this context. + */ + MDC(const CFStringRef& key, const CFStringRef& value); + /** + * Set the key context in the current thread's context map to value. + * + *

If the current thread does not have a context map it is + * created as a side effect. + * @param key context identifier + * @param value a string that distinguishes this context. + */ + static void put(const CFStringRef& key, const CFStringRef& value); + /** + * Get the context identified by the key parameter. + * + *

This method has no side effects. + * @param key context identifier. + * @return value for key, empty if not set. + * */ + static CFStringRef get(const CFStringRef& key); + /** + * Remove the the context identified by the key + * parameter. + * @param key context identifier. + * @return value if key had been set, empty if not. + */ + static CFStringRef remove(const CFStringRef& key); #endif /** * Remove the the context identified by the key diff --git a/src/main/include/log4cxx/ndc.h b/src/main/include/log4cxx/ndc.h index ed95efdb9..5341730c5 100644 --- a/src/main/include/log4cxx/ndc.h +++ b/src/main/include/log4cxx/ndc.h @@ -259,6 +259,31 @@ class LOG4CXX_EXPORT NDC */ static bool pop(std::basic_string& dst); #endif +#if LOG4CXX_CFSTRING_API + /** + Add \c message onto the context stack. + @see The #push method. + @param message The text added to the diagnostic context information. + */ + NDC(const CFStringRef& message); + /** + Add \c message to the stack associated with the current thread. + @param message The text added to the diagnostic context information. + */ + static void push(const CFStringRef& message); + /** + Append to \c dst the top value in the stack associated with the current thread without removing it. + @param dst to which top value is appended. + @return true if NDC contained at least one value. + */ + static bool peek(CFStringRef& dst); + /** + Append to \c dst the top value in the stack associated with the current thread and then remove it. + @param dst to which top value is appended. + @return true if NDC contained at least one value. + */ + static bool pop(CFStringRef& dst); +#endif private: NDC(const NDC&); diff --git a/src/main/include/log4cxx/stream.h b/src/main/include/log4cxx/stream.h index bc346653b..2655e763b 100644 --- a/src/main/include/log4cxx/stream.h +++ b/src/main/include/log4cxx/stream.h @@ -459,6 +459,11 @@ class LOG4CXX_EXPORT ulogstream : public logstream_base const log4cxx::LevelPtr& level); #endif +#if LOG4CXX_CFSTRING_API + ulogstream(const CFStringRef& loggerName, + const log4cxx::LevelPtr& level); +#endif + ~ulogstream(); /**