Skip to content

Commit

Permalink
Allow CFString code testing on non-Apple systems (#244)
Browse files Browse the repository at this point in the history
* Add CFString tests to transcodertests
  • Loading branch information
swebb2066 authored Aug 2, 2023
1 parent f0473b5 commit 455fb8e
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ target_include_directories(log4cxx PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

if(LOG4CXX_CFSTRING)
if(APPLE)
target_link_libraries(log4cxx PUBLIC "-framework CoreFoundation")
else()
add_subdirectory(mock-apple)
endif()
endif()

if(LOG4CXX_QT_SUPPORT)
target_include_directories(log4cxx-qt PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
Expand Down
4 changes: 0 additions & 4 deletions src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,6 @@ if(${ENABLE_FMT_LAYOUT})
target_link_libraries(log4cxx PUBLIC fmt::fmt)
endif()

if (LOG4CXX_CFSTRING)
target_link_libraries(log4cxx PRIVATE "-framework CoreFoundation")
endif()

if(LOG4CXX_ABI_CHECK)
message("Getting dependencies for ABI compatability check...")
# Get the latest version of abi-dumper and abi-compliance-checker
Expand Down
2 changes: 1 addition & 1 deletion src/main/cpp/messagebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ CharMessageBuffer& CharMessageBuffer::operator<<(const CFStringRef& msg)
}
else
{
m_priv->buf.append(&tmp[0], tmp.size());
m_priv->buf.append(tmp);
}
return *this;
}
Expand Down
70 changes: 70 additions & 0 deletions src/main/mock-apple/CFString.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* Mocked CFString implementation
*/
#include "CoreFoundation/CFString.h"
#include <apr_pools.h>
#include <exception>

namespace {
int throw_out_of_mem(int status)
{
throw std::bad_alloc();
return status;
}
apr_pool_t* getStringPool()
{
static struct cfstring_pool
{
apr_pool_t* ptr = 0;
cfstring_pool()
{
apr_pool_create_core_ex(&ptr, throw_out_of_mem, NULL);
}
~cfstring_pool()
{
apr_pool_destroy(ptr);
}
} pool;
return pool.ptr;
}
} // namespace

extern "C" {

CFRange CFRangeMake(CFIndex loc, CFIndex len) {
CFRange result;
result.location = loc;
result.length = len;
return result;
}

CFIndex CFStringGetLength(CFStringRef theString) {
UniChar* data = (UniChar*)theString;
CFIndex result = 0;
while (data[result])
++result;
return result;
}
void CFStringGetCharacters(CFStringRef theString, CFRange range, UniChar *buffer) {
UniChar* data = (UniChar*)theString;
CFIndex index = 0;
while (index < range.length) {
*buffer = data[range.location + index];
++index;
++buffer;
}
}
CFStringRef CFStringCreateWithCharacters(CFAllocatorRef alloc, const UniChar *chars, CFIndex numChars) {
UniChar* result = (UniChar*)apr_palloc(getStringPool(), (numChars + 1) * sizeof(UniChar));
result[numChars] = 0;
for (UniChar* p = result; 0 < numChars; --numChars)
*p++ = *chars++;
return (CFStringRef)result;
}
CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding) {
UniChar* result = (UniChar*)apr_palloc(getStringPool(), (strlen(cStr) + 1) * sizeof(UniChar));
for (UniChar *p = result; *p++ = *cStr++;)
;
return (CFStringRef)result;
}

} // extern "C"
25 changes: 25 additions & 0 deletions src/main/mock-apple/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Build the MockCoreFoundation library
add_library(MockCoreFoundation STATIC CFString.cpp)
target_compile_definitions(MockCoreFoundation PRIVATE ${APR_COMPILE_DEFINITIONS})
target_include_directories(MockCoreFoundation INTERFACE PRIVATE ${APR_INCLUDE_DIR})

