Added support for charset conversion with ICU (thanks to Mehmet Bozkurt).
This commit is contained in:
parent
f381654277
commit
9d2703c376
2
AUTHORS
2
AUTHORS
@ -28,7 +28,7 @@ AUTHORS file.
|
||||
- Zarafa <http://developer.zarafa.com/VmimePatches>
|
||||
- Bartek Szurgot <vempirelord@wp.pl, http://baszerr.org>
|
||||
- Achim Brandt <http://sourceforge.net/users/a-brandt/>
|
||||
- Mehmet Bozkurt <mehmet.bozkurt78@gmail.com> (OpenSSL support)
|
||||
- Mehmet Bozkurt <mehmet.bozkurt78@gmail.com> (OpenSSL support, ICU support)
|
||||
|
||||
Please apologize if I have forgotten someone here. ;) Send me an email
|
||||
to <vincent@vmime.org> if you want your name to be listed.
|
||||
|
@ -12,7 +12,7 @@
|
||||
# http://www.cmake.org
|
||||
#
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3 FATAL_ERROR)
|
||||
|
||||
INCLUDE(cmake/Utils.cmake)
|
||||
|
||||
@ -623,25 +623,74 @@ ENDIF(VMIME_HAVE_TLS_SUPPORT)
|
||||
|
||||
|
||||
##############################################################################
|
||||
# iconv
|
||||
# Charset conversion library
|
||||
|
||||
INCLUDE(cmake/FindIconv.cmake)
|
||||
INCLUDE(cmake/FindICU.cmake)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${INCLUDE_DIRECTORIES}
|
||||
${ICONV_INCLUDE_DIR}
|
||||
)
|
||||
FIND_PACKAGE(ICU QUIET)
|
||||
|
||||
IF(VMIME_BUILD_SHARED_LIBRARY)
|
||||
TARGET_LINK_LIBRARIES(
|
||||
${VMIME_LIBRARY_NAME}
|
||||
${TARGET_LINK_LIBRARIES}
|
||||
${ICONV_LIBRARIES}
|
||||
)
|
||||
IF(ICONV_FOUND)
|
||||
SET(VMIME_CHARSETCONV_LIB_IS_ICONV_DEFAULT "ON")
|
||||
SET(VMIME_CHARSETCONV_LIB_IS_ICU_DEFAULT "OFF")
|
||||
ELSEIF(ICU_LIBRARIES)
|
||||
SET(VMIME_CHARSETCONV_LIB_IS_ICONV_DEFAULT "OFF")
|
||||
SET(VMIME_CHARSETCONV_LIB_IS_ICU_DEFAULT "ON")
|
||||
ENDIF()
|
||||
|
||||
SET(VMIME_PKGCONFIG_LIBS "${VMIME_PKGCONFIG_LIBS} ${ICONV_LIBRARIES}")
|
||||
SET(VMIME_PKGCONFIG_CFLAGS "${VMIME_PKGCONFIG_CFLAGS} -I${ICONV_INCLUDE_DIR}")
|
||||
OPTION(
|
||||
VMIME_CHARSETCONV_LIB_IS_ICONV
|
||||
"Use iconv library for charset conversion"
|
||||
${VMIME_CHARSETCONV_LIB_IS_ICONV_DEFAULT}
|
||||
)
|
||||
|
||||
OPTION(
|
||||
VMIME_CHARSETCONV_LIB_IS_ICU
|
||||
"Use ICU library for charset conversion"
|
||||
${VMIME_CHARSETCONV_LIB_IS_ICU_DEFAULT}
|
||||
)
|
||||
|
||||
IF(VMIME_CHARSETCONV_LIB_IS_ICONV)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${INCLUDE_DIRECTORIES}
|
||||
${ICONV_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
IF(VMIME_BUILD_SHARED_LIBRARY)
|
||||
TARGET_LINK_LIBRARIES(
|
||||
${VMIME_LIBRARY_NAME}
|
||||
${TARGET_LINK_LIBRARIES}
|
||||
${ICONV_LIBRARIES}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET(VMIME_PKGCONFIG_LIBS "${VMIME_PKGCONFIG_LIBS} ${ICONV_LIBRARIES}")
|
||||
SET(VMIME_PKGCONFIG_CFLAGS "${VMIME_PKGCONFIG_CFLAGS} -I${ICONV_INCLUDE_DIR}")
|
||||
|
||||
ELSEIF(VMIME_CHARSETCONV_LIB_IS_ICU)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${INCLUDE_DIRECTORIES}
|
||||
${ICU_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
IF(VMIME_BUILD_SHARED_LIBRARY)
|
||||
TARGET_LINK_LIBRARIES(
|
||||
${VMIME_LIBRARY_NAME}
|
||||
${TARGET_LINK_LIBRARIES}
|
||||
${ICU_LIBRARIES}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET(VMIME_PKGCONFIG_LIBS "${VMIME_PKGCONFIG_LIBS} ${ICU_LIBRARIES}")
|
||||
SET(VMIME_PKGCONFIG_CFLAGS "${VMIME_PKGCONFIG_CFLAGS} -I${ICU_INCLUDE_DIRS}")
|
||||
|
||||
ELSE()
|
||||
|
||||
MESSAGE(FATAL_ERROR "No charset conversion library was selected/found")
|
||||
|
||||
ENDIF()
|
||||
|
||||
|
||||
##############################################################################
|
||||
|
15
SConstruct
15
SConstruct
@ -57,6 +57,7 @@ libvmime_sources = [
|
||||
'charset.cpp', 'charset.hpp',
|
||||
'charsetConverter.cpp', 'charsetConverter.hpp',
|
||||
'charsetConverter_iconv.cpp', 'charsetConverter_iconv.hpp',
|
||||
'charsetConverter_icu.cpp', 'charsetConverter_icu.hpp',
|
||||
'charsetConverter_idna.cpp', 'charsetConverter_idna.hpp',
|
||||
'charsetConverterOptions.cpp', 'charsetConverterOptions.hpp',
|
||||
'component.cpp', 'component.hpp',
|
||||
@ -673,6 +674,15 @@ if env['with_tls'] == 'yes':
|
||||
|
||||
env.Append(CXXFLAGS = ['-pthread'])
|
||||
|
||||
# Charset conversion library
|
||||
|
||||
# -- iconv
|
||||
if sys.platform == "mac" or sys.platform == "darwin":
|
||||
env.Append(LIBS = ['iconv', 'gcrypt'])
|
||||
|
||||
# -- ICU
|
||||
env.Append(LIBS = ['icuuc', 'icudata', 'icui18n'])
|
||||
|
||||
# Generate help text for command line options
|
||||
Help(opts.GenerateHelpText(env))
|
||||
|
||||
@ -836,6 +846,11 @@ config_hpp.write('\n')
|
||||
config_hpp.write('#define VMIME_HAVE_SIZE_T 1\n')
|
||||
config_hpp.write('\n')
|
||||
|
||||
config_hpp.write('// Charset conversion support\n')
|
||||
config_hpp.write('#define VMIME_CHARSETCONV_LIB_IS_ICONV 1\n')
|
||||
config_hpp.write('#define VMIME_CHARSETCONV_LIB_IS_ICU 0\n')
|
||||
config_hpp.write('\n')
|
||||
|
||||
config_hpp.write('// Options\n')
|
||||
|
||||
config_hpp.write('// -- File-system support\n')
|
||||
|
314
cmake/FindICU.cmake
Normal file
314
cmake/FindICU.cmake
Normal file
@ -0,0 +1,314 @@
|
||||
# This module can find the International Components for Unicode (ICU) Library
|
||||
#
|
||||
# Requirements:
|
||||
# - CMake >= 2.8.3 (for new version of find_package_handle_standard_args)
|
||||
#
|
||||
# The following variables will be defined for your use:
|
||||
# - ICU_FOUND : were all of your specified components found (include dependencies)?
|
||||
# - ICU_INCLUDE_DIRS : ICU include directory
|
||||
# - ICU_LIBRARIES : ICU libraries
|
||||
# - ICU_VERSION : complete version of ICU (x.y.z)
|
||||
# - ICU_MAJOR_VERSION : major version of ICU
|
||||
# - ICU_MINOR_VERSION : minor version of ICU
|
||||
# - ICU_PATCH_VERSION : patch version of ICU
|
||||
# - ICU_<COMPONENT>_FOUND : were <COMPONENT> found? (FALSE for non specified component if it is not a dependency)
|
||||
#
|
||||
# For windows or non standard installation, define ICU_ROOT variable to point to the root installation of ICU. Two ways:
|
||||
# - run cmake with -DICU_ROOT=<PATH>
|
||||
# - define an environment variable with the same name before running cmake
|
||||
# With cmake-gui, before pressing "Configure":
|
||||
# 1) Press "Add Entry" button
|
||||
# 2) Add a new entry defined as:
|
||||
# - Name: ICU_ROOT
|
||||
# - Type: choose PATH in the selection list
|
||||
# - Press "..." button and select the root installation of ICU
|
||||
#
|
||||
# Example Usage:
|
||||
#
|
||||
# 1. Copy this file in the root of your project source directory
|
||||
# 2. Then, tell CMake to search this non-standard module in your project directory by adding to your CMakeLists.txt:
|
||||
# set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR})
|
||||
# 3. Finally call find_package() once, here are some examples to pick from
|
||||
#
|
||||
# Require ICU 4.4 or later
|
||||
# find_package(ICU 4.4 REQUIRED)
|
||||
#
|
||||
# if(ICU_FOUND)
|
||||
# include_directories(${ICU_INCLUDE_DIRS})
|
||||
# add_executable(myapp myapp.c)
|
||||
# target_link_libraries(myapp ${ICU_LIBRARIES})
|
||||
# endif(ICU_FOUND)
|
||||
|
||||
#=============================================================================
|
||||
# Copyright (c) 2011-2012, julp
|
||||
# https://github.com/julp/FindICU.cmake
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
#=============================================================================
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
|
||||
########## Private ##########
|
||||
set(ICU_PUBLIC_VAR_NS "ICU") # Prefix for all ICU relative public variables
|
||||
set(ICU_PRIVATE_VAR_NS "_${ICU_PUBLIC_VAR_NS}") # Prefix for all ICU relative internal variables
|
||||
set(PC_ICU_PRIVATE_VAR_NS "_PC${ICU_PRIVATE_VAR_NS}") # Prefix for all pkg-config relative internal variables
|
||||
|
||||
function(icudebug _VARNAME)
|
||||
if(${ICU_PUBLIC_VAR_NS}_DEBUG)
|
||||
if(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
|
||||
message("${ICU_PUBLIC_VAR_NS}_${_VARNAME} = ${${ICU_PUBLIC_VAR_NS}_${_VARNAME}}")
|
||||
else(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
|
||||
message("${ICU_PUBLIC_VAR_NS}_${_VARNAME} = <UNDEFINED>")
|
||||
endif(DEFINED ${ICU_PUBLIC_VAR_NS}_${_VARNAME})
|
||||
endif(${ICU_PUBLIC_VAR_NS}_DEBUG)
|
||||
endfunction(icudebug)
|
||||
|
||||
set(${ICU_PRIVATE_VAR_NS}_ROOT "")
|
||||
if(DEFINED ENV{ICU_ROOT})
|
||||
set(${ICU_PRIVATE_VAR_NS}_ROOT "$ENV{ICU_ROOT}")
|
||||
endif(DEFINED ENV{ICU_ROOT})
|
||||
if (DEFINED ICU_ROOT)
|
||||
set(${ICU_PRIVATE_VAR_NS}_ROOT "${ICU_ROOT}")
|
||||
endif(DEFINED ICU_ROOT)
|
||||
|
||||
set(${ICU_PRIVATE_VAR_NS}_BIN_SUFFIXES )
|
||||
set(${ICU_PRIVATE_VAR_NS}_LIB_SUFFIXES )
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_BIN_SUFFIXES "bin64")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_LIB_SUFFIXES "lib64")
|
||||
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_BIN_SUFFIXES "bin")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_LIB_SUFFIXES "lib")
|
||||
|
||||
set(${ICU_PRIVATE_VAR_NS}_COMPONENTS )
|
||||
# <icu component name> <library name 1> ... <library name N>
|
||||
macro(icu_declare_component _NAME)
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_COMPONENTS ${_NAME})
|
||||
set("${ICU_PRIVATE_VAR_NS}_COMPONENTS_${_NAME}" ${ARGN})
|
||||
endmacro(icu_declare_component)
|
||||
|
||||
icu_declare_component(data icudata)
|
||||
icu_declare_component(uc icuuc) # Common and Data libraries
|
||||
icu_declare_component(i18n icui18n icuin) # Internationalization library
|
||||
icu_declare_component(io icuio ustdio) # Stream and I/O Library
|
||||
icu_declare_component(le icule) # Layout library
|
||||
icu_declare_component(lx iculx) # Paragraph Layout library
|
||||
|
||||
########## Public ##########
|
||||
set(${ICU_PUBLIC_VAR_NS}_FOUND TRUE)
|
||||
set(${ICU_PUBLIC_VAR_NS}_LIBRARIES )
|
||||
set(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS )
|
||||
set(${ICU_PUBLIC_VAR_NS}_C_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CXX_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CPP_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_C_SHARED_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CXX_SHARED_FLAGS "")
|
||||
set(${ICU_PUBLIC_VAR_NS}_CPP_SHARED_FLAGS "")
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PRIVATE_VAR_NS}_COMPONENTS})
|
||||
string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
|
||||
set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" FALSE) # may be done in the icu_declare_component macro
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
|
||||
# Check components
|
||||
if(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS) # uc required at least
|
||||
set(${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS uc)
|
||||
else(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
|
||||
list(APPEND ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS uc)
|
||||
list(REMOVE_DUPLICATES ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
|
||||
if(NOT DEFINED ${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
|
||||
message(FATAL_ERROR "Unknown ICU component: ${${ICU_PRIVATE_VAR_NS}_COMPONENT}")
|
||||
endif(NOT DEFINED ${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
endif(NOT ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
|
||||
|
||||
# Includes
|
||||
find_path(
|
||||
${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS
|
||||
NAMES unicode/utypes.h utypes.h
|
||||
HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT}
|
||||
PATH_SUFFIXES "include"
|
||||
DOC "Include directories for ICU"
|
||||
)
|
||||
|
||||
if(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
|
||||
########## <part to keep synced with tests/version/CMakeLists.txt> ##########
|
||||
if(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uvernum.h") # ICU >= 4
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uvernum.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uversion.h") # ICU [2;4[
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/uversion.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/utypes.h") # ICU [1.4;2[
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/unicode/utypes.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
elseif(EXISTS "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/utypes.h") # ICU 1.3
|
||||
file(READ "${${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS}/utypes.h" ${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS)
|
||||
else()
|
||||
message(FATAL_ERROR "ICU version header not found")
|
||||
endif()
|
||||
|
||||
if(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *ICU_VERSION *\"([0-9]+)\".*") # ICU 1.3
|
||||
# [1.3;1.4[ as #define ICU_VERSION "3" (no patch version, ie all 1.3.X versions will be detected as 1.3.0)
|
||||
set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "1")
|
||||
set(${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${CMAKE_MATCH_1}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "0")
|
||||
elseif(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *U_ICU_VERSION_MAJOR_NUM *([0-9]+).*")
|
||||
set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
||||
#
|
||||
# Since version 4.9.1, ICU release version numbering was totaly changed, see:
|
||||
# - http://site.icu-project.org/download/49
|
||||
# - http://userguide.icu-project.org/design#TOC-Version-Numbers-in-ICU
|
||||
#
|
||||
if(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION LESS 49)
|
||||
string(REGEX REPLACE ".*# *define *U_ICU_VERSION_MINOR_NUM *([0-9]+).*" "\\1" ${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS}")
|
||||
string(REGEX REPLACE ".*# *define *U_ICU_VERSION_PATCHLEVEL_NUM *([0-9]+).*" "\\1" ${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "${${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS}")
|
||||
else(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION LESS 49)
|
||||
string(REGEX MATCH [0-9]$ ${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION}")
|
||||
string(REGEX REPLACE [0-9]$ "" ${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "${${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION}")
|
||||
string(REGEX REPLACE ".*# *define *U_ICU_VERSION_MINOR_NUM *([0-9]+).*" "\\1" ${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "${${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS}")
|
||||
endif(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION LESS 49)
|
||||
elseif(${ICU_PRIVATE_VAR_NS}_VERSION_HEADER_CONTENTS MATCHES ".*# *define *U_ICU_VERSION *\"(([0-9]+)(\\.[0-9]+)*)\".*") # ICU [1.4;1.8[
|
||||
# [1.4;1.8[ as #define U_ICU_VERSION "1.4.1.2" but it seems that some 1.4.1(?:\.\d)? have releasing error and appears as 1.4.0
|
||||
set(${ICU_PRIVATE_VAR_NS}_FULL_VERSION "${CMAKE_MATCH_1}") # copy CMAKE_MATCH_1, no longer valid on the following if
|
||||
if(${ICU_PRIVATE_VAR_NS}_FULL_VERSION MATCHES "^([0-9]+)\\.([0-9]+)$")
|
||||
set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${CMAKE_MATCH_2}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "0")
|
||||
elseif(${ICU_PRIVATE_VAR_NS}_FULL_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
|
||||
set(${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION "${CMAKE_MATCH_1}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_MINOR_VERSION "${CMAKE_MATCH_2}")
|
||||
set(${ICU_PUBLIC_VAR_NS}_PATCH_VERSION "${CMAKE_MATCH_3}")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "failed to detect ICU version")
|
||||
endif()
|
||||
set(${ICU_PUBLIC_VAR_NS}_VERSION "${${ICU_PUBLIC_VAR_NS}_MAJOR_VERSION}.${${ICU_PUBLIC_VAR_NS}_MINOR_VERSION}.${${ICU_PUBLIC_VAR_NS}_PATCH_VERSION}")
|
||||
########## </part to keep synced with tests/version/CMakeLists.txt> ##########
|
||||
|
||||
# Check dependencies (implies pkg-config)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
set(${ICU_PRIVATE_VAR_NS}_COMPONENTS_DUP ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PRIVATE_VAR_NS}_COMPONENTS_DUP})
|
||||
pkg_check_modules(PC_ICU_PRIVATE_VAR_NS "icu-${${ICU_PRIVATE_VAR_NS}_COMPONENT}" QUIET)
|
||||
|
||||
if(${PC_ICU_PRIVATE_VAR_NS}_FOUND)
|
||||
foreach(${PC_ICU_PRIVATE_VAR_NS}_LIBRARY ${PC_ICU_LIBRARIES})
|
||||
string(REGEX REPLACE "^icu" "" ${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY ${${PC_ICU_PRIVATE_VAR_NS}_LIBRARY})
|
||||
list(APPEND ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS ${${PC_ICU_PRIVATE_VAR_NS}_STRIPPED_LIBRARY})
|
||||
endforeach(${PC_ICU_PRIVATE_VAR_NS}_LIBRARY)
|
||||
endif(${PC_ICU_PRIVATE_VAR_NS}_FOUND)
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
list(REMOVE_DUPLICATES ${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS)
|
||||
endif(PKG_CONFIG_FOUND)
|
||||
|
||||
# Check libraries
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_COMPONENT ${${ICU_PUBLIC_VAR_NS}_FIND_COMPONENTS})
|
||||
set(${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES )
|
||||
set(${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES )
|
||||
foreach(${ICU_PRIVATE_VAR_NS}_BASE_NAME ${${ICU_PRIVATE_VAR_NS}_COMPONENTS_${${ICU_PRIVATE_VAR_NS}_COMPONENT}})
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}d")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}${ICU_MAJOR_VERSION}${ICU_MINOR_VERSION}")
|
||||
list(APPEND ${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES "${${ICU_PRIVATE_VAR_NS}_BASE_NAME}${ICU_MAJOR_VERSION}${ICU_MINOR_VERSION}d")
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_BASE_NAME)
|
||||
|
||||
find_library(
|
||||
${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}
|
||||
NAMES ${${ICU_PRIVATE_VAR_NS}_POSSIBLE_RELEASE_NAMES}
|
||||
HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT}
|
||||
PATH_SUFFIXES ${_ICU_LIB_SUFFIXES}
|
||||
DOC "Release libraries for ICU"
|
||||
)
|
||||
find_library(
|
||||
${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}
|
||||
NAMES ${${ICU_PRIVATE_VAR_NS}_POSSIBLE_DEBUG_NAMES}
|
||||
HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT}
|
||||
PATH_SUFFIXES ${_ICU_LIB_SUFFIXES}
|
||||
DOC "Debug libraries for ICU"
|
||||
)
|
||||
|
||||
string(TOUPPER "${${ICU_PRIVATE_VAR_NS}_COMPONENT}" ${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT)
|
||||
if(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT} AND NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # both not found
|
||||
set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" FALSE)
|
||||
set("${ICU_PUBLIC_VAR_NS}_FOUND" FALSE)
|
||||
else(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT} AND NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # one or both found
|
||||
set("${ICU_PUBLIC_VAR_NS}_${${ICU_PRIVATE_VAR_NS}_UPPER_COMPONENT}_FOUND" TRUE)
|
||||
if(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # release not found => we are in debug
|
||||
set(${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT} "${${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}")
|
||||
elseif(NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}) # debug not found => we are in release
|
||||
set(${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT} "${${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}")
|
||||
else() # both found
|
||||
set(
|
||||
${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT}
|
||||
optimized ${${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}
|
||||
debug ${${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT}}
|
||||
)
|
||||
endif()
|
||||
list(APPEND ${ICU_PUBLIC_VAR_NS}_LIBRARIES ${${ICU_PRIVATE_VAR_NS}_LIB_${${ICU_PRIVATE_VAR_NS}_COMPONENT}})
|
||||
endif(NOT ${ICU_PRIVATE_VAR_NS}_LIB_RELEASE_${${ICU_PRIVATE_VAR_NS}_COMPONENT} AND NOT ${ICU_PRIVATE_VAR_NS}_LIB_DEBUG_${${ICU_PRIVATE_VAR_NS}_COMPONENT})
|
||||
endforeach(${ICU_PRIVATE_VAR_NS}_COMPONENT)
|
||||
|
||||
# Try to find out compiler flags
|
||||
find_program(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE HINTS ${${ICU_PRIVATE_VAR_NS}_ROOT} icu-config)
|
||||
if(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_C_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cxxflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CXX_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cppflags OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CPP_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_C_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cxxflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CXX_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE} --cppflags-dynamic OUTPUT_VARIABLE ${ICU_PUBLIC_VAR_NS}_CPP_SHARED_FLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif(${ICU_PUBLIC_VAR_NS}_CONFIG_EXECUTABLE)
|
||||
|
||||
# Check find_package arguments
|
||||
include(FindPackageHandleStandardArgs)
|
||||
if(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
find_package_handle_standard_args(
|
||||
${ICU_PUBLIC_VAR_NS}
|
||||
REQUIRED_VARS ${ICU_PUBLIC_VAR_NS}_LIBRARIES ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS
|
||||
VERSION_VAR ${ICU_PUBLIC_VAR_NS}_VERSION
|
||||
)
|
||||
else(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
find_package_handle_standard_args(${ICU_PUBLIC_VAR_NS} "ICU not found" ${ICU_PUBLIC_VAR_NS}_LIBRARIES ${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
|
||||
endif(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
else(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
|
||||
if(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
message(FATAL_ERROR "Could not find ICU include directory")
|
||||
endif(${ICU_PUBLIC_VAR_NS}_FIND_REQUIRED AND NOT ${ICU_PUBLIC_VAR_NS}_FIND_QUIETLY)
|
||||
endif(${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(
|
||||
${ICU_PUBLIC_VAR_NS}_INCLUDE_DIRS
|
||||
${ICU_PUBLIC_VAR_NS}_LIBRARIES
|
||||
)
|
||||
|
||||
# IN (args)
|
||||
icudebug("FIND_COMPONENTS")
|
||||
icudebug("FIND_REQUIRED")
|
||||
icudebug("FIND_QUIETLY")
|
||||
icudebug("FIND_VERSION")
|
||||
# OUT
|
||||
# Found
|
||||
icudebug("FOUND")
|
||||
icudebug("UC_FOUND")
|
||||
icudebug("I18N_FOUND")
|
||||
icudebug("IO_FOUND")
|
||||
icudebug("LE_FOUND")
|
||||
icudebug("LX_FOUND")
|
||||
icudebug("DATA_FOUND")
|
||||
# Flags
|
||||
icudebug("C_FLAGS")
|
||||
icudebug("CPP_FLAGS")
|
||||
icudebug("CXX_FLAGS")
|
||||
icudebug("C_SHARED_FLAGS")
|
||||
icudebug("CPP_SHARED_FLAGS")
|
||||
icudebug("CXX_SHARED_FLAGS")
|
||||
# Linking
|
||||
icudebug("INCLUDE_DIRS")
|
||||
icudebug("LIBRARIES")
|
||||
# Version
|
||||
icudebug("MAJOR_VERSION")
|
||||
icudebug("MINOR_VERSION")
|
||||
icudebug("PATCH_VERSION")
|
||||
icudebug("VERSION")
|
@ -37,6 +37,10 @@ typedef unsigned @VMIME_32BIT_TYPE@ vmime_uint32;
|
||||
|
||||
#cmakedefine01 VMIME_HAVE_SIZE_T
|
||||
|
||||
// Charset conversion support
|
||||
#cmakedefine01 VMIME_CHARSETCONV_LIB_IS_ICONV
|
||||
#cmakedefine01 VMIME_CHARSETCONV_LIB_IS_ICU
|
||||
|
||||
// Options
|
||||
// -- File-system support
|
||||
#cmakedefine01 VMIME_HAVE_FILESYSTEM_FEATURES
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
#include "vmime/charsetConverter.hpp"
|
||||
|
||||
#include "vmime/charsetConverter_iconv.hpp"
|
||||
#include "vmime/charsetConverter_idna.hpp"
|
||||
|
||||
|
||||
@ -39,7 +38,7 @@ ref <charsetConverter> charsetConverter::create
|
||||
if (source == "idna" || dest == "idna")
|
||||
return vmime::create <charsetConverter_idna>(source, dest, opts);
|
||||
else
|
||||
return vmime::create <charsetConverter_iconv>(source, dest, opts);
|
||||
return createGenericConverter(source, dest, opts);
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,6 +21,12 @@
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_CHARSETCONV_LIB_IS_ICONV
|
||||
|
||||
|
||||
#include "vmime/charsetConverter_iconv.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
@ -82,6 +88,15 @@ namespace vmime
|
||||
{
|
||||
|
||||
|
||||
// static
|
||||
ref <charsetConverter> charsetConverter::createGenericConverter
|
||||
(const charset& source, const charset& dest,
|
||||
const charsetConverterOptions& opts)
|
||||
{
|
||||
return vmime::create <charsetConverter_iconv>(source, dest, opts);
|
||||
}
|
||||
|
||||
|
||||
charsetConverter_iconv::charsetConverter_iconv
|
||||
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
|
||||
: m_desc(NULL), m_source(source), m_dest(dest), m_options(opts)
|
||||
@ -433,3 +448,6 @@ void charsetFilteredOutputStream_iconv::flush()
|
||||
|
||||
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_CHARSETCONV_LIB_IS_ICONV
|
||||
|
202
src/charsetConverter_icu.cpp
Executable file
202
src/charsetConverter_icu.cpp
Executable file
@ -0,0 +1,202 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_CHARSETCONV_LIB_IS_ICU
|
||||
|
||||
|
||||
#include "vmime/charsetConverter_icu.hpp"
|
||||
|
||||
#include "vmime/exception.hpp"
|
||||
#include "vmime/utility/inputStreamStringAdapter.hpp"
|
||||
#include "vmime/utility/outputStreamStringAdapter.hpp"
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
|
||||
#include <unicode/ucnv.h>
|
||||
#include <unicode/ucnv_err.h>
|
||||
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
}
|
||||
|
||||
|
||||
#include <unicode/unistr.h>
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
|
||||
|
||||
// static
|
||||
ref <charsetConverter> charsetConverter::createGenericConverter
|
||||
(const charset& source, const charset& dest,
|
||||
const charsetConverterOptions& opts)
|
||||
{
|
||||
return vmime::create <charsetConverter_icu>(source, dest, opts);
|
||||
}
|
||||
|
||||
|
||||
charsetConverter_icu::charsetConverter_icu
|
||||
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
|
||||
: m_from(NULL), m_to(NULL), m_source(source), m_dest(dest), m_options(opts)
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
m_from = ucnv_open(source.getName().c_str(), &err);
|
||||
|
||||
if (err != U_ZERO_ERROR)
|
||||
throw exceptions::charset_conv_error("Cannot initialize ICU [from] converter.");
|
||||
|
||||
m_to = ucnv_open(dest.getName().c_str(), &err);
|
||||
|
||||
if (err != U_ZERO_ERROR)
|
||||
throw exceptions::charset_conv_error("Cannot initialize ICU [to] converter.");
|
||||
}
|
||||
|
||||
|
||||
charsetConverter_icu::~charsetConverter_icu()
|
||||
{
|
||||
ucnv_close(m_from);
|
||||
ucnv_close(m_to);
|
||||
}
|
||||
|
||||
|
||||
void charsetConverter_icu::convert(utility::inputStream& in, utility::outputStream& out)
|
||||
{
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
// From buffers
|
||||
char cpInBuffer[16]; // stream data put here
|
||||
size_t outSize = ucnv_getMinCharSize(m_from) * sizeof(cpInBuffer) * sizeof(UChar);
|
||||
UChar* uOutBuffer = new UChar[outSize]; // Unicode chars end up here
|
||||
|
||||
// Auto delete Unicode char buffer
|
||||
vmime::utility::auto_ptr<UChar> cleanup(uOutBuffer);
|
||||
|
||||
// To buffers
|
||||
// converted (char) data end up here
|
||||
size_t cpOutBufferSz = ucnv_getMaxCharSize(m_to) * outSize;
|
||||
char* cpOutBuffer = new char[cpOutBufferSz];
|
||||
vmime::utility::auto_ptr<char> cleanupOut(cpOutBuffer);
|
||||
|
||||
// Set replacement chars for when converting from Unicode to codepage
|
||||
icu::UnicodeString substString(m_options.invalidSequence.c_str());
|
||||
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
|
||||
|
||||
if (U_FAILURE(err))
|
||||
throw exceptions::charset_conv_error("[ICU] Error setting replacement char.");
|
||||
|
||||
// Input data available
|
||||
while (!in.eof())
|
||||
{
|
||||
// Read input data into buffer
|
||||
size_t inLength = static_cast<size_t>(in.read(cpInBuffer, sizeof(cpInBuffer)));
|
||||
|
||||
// Beginning of read data
|
||||
const char* source = &cpInBuffer[0];
|
||||
const char* sourceLimit = source + inLength; // end + 1
|
||||
|
||||
UBool flush = in.eof(); // is this last run?
|
||||
|
||||
UErrorCode toErr;
|
||||
|
||||
// Loop until all source has been processed
|
||||
do
|
||||
{
|
||||
// Set up target pointers
|
||||
UChar* target = uOutBuffer;
|
||||
UChar* targetLimit = target + outSize;
|
||||
|
||||
toErr = U_ZERO_ERROR;
|
||||
ucnv_toUnicode(m_from, &target, targetLimit,
|
||||
&source, sourceLimit, NULL, flush, &toErr);
|
||||
|
||||
if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr))
|
||||
throw exceptions::charset_conv_error("[ICU] Error converting to Unicode from " + m_source.getName());
|
||||
|
||||
// The Unicode source is the buffer just written and the limit
|
||||
// is where the previous conversion stopped (target is moved in the conversion)
|
||||
const UChar* uSource = uOutBuffer;
|
||||
UChar* uSourceLimit = target;
|
||||
UErrorCode fromErr;
|
||||
|
||||
// Loop until converted chars are fully written
|
||||
do
|
||||
{
|
||||
char* cpTarget = &cpOutBuffer[0];
|
||||
const char* cpTargetLimit = cpOutBuffer + cpOutBufferSz;
|
||||
|
||||
fromErr = U_ZERO_ERROR;
|
||||
|
||||
// Write converted bytes (Unicode) to destination codepage
|
||||
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
|
||||
&uSource, uSourceLimit, NULL, flush, &fromErr);
|
||||
|
||||
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
|
||||
throw exceptions::charset_conv_error("[ICU] Error converting from Unicode to " + m_dest.getName());
|
||||
|
||||
// Write to destination stream
|
||||
out.write(cpOutBuffer, (cpTarget - cpOutBuffer));
|
||||
|
||||
} while (fromErr == U_BUFFER_OVERFLOW_ERROR);
|
||||
|
||||
} while (toErr == U_BUFFER_OVERFLOW_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void charsetConverter_icu::convert(const string& in, string& out)
|
||||
{
|
||||
if (m_source == m_dest)
|
||||
{
|
||||
// No conversion needed
|
||||
out = in;
|
||||
return;
|
||||
}
|
||||
|
||||
out.clear();
|
||||
|
||||
utility::inputStreamStringAdapter is(in);
|
||||
utility::outputStreamStringAdapter os(out);
|
||||
|
||||
convert(is, os);
|
||||
|
||||
os.flush();
|
||||
}
|
||||
|
||||
|
||||
ref <utility::charsetFilteredOutputStream> charsetConverter_icu::getFilteredOutputStream(utility::outputStream& os)
|
||||
{
|
||||
// TODO: implement charsetFilteredOutputStream for ICU
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_CHARSETCONV_LIB_IS_ICU
|
@ -49,6 +49,8 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest)
|
||||
vmime::utility::outputStreamStringAdapter os(output);
|
||||
vmime::ref <vmime::utility::filteredOutputStream> cfos = cc->getFilteredOutputStream(os);
|
||||
|
||||
VASSERT_NOT_NULL("filteredOutputStream availability", cfos);
|
||||
|
||||
// føo = 66 c3 b8 6f [UTF8]
|
||||
// føo = 66 c3 b8 6f [latin1]
|
||||
|
||||
@ -79,6 +81,8 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest)
|
||||
vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
|
||||
conv->getFilteredOutputStream(osa);
|
||||
|
||||
VASSERT_NOT_NULL("filteredOutputStream availability", os);
|
||||
|
||||
vmime::utility::inputStreamStringAdapter is(in);
|
||||
|
||||
vmime::utility::stream::value_type buffer[16];
|
||||
@ -116,6 +120,8 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest)
|
||||
vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
|
||||
conv->getFilteredOutputStream(osa);
|
||||
|
||||
VASSERT_NOT_NULL("filteredOutputStream availability", os);
|
||||
|
||||
vmime::utility::inputStreamStringAdapter is(in);
|
||||
|
||||
vmime::utility::bufferedStreamCopy(is, *os);
|
||||
@ -151,6 +157,8 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest)
|
||||
vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
|
||||
conv->getFilteredOutputStream(osa);
|
||||
|
||||
VASSERT_NOT_NULL("filteredOutputStream availability", os);
|
||||
|
||||
vmime::utility::inputStreamStringAdapter is(in);
|
||||
|
||||
vmime::utility::stream::value_type buffer[16];
|
||||
@ -189,6 +197,8 @@ VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest)
|
||||
vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
|
||||
conv->getFilteredOutputStream(osa);
|
||||
|
||||
VASSERT_NOT_NULL("filteredOutputStream availability", os);
|
||||
|
||||
vmime::utility::inputStreamStringAdapter is(in);
|
||||
|
||||
vmime::utility::stream::value_type buffer[16];
|
||||
|
@ -141,7 +141,8 @@ VMIME_TEST_SUITE_BEGIN(charsetTest)
|
||||
void testUTF7Support()
|
||||
{
|
||||
// Ensure UTF-7 is supported, because it is used for IMAP
|
||||
VASSERT_EQ("1", "VMime +ACY UTF-7 encoding", convertHelper("VMime & UTF-7 encoding", "utf-8", "utf-7"));
|
||||
VASSERT_EQ("1", "VMime +- UTF-7 encoding", convertHelper("VMime + UTF-7 encoding", "utf-8", "utf-7"));
|
||||
VASSERT_EQ("2", "f+APg-o", convertHelper("\x66\xc3\xb8\x6f", "utf-8", "utf-7"));
|
||||
}
|
||||
|
||||
VMIME_TEST_SUITE_END
|
||||
|
@ -104,6 +104,12 @@ public:
|
||||
* @return a filtered output stream, or NULL if not supported
|
||||
*/
|
||||
virtual ref <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os) = 0;
|
||||
|
||||
private:
|
||||
|
||||
static ref <charsetConverter> createGenericConverter
|
||||
(const charset& source, const charset& dest,
|
||||
const charsetConverterOptions& opts);
|
||||
};
|
||||
|
||||
|
||||
|
@ -25,6 +25,12 @@
|
||||
#define VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_CHARSETCONV_LIB_IS_ICONV
|
||||
|
||||
|
||||
#include "vmime/charsetConverter.hpp"
|
||||
|
||||
|
||||
@ -121,4 +127,6 @@ private:
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_CHARSETCONV_LIB_IS_ICONV
|
||||
|
||||
#endif // VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED
|
||||
|
84
vmime/charsetConverter_icu.hpp
Executable file
84
vmime/charsetConverter_icu.hpp
Executable file
@ -0,0 +1,84 @@
|
||||
//
|
||||
// VMime library (http://www.vmime.org)
|
||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 3 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
// Linking this library statically or dynamically with other modules is making
|
||||
// a combined work based on this library. Thus, the terms and conditions of
|
||||
// the GNU General Public License cover the whole combination.
|
||||
//
|
||||
|
||||
#ifndef VMIME_CHARSETCONVERTER_ICU_HPP_INCLUDED
|
||||
#define VMIME_CHARSETCONVERTER_ICU_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "vmime/config.hpp"
|
||||
|
||||
|
||||
#if VMIME_CHARSETCONV_LIB_IS_ICU
|
||||
|
||||
|
||||
#include "vmime/charsetConverter.hpp"
|
||||
|
||||
|
||||
struct UConverter;
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
|
||||
|
||||
/** A generic charset converter which uses ICU library.
|
||||
*/
|
||||
|
||||
class charsetConverter_icu : public charsetConverter
|
||||
{
|
||||
public:
|
||||
|
||||
/** Construct and initialize an ICU charset converter.
|
||||
*
|
||||
* @param source input charset
|
||||
* @param dest output charset
|
||||
* @param opts conversion options
|
||||
*/
|
||||
charsetConverter_icu(const charset& source, const charset& dest,
|
||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
||||
|
||||
~charsetConverter_icu();
|
||||
|
||||
void convert(const string& in, string& out);
|
||||
void convert(utility::inputStream& in, utility::outputStream& out);
|
||||
|
||||
ref <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os);
|
||||
|
||||
private:
|
||||
|
||||
UConverter* m_from;
|
||||
UConverter* m_to;
|
||||
|
||||
charset m_source;
|
||||
charset m_dest;
|
||||
|
||||
charsetConverterOptions m_options;
|
||||
};
|
||||
|
||||
|
||||
} // vmime
|
||||
|
||||
|
||||
#endif // VMIME_CHARSETCONV_LIB_IS_ICU
|
||||
|
||||
#endif // VMIME_CHARSETCONVERTER_ICU_HPP_INCLUDED
|
Loading…
Reference in New Issue
Block a user