# Add to log4cxx as a dependency
target_link_libraries(log4cxx PRIVATE MockCoreFoundation)
target_include_directories(log4cxx INTERFACE PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
24 changes: 24 additions & 0 deletions src/main/mock-apple/CoreFoundation/CFString.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Mocked CFString.h
*/
#include <stdint.h>
#if !defined(__COREFOUNDATION_CFSTRING__)
#define __COREFOUNDATION_CFSTRING__ 1
extern "C" {
typedef unsigned short UniChar;
typedef long CFIndex;
typedef struct __CFRange {
CFIndex location;
CFIndex length;
} CFRange;
typedef const struct __CFString* CFStringRef;
typedef const struct __CFAllocator* CFAllocatorRef;
typedef uint32_t CFStringEncoding;
CFRange CFRangeMake(CFIndex loc, CFIndex len);
CFIndex CFStringGetLength(CFStringRef theString);
void CFStringGetCharacters(CFStringRef theString, CFRange range, UniChar *buffer);
CFStringRef CFStringCreateWithCharacters(CFAllocatorRef alloc, const UniChar *chars, CFIndex numChars);
CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
#define kCFAllocatorDefault 0
#define CFSTR(cStr) CFStringCreateWithCString(kCFAllocatorDefault, cStr, 0)
}
#endif /* ! __COREFOUNDATION_CFSTRING__ */
6 changes: 5 additions & 1 deletion src/test/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,16 @@ endif()

get_filename_component(UNIT_TEST_WORKING_DIR ../resources ABSOLUTE)
if(LOG4CXX_CFSTRING)
set(CFSTR_TESTS filetestcase messagebuffertest leveltestcase streamtestcase)
set(CFSTR_TESTS filetestcase messagebuffertest leveltestcase streamtestcase transcodertestcase)
endif()
foreach(testName IN LISTS ALL_LOG4CXX_TESTS)
if (${testName} IN_LIST CFSTR_TESTS)
if(APPLE)
target_compile_options(${testName} PRIVATE "-fconstant-cfstrings")
target_link_libraries(${testName} PRIVATE "-framework CoreFoundation")
else()
target_link_libraries(${testName} PRIVATE MockCoreFoundation)
endif()
endif()
target_compile_definitions(${testName} PRIVATE ${TEST_COMPILE_DEFINITIONS} ${LOG4CXX_COMPILE_DEFINITIONS} ${APR_COMPILE_DEFINITIONS} ${APR_UTIL_COMPILE_DEFINITIONS} )
target_include_directories(${testName} PRIVATE ${CMAKE_CURRENT_LIST_DIR} $<TARGET_PROPERTY:log4cxx,INCLUDE_DIRECTORIES>)
Expand Down
34 changes: 32 additions & 2 deletions src/test/cpp/helpers/transcodertestcase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#include "../insertwide.h"
#include "../logunit.h"

#if LOG4CXX_CFSTRING_API
#include <CoreFoundation/CFString.h>
#endif

using namespace log4cxx;
using namespace log4cxx::helpers;
Expand All @@ -34,6 +37,9 @@ LOGUNIT_CLASS(TranscoderTestCase)
LOGUNIT_TEST(decode3);
#if LOG4CXX_WCHAR_T_API
LOGUNIT_TEST(decode4);
#endif
#if LOG4CXX_CFSTRING_API
LOGUNIT_TEST(decode5);
#endif
LOGUNIT_TEST(decode7);
LOGUNIT_TEST(decode8);
Expand All @@ -50,6 +56,9 @@ LOGUNIT_CLASS(TranscoderTestCase)
LOGUNIT_TEST(encode5);
#endif
LOGUNIT_TEST(encode6);
#if LOG4CXX_CFSTRING_API
LOGUNIT_TEST(encode7);
#endif
LOGUNIT_TEST(testDecodeUTF8_1);
LOGUNIT_TEST(testDecodeUTF8_2);
LOGUNIT_TEST(testDecodeUTF8_3);
Expand Down Expand Up @@ -106,6 +115,16 @@ LOGUNIT_CLASS(TranscoderTestCase)
}
#endif

#if LOG4CXX_CFSTRING_API
void decode5()
{
LogString nothing;
LogString decoded(LOG4CXX_STR("foo\n"));
Transcoder::decode(nothing, decoded);
LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("foo\n"), decoded);
}
#endif


enum { BUFSIZE = 255 };

Expand Down Expand Up @@ -169,7 +188,7 @@ LOGUNIT_CLASS(TranscoderTestCase)
{
// Test invalid multibyte string
LogString greeting;
greeting.push_back( 0xff );
greeting.push_back( logchar(0xff) );
std::wstring encoded;
Transcoder::encode(greeting, encoded);

Expand Down Expand Up @@ -247,6 +266,17 @@ LOGUNIT_CLASS(TranscoderTestCase)
Transcoder::encode(decoded, encoded);
}

#if LOG4CXX_CFSTRING_API
void encode7()
{
const LogString greeting(LOG4CXX_STR("Hello, World"));
CFStringRef encoded = Transcoder::encode(greeting);
LogString decoded;
Transcoder::decode(encoded, decoded);
LOGUNIT_ASSERT_EQUAL(LOG4CXX_STR("Hello, World"), decoded);
}
#endif

void testDecodeUTF8_1()
{
std::string src("a");
Expand All @@ -257,7 +287,7 @@ LOGUNIT_CLASS(TranscoderTestCase)

void testDecodeUTF8_2()
{
std::string src(1, 0x80);
std::string src(1, char(0x80));
LogString out;
Transcoder::decodeUTF8(src, out);
LOGUNIT_ASSERT_EQUAL(LogString(1, Transcoder::LOSSCHAR), out);
Expand Down

0 comments on commit 455fb8e

Please sign in to comment.