Merge branch 'master' into master
This commit is contained in:
commit
71968d978d
118
CMakeLists.txt
118
CMakeLists.txt
@ -12,7 +12,7 @@
|
|||||||
# http://www.cmake.org
|
# http://www.cmake.org
|
||||||
#
|
#
|
||||||
|
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.6 FATAL_ERROR)
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR)
|
||||||
|
|
||||||
INCLUDE(cmake/Utils.cmake)
|
INCLUDE(cmake/Utils.cmake)
|
||||||
|
|
||||||
@ -68,6 +68,11 @@ SET(VMIME_API_VERSION ${VMIME_API_VERSION_CURRENT}.${VMIME_API_VERSION_REVISION}
|
|||||||
# Set base name
|
# Set base name
|
||||||
SET(VMIME_LIBRARY_NAME vmime)
|
SET(VMIME_LIBRARY_NAME vmime)
|
||||||
|
|
||||||
|
# Enable C++11
|
||||||
|
SET(CMAKE_CXX_STANDARD 11)
|
||||||
|
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
SET(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
# Source files
|
# Source files
|
||||||
FILE(
|
FILE(
|
||||||
GLOB_RECURSE
|
GLOB_RECURSE
|
||||||
@ -109,6 +114,10 @@ IF(VMIME_BUILD_SHARED_LIBRARY)
|
|||||||
${VMIME_LIBRARY_INCLUDE_FILES}
|
${VMIME_LIBRARY_INCLUDE_FILES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TARGET_INCLUDE_DIRECTORIES(${VMIME_LIBRARY_NAME} PUBLIC
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
)
|
||||||
|
|
||||||
GENERATE_EXPORT_HEADER(
|
GENERATE_EXPORT_HEADER(
|
||||||
${VMIME_LIBRARY_NAME}
|
${VMIME_LIBRARY_NAME}
|
||||||
BASE_NAME VMIME
|
BASE_NAME VMIME
|
||||||
@ -154,6 +163,10 @@ IF(VMIME_BUILD_STATIC_LIBRARY)
|
|||||||
${VMIME_LIBRARY_INCLUDE_FILES}
|
${VMIME_LIBRARY_INCLUDE_FILES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TARGET_INCLUDE_DIRECTORIES(${VMIME_LIBRARY_NAME}-static PUBLIC
|
||||||
|
$<INSTALL_INTERFACE:include>
|
||||||
|
)
|
||||||
|
|
||||||
GENERATE_EXPORT_HEADER(
|
GENERATE_EXPORT_HEADER(
|
||||||
${VMIME_LIBRARY_NAME}-static
|
${VMIME_LIBRARY_NAME}-static
|
||||||
BASE_NAME VMIME
|
BASE_NAME VMIME
|
||||||
@ -199,6 +212,7 @@ SET(CMAKE_INSTALL_LIBDIR lib CACHE PATH "Output directory for libraries")
|
|||||||
IF(VMIME_BUILD_SHARED_LIBRARY)
|
IF(VMIME_BUILD_SHARED_LIBRARY)
|
||||||
INSTALL(
|
INSTALL(
|
||||||
TARGETS ${VMIME_LIBRARY_NAME}
|
TARGETS ${VMIME_LIBRARY_NAME}
|
||||||
|
EXPORT ${VMIME_LIBRARY_NAME}-config
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT sharedlibs
|
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT sharedlibs
|
||||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT sharedlibs
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT sharedlibs
|
||||||
)
|
)
|
||||||
@ -207,6 +221,7 @@ ENDIF()
|
|||||||
IF(VMIME_BUILD_STATIC_LIBRARY)
|
IF(VMIME_BUILD_STATIC_LIBRARY)
|
||||||
INSTALL(
|
INSTALL(
|
||||||
TARGETS ${VMIME_LIBRARY_NAME}-static
|
TARGETS ${VMIME_LIBRARY_NAME}-static
|
||||||
|
EXPORT ${VMIME_LIBRARY_NAME}-config
|
||||||
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT staticlibs
|
LIBRARY DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT staticlibs
|
||||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT staticlibs
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT staticlibs
|
||||||
)
|
)
|
||||||
@ -222,6 +237,8 @@ INSTALL_HEADERS_WITH_DIRECTORY(VMIME_LIBRARY_GENERATED_INCLUDE_FILES headers "${
|
|||||||
# COMPONENT headers
|
# COMPONENT headers
|
||||||
#)
|
#)
|
||||||
|
|
||||||
|
install(EXPORT ${VMIME_LIBRARY_NAME}-config DESTINATION cmake)
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Tests
|
# Tests
|
||||||
@ -783,89 +800,6 @@ ELSE()
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# Language features
|
|
||||||
|
|
||||||
# C++11
|
|
||||||
INCLUDE(cmake/cmake-cxx11/Modules/CheckCXX11Features.cmake)
|
|
||||||
|
|
||||||
# Smart pointers
|
|
||||||
#
|
|
||||||
# If a C++11-compliant compiler is available and supports std::shared_ptr<>,
|
|
||||||
# use the standard implementation. Else, use boost::shared_ptr<>.
|
|
||||||
# In any case, let the user override the choice with VMIME_SHARED_PTR_USE_CXX
|
|
||||||
# and VMIME_SHARED_PTR_USE_BOOST variables.
|
|
||||||
|
|
||||||
CHECK_CXX_SOURCE_COMPILES(
|
|
||||||
"
|
|
||||||
#include <memory>
|
|
||||||
struct A { int foo; };
|
|
||||||
int main() {
|
|
||||||
std::shared_ptr <A> a = std::make_shared <A>();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
VMIME_HAS_CXX11_SHARED_PTR
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(NOT VMIME_SHARED_PTR_USE_CXX AND NOT VMIME_SHARED_PTR_USE_BOOST)
|
|
||||||
IF(CXX11_COMPILER_FLAGS AND VMIME_HAS_CXX11_SHARED_PTR)
|
|
||||||
# If std::shared_ptr<> is available, use it by default
|
|
||||||
SET(VMIME_SHARED_PTR_USE_CXX_DEFAULT ON)
|
|
||||||
SET(VMIME_SHARED_PTR_USE_BOOST_DEFAULT OFF)
|
|
||||||
ELSE()
|
|
||||||
# Else, set default to boost::shared_ptr<>
|
|
||||||
SET(VMIME_SHARED_PTR_USE_CXX_DEFAULT OFF)
|
|
||||||
SET(VMIME_SHARED_PTR_USE_BOOST_DEFAULT ON)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
OPTION(
|
|
||||||
VMIME_SHARED_PTR_USE_CXX
|
|
||||||
"Use standard std::shared_ptr<> (requires a C++11 compiler)"
|
|
||||||
${VMIME_SHARED_PTR_USE_CXX_DEFAULT}
|
|
||||||
)
|
|
||||||
|
|
||||||
OPTION(
|
|
||||||
VMIME_SHARED_PTR_USE_BOOST
|
|
||||||
"Use boost::shared_ptr<> (requires Boost)"
|
|
||||||
${VMIME_SHARED_PTR_USE_BOOST_DEFAULT}
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(VMIME_SHARED_PTR_USE_CXX AND VMIME_SHARED_PTR_USE_BOOST)
|
|
||||||
MESSAGE(FATAL_ERROR "Options VMIME_SHARED_PTR_USE_CXX and VMIME_SHARED_PTR_USE_BOOST are mutually exclusive (select one or the other, but not both!)")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(VMIME_SHARED_PTR_USE_CXX)
|
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS}")
|
|
||||||
|
|
||||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "Checking support for shared_ptr<>: built-in (C++11)")
|
|
||||||
|
|
||||||
ELSEIF(VMIME_SHARED_PTR_USE_BOOST)
|
|
||||||
|
|
||||||
# Depends on Boost library if C++11 is not supported
|
|
||||||
FIND_PACKAGE(Boost)
|
|
||||||
|
|
||||||
IF(Boost_FOUND)
|
|
||||||
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(FATAL_ERROR "Boost library is required for shared_ptr<>, unless you compile using C++11")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "Checking support for shared_ptr<>: boost library")
|
|
||||||
|
|
||||||
ELSE()
|
|
||||||
|
|
||||||
MESSAGE(FATAL_ERROR "No implementation for shared_ptr<> was selected/found")
|
|
||||||
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Platform
|
# Platform
|
||||||
|
|
||||||
@ -997,12 +931,12 @@ IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|||||||
|
|
||||||
SET(
|
SET(
|
||||||
CMAKE_CXX_FLAGS
|
CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -D_REENTRANT=1 -W -Wall -pedantic -Warray-bounds-pointer-arithmetic -Wold-style-cast -Wconversion -Wcast-align -Wno-sign-conversion"
|
"-D_REENTRANT=1 -W -Wall -pedantic -Warray-bounds-pointer-arithmetic -Wold-style-cast -Wconversion -Wcast-align -Wno-sign-conversion ${CMAKE_CXX_FLAGS}"
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
|
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||||
|
|
||||||
#SET(CMAKE_EXE_LINKER_FLAGS "-s")
|
#SET(CMAKE_EXE_LINKER_FLAGS "-s")
|
||||||
|
|
||||||
@ -1012,12 +946,12 @@ ELSE()
|
|||||||
|
|
||||||
SET(
|
SET(
|
||||||
CMAKE_CXX_FLAGS
|
CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -D_REENTRANT=1 -W -Wall -pedantic -Wpointer-arith -Wold-style-cast -Wconversion -Wcast-align -Wno-long-long"
|
"-D_REENTRANT=1 -W -Wall -pedantic -Wpointer-arith -Wold-style-cast -Wconversion -Wcast-align -Wno-long-long ${CMAKE_CXX_FLAGS}"
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
|
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||||
|
|
||||||
#SET(CMAKE_EXE_LINKER_FLAGS "-s")
|
#SET(CMAKE_EXE_LINKER_FLAGS "-s")
|
||||||
|
|
||||||
|
76
HACKING
76
HACKING
@ -80,25 +80,52 @@ width to its preferred settings (eg. 4 or 8 spaces).
|
|||||||
2.2. Brace position
|
2.2. Brace position
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Open braces should always be at the beginning of the line after the statement
|
Open braces should always be at the end of the line of the statement that
|
||||||
that begins the block. Contents of the brace should be indented by 1 tab.
|
begins the block. Contents of the brace should be indented by 1 tab.
|
||||||
|
|
||||||
|
if (expr) {
|
||||||
|
|
||||||
if (expr)
|
|
||||||
{
|
|
||||||
do_something();
|
do_something();
|
||||||
do_another_thing();
|
do_another_thing();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
do_something_else();
|
do_something_else();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
In a function, the opening brace must always be followed by an empty line:
|
||||||
|
|
||||||
|
void header::appendField(const shared_ptr <headerField>& field) {
|
||||||
|
|
||||||
|
m_fields.push_back(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
A function with few arguments:
|
||||||
|
|
||||||
|
bool header::hasField(const string& fieldName) const {
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
A function with more arguments:
|
||||||
|
|
||||||
|
void header::parseImpl(
|
||||||
|
const parsingContext& ctx,
|
||||||
|
const string& buffer,
|
||||||
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
2.3. "switch" statement
|
2.3. "switch" statement
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
switch (expr)
|
switch (expr) {
|
||||||
{
|
|
||||||
case 0:
|
case 0:
|
||||||
|
|
||||||
something;
|
something;
|
||||||
@ -109,44 +136,35 @@ that begins the block. Contents of the brace should be indented by 1 tab.
|
|||||||
something_else;
|
something_else;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2: {
|
||||||
{
|
|
||||||
int var = 42;
|
int var = 42;
|
||||||
another_thing;
|
another_thing;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
2.4. Single instruction
|
2.4. Single instruction
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Omit braces around simple single-statement body:
|
Don't omit braces around simple single-statement body:
|
||||||
|
|
||||||
if (...)
|
if (...) {
|
||||||
something;
|
something;
|
||||||
|
}
|
||||||
|
|
||||||
and not:
|
and not:
|
||||||
|
|
||||||
if (...)
|
if (...)
|
||||||
{
|
|
||||||
something;
|
something;
|
||||||
}
|
|
||||||
|
|
||||||
Except when body spans over multiple lines:
|
|
||||||
|
|
||||||
if (...)
|
|
||||||
{
|
|
||||||
something_too_long_for(
|
|
||||||
a_single_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
2.5. Line length
|
2.5. Line length
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Each line of text should not exceed 80 characters.
|
If possible, each line of text should not exceed 100 characters, except if
|
||||||
|
manual line wrapping breaks code clarity.
|
||||||
|
|
||||||
Exception: if a comment line contains an example command or a literal URL
|
Exception: if a comment line contains an example command or a literal URL
|
||||||
longer than 100 characters, that line may be longer than 100 characters
|
longer than 100 characters, that line may be longer than 100 characters
|
||||||
@ -290,8 +308,8 @@ Where ever possible, place comments above the code instead of beside it.
|
|||||||
Comments can be placed at the end of a line when one or more spaces follow.
|
Comments can be placed at the end of a line when one or more spaces follow.
|
||||||
Tabs should NOT be used to indent at the end of a line:
|
Tabs should NOT be used to indent at the end of a line:
|
||||||
|
|
||||||
class myClass
|
class myClass {
|
||||||
{
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int m_member1; // first member
|
int m_member1; // first member
|
||||||
@ -322,8 +340,8 @@ the purpose of the functions/classes and the meaning of the parameters.
|
|||||||
|
|
||||||
* No more than one class per file (except for inner classes).
|
* No more than one class per file (except for inner classes).
|
||||||
|
|
||||||
* Put the inclusion for the class's header file as the first inclusion in
|
* Put the #include for the class's header file first in the implementation
|
||||||
the implementation file.
|
file.
|
||||||
|
|
||||||
* Put the copyright header at the top of each file.
|
* Put the copyright header at the top of each file.
|
||||||
|
|
||||||
|
1
cmake/cmake-cxx11/.gitignore
vendored
1
cmake/cmake-cxx11/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
build
|
|
@ -1,7 +0,0 @@
|
|||||||
These things need to be changed when this module is merged into CMake:
|
|
||||||
|
|
||||||
-change include(CheckCXXCompilerFlag) in CheckCXX11Features.cmake to
|
|
||||||
include(${CMAKE_CURRENT_LIST_DIR}/CheckCXXCompilerFlag.cmake)
|
|
||||||
-remove the setting of CMAKE_MODULE_PATH from the testcase CMakeLists.txt
|
|
||||||
-change all tabs to spaces in the cpp files
|
|
||||||
|
|
@ -1,142 +0,0 @@
|
|||||||
# - Check which parts of the C++11 standard the compiler supports
|
|
||||||
#
|
|
||||||
# When found it will set the following variables
|
|
||||||
#
|
|
||||||
# CXX11_COMPILER_FLAGS - the compiler flags needed to get C++11 features
|
|
||||||
#
|
|
||||||
# HAS_CXX11_AUTO - auto keyword
|
|
||||||
# HAS_CXX11_AUTO_RET_TYPE - function declaration with deduced return types
|
|
||||||
# HAS_CXX11_CLASS_OVERRIDE - override and final keywords for classes and methods
|
|
||||||
# HAS_CXX11_CONSTEXPR - constexpr keyword
|
|
||||||
# HAS_CXX11_CSTDINT_H - cstdint header
|
|
||||||
# HAS_CXX11_DECLTYPE - decltype keyword
|
|
||||||
# HAS_CXX11_FUNC - __func__ preprocessor constant
|
|
||||||
# HAS_CXX11_INITIALIZER_LIST - initializer list
|
|
||||||
# HAS_CXX11_LAMBDA - lambdas
|
|
||||||
# HAS_CXX11_LIB_REGEX - regex library
|
|
||||||
# HAS_CXX11_LONG_LONG - long long signed & unsigned types
|
|
||||||
# HAS_CXX11_NULLPTR - nullptr
|
|
||||||
# HAS_CXX11_RVALUE_REFERENCES - rvalue references
|
|
||||||
# HAS_CXX11_SIZEOF_MEMBER - sizeof() non-static members
|
|
||||||
# HAS_CXX11_STATIC_ASSERT - static_assert()
|
|
||||||
# HAS_CXX11_VARIADIC_TEMPLATES - variadic templates
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright 2011,2012 Rolf Eike Beer <eike@sf-mail.de>
|
|
||||||
# Copyright 2012 Andreas Weis
|
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License");
|
|
||||||
# see accompanying file Copyright.txt for details.
|
|
||||||
#
|
|
||||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
||||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the License for more information.
|
|
||||||
#=============================================================================
|
|
||||||
# (To distribute this file outside of CMake, substitute the full
|
|
||||||
# License text for the above reference.)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Each feature may have up to 3 checks, every one of them in it's own file
|
|
||||||
# FEATURE.cpp - example that must build and return 0 when run
|
|
||||||
# FEATURE_fail.cpp - example that must build, but may not return 0 when run
|
|
||||||
# FEATURE_fail_compile.cpp - example that must fail compilation
|
|
||||||
#
|
|
||||||
# The first one is mandatory, the latter 2 are optional and do not depend on
|
|
||||||
# each other (i.e. only one may be present).
|
|
||||||
#
|
|
||||||
|
|
||||||
if (NOT CMAKE_CXX_COMPILER_LOADED)
|
|
||||||
message(FATAL_ERROR "CheckCXX11Features modules only works if language CXX is enabled")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8.3)
|
|
||||||
|
|
||||||
#
|
|
||||||
### Check for needed compiler flags
|
|
||||||
#
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
check_cxx_compiler_flag("-std=c++11" _HAS_CXX11_FLAG)
|
|
||||||
if (NOT _HAS_CXX11_FLAG)
|
|
||||||
check_cxx_compiler_flag("-std=c++0x" _HAS_CXX0X_FLAG)
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
if (_HAS_CXX11_FLAG)
|
|
||||||
set(CXX11_COMPILER_FLAGS "-std=c++11")
|
|
||||||
elseif (_HAS_CXX0X_FLAG)
|
|
||||||
set(CXX11_COMPILER_FLAGS "-std=c++0x")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
|
||||||
if (NOT DEFINED ${RESULT_VAR})
|
|
||||||
set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx11_${FEATURE_NAME}")
|
|
||||||
|
|
||||||
set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/CheckCXX11Features/cxx11-test-${FEATURE_NAME})
|
|
||||||
set(_LOG_NAME "\"${FEATURE_NAME}\"")
|
|
||||||
message(STATUS "Checking C++11 support for ${_LOG_NAME}")
|
|
||||||
|
|
||||||
set(_SRCFILE "${_SRCFILE_BASE}.cpp")
|
|
||||||
set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
|
|
||||||
set(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
|
|
||||||
|
|
||||||
if (CMAKE_CROSSCOMPILING)
|
|
||||||
try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}"
|
|
||||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
|
||||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}"
|
|
||||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
|
||||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
else (CMAKE_CROSSCOMPILING)
|
|
||||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
|
||||||
"${_bindir}" "${_SRCFILE}"
|
|
||||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
|
||||||
if (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
|
||||||
set(${RESULT_VAR} TRUE)
|
|
||||||
else (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
|
||||||
set(${RESULT_VAR} FALSE)
|
|
||||||
endif (_COMPILE_RESULT_VAR AND NOT _RUN_RESULT_VAR)
|
|
||||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
|
||||||
"${_bindir}_fail" "${_SRCFILE_FAIL}"
|
|
||||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
|
||||||
if (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
|
||||||
set(${RESULT_VAR} TRUE)
|
|
||||||
else (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
|
||||||
set(${RESULT_VAR} FALSE)
|
|
||||||
endif (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
|
||||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
|
||||||
endif (CMAKE_CROSSCOMPILING)
|
|
||||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
|
||||||
try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}"
|
|
||||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
|
||||||
if (_TMP_RESULT)
|
|
||||||
set(${RESULT_VAR} FALSE)
|
|
||||||
else (_TMP_RESULT)
|
|
||||||
set(${RESULT_VAR} TRUE)
|
|
||||||
endif (_TMP_RESULT)
|
|
||||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
|
||||||
|
|
||||||
if (${RESULT_VAR})
|
|
||||||
message(STATUS "Checking C++11 support for ${_LOG_NAME}: works")
|
|
||||||
else (${RESULT_VAR})
|
|
||||||
message(STATUS "Checking C++11 support for ${_LOG_NAME}: not supported")
|
|
||||||
endif (${RESULT_VAR})
|
|
||||||
set(${RESULT_VAR} ${${RESULT_VAR}} CACHE INTERNAL "C++11 support for ${_LOG_NAME}")
|
|
||||||
endif (NOT DEFINED ${RESULT_VAR})
|
|
||||||
endfunction(cxx11_check_feature)
|
|
||||||
|
|
||||||
cxx11_check_feature("__func__" HAS_CXX11_FUNC)
|
|
||||||
cxx11_check_feature("auto" HAS_CXX11_AUTO)
|
|
||||||
cxx11_check_feature("auto_ret_type" HAS_CXX11_AUTO_RET_TYPE)
|
|
||||||
cxx11_check_feature("class_override_final" HAS_CXX11_CLASS_OVERRIDE)
|
|
||||||
cxx11_check_feature("constexpr" HAS_CXX11_CONSTEXPR)
|
|
||||||
cxx11_check_feature("cstdint" HAS_CXX11_CSTDINT_H)
|
|
||||||
cxx11_check_feature("decltype" HAS_CXX11_DECLTYPE)
|
|
||||||
cxx11_check_feature("initializer_list" HAS_CXX11_INITIALIZER_LIST)
|
|
||||||
cxx11_check_feature("lambda" HAS_CXX11_LAMBDA)
|
|
||||||
cxx11_check_feature("long_long" HAS_CXX11_LONG_LONG)
|
|
||||||
cxx11_check_feature("nullptr" HAS_CXX11_NULLPTR)
|
|
||||||
cxx11_check_feature("regex" HAS_CXX11_LIB_REGEX)
|
|
||||||
cxx11_check_feature("rvalue-references" HAS_CXX11_RVALUE_REFERENCES)
|
|
||||||
cxx11_check_feature("sizeof_member" HAS_CXX11_SIZEOF_MEMBER)
|
|
||||||
cxx11_check_feature("static_assert" HAS_CXX11_STATIC_ASSERT)
|
|
||||||
cxx11_check_feature("variadic_templates" HAS_CXX11_VARIADIC_TEMPLATES)
|
|
@ -1,8 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
if (!__func__)
|
|
||||||
return 1;
|
|
||||||
if (!(*__func__))
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
auto i = 5;
|
|
||||||
auto f = 3.14159f;
|
|
||||||
auto d = 3.14159;
|
|
||||||
bool ret = (
|
|
||||||
(sizeof(f) < sizeof(d)) &&
|
|
||||||
(sizeof(i) == sizeof(int))
|
|
||||||
);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
// must fail because there is no initializer
|
|
||||||
auto i;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
auto foo(int i) -> int {
|
|
||||||
return i - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
return foo(1);
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
class base {
|
|
||||||
public:
|
|
||||||
virtual int foo(int a)
|
|
||||||
{ return 4 + a; }
|
|
||||||
int bar(int a) final
|
|
||||||
{ return a - 2; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class sub final : public base {
|
|
||||||
public:
|
|
||||||
virtual int foo(int a) override
|
|
||||||
{ return 8 + 2 * a; };
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
base b;
|
|
||||||
sub s;
|
|
||||||
|
|
||||||
return (b.foo(2) * 2 == s.foo(2)) ? 0 : 1;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
class base {
|
|
||||||
public:
|
|
||||||
virtual int foo(int a)
|
|
||||||
{ return 4 + a; }
|
|
||||||
virtual int bar(int a) final
|
|
||||||
{ return a - 2; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class sub final : public base {
|
|
||||||
public:
|
|
||||||
virtual int foo(int a) override
|
|
||||||
{ return 8 + 2 * a; };
|
|
||||||
virtual int bar(int a)
|
|
||||||
{ return a; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class impossible : public sub { };
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
base b;
|
|
||||||
sub s;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
constexpr int square(int x)
|
|
||||||
{
|
|
||||||
return x*x;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int the_answer()
|
|
||||||
{
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int test_arr[square(3)];
|
|
||||||
bool ret = (
|
|
||||||
(square(the_answer()) == 1764) &&
|
|
||||||
(sizeof(test_arr)/sizeof(test_arr[0]) == 9)
|
|
||||||
);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
#include <cstdint>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool test =
|
|
||||||
(sizeof(int8_t) == 1) &&
|
|
||||||
(sizeof(int16_t) == 2) &&
|
|
||||||
(sizeof(int32_t) == 4) &&
|
|
||||||
(sizeof(int64_t) == 8);
|
|
||||||
return test ? 0 : 1;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
bool check_size(int i)
|
|
||||||
{
|
|
||||||
return sizeof(int) == sizeof(decltype(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool ret = check_size(42);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
#include <vector>
|
|
||||||
|
|
||||||
class seq {
|
|
||||||
public:
|
|
||||||
seq(std::initializer_list<int> list);
|
|
||||||
|
|
||||||
int length() const;
|
|
||||||
private:
|
|
||||||
std::vector<int> m_v;
|
|
||||||
};
|
|
||||||
|
|
||||||
seq::seq(std::initializer_list<int> list)
|
|
||||||
: m_v(list)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int seq::length() const
|
|
||||||
{
|
|
||||||
return m_v.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
seq a = {18, 20, 2, 0, 4, 7};
|
|
||||||
|
|
||||||
return (a.length() == 6) ? 0 : 1;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
int main()
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
return ([&ret]() -> int { return ret; })();
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
long long l;
|
|
||||||
unsigned long long ul;
|
|
||||||
|
|
||||||
return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
void *v = nullptr;
|
|
||||||
|
|
||||||
return v ? 1 : 0;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
int i = nullptr;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#include <algorithm>
|
|
||||||
#include <regex>
|
|
||||||
|
|
||||||
int parse_line(std::string const& line)
|
|
||||||
{
|
|
||||||
std::string tmp;
|
|
||||||
if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+//(-)?(\\d)+(\\s)+"))) {
|
|
||||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+//(-)?(\\d)+"), std::string("V"));
|
|
||||||
} else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) {
|
|
||||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+"), std::string("V"));
|
|
||||||
} else if(std::regex_search(line, std::regex("(\\s)+(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+(\\s)+"))) {
|
|
||||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+/(-)?(\\d)+/(-)?(\\d)+"), std::string("V"));
|
|
||||||
} else {
|
|
||||||
tmp = std::regex_replace(line, std::regex("(-)?(\\d)+"), std::string("V"));
|
|
||||||
}
|
|
||||||
return static_cast<int>(std::count(tmp.begin(), tmp.end(), 'V'));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
bool test = (parse_line("f 7/7/7 -3/3/-3 2/-2/2") == 3) &&
|
|
||||||
(parse_line("f 7//7 3//-3 -2//2") == 3) &&
|
|
||||||
(parse_line("f 7/7 3/-3 -2/2") == 3) &&
|
|
||||||
(parse_line("f 7 3 -2") == 3);
|
|
||||||
return test ? 0 : 1;
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
#include <cassert>
|
|
||||||
|
|
||||||
class rvmove {
|
|
||||||
public:
|
|
||||||
void *ptr;
|
|
||||||
char *array;
|
|
||||||
|
|
||||||
rvmove()
|
|
||||||
: ptr(0),
|
|
||||||
array(new char[10])
|
|
||||||
{
|
|
||||||
ptr = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
rvmove(rvmove &&other)
|
|
||||||
: ptr(other.ptr),
|
|
||||||
array(other.array)
|
|
||||||
{
|
|
||||||
other.array = 0;
|
|
||||||
other.ptr = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
~rvmove()
|
|
||||||
{
|
|
||||||
assert(((ptr != 0) && (array != 0)) || ((ptr == 0) && (array == 0)));
|
|
||||||
delete[] array;
|
|
||||||
}
|
|
||||||
|
|
||||||
rvmove &operator=(rvmove &&other)
|
|
||||||
{
|
|
||||||
delete[] array;
|
|
||||||
ptr = other.ptr;
|
|
||||||
array = other.array;
|
|
||||||
other.array = 0;
|
|
||||||
other.ptr = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rvmove create()
|
|
||||||
{
|
|
||||||
return rvmove();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
rvmove(const rvmove &);
|
|
||||||
rvmove &operator=(const rvmove &);
|
|
||||||
};
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
rvmove mine;
|
|
||||||
if (mine.ptr != &mine)
|
|
||||||
return 1;
|
|
||||||
mine = rvmove::create();
|
|
||||||
if (mine.ptr == &mine)
|
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
struct foo {
|
|
||||||
char bar;
|
|
||||||
int baz;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
bool ret = (
|
|
||||||
(sizeof(foo::bar) == 1) &&
|
|
||||||
(sizeof(foo::baz) >= sizeof(foo::bar)) &&
|
|
||||||
(sizeof(foo) >= sizeof(foo::bar) + sizeof(foo::baz))
|
|
||||||
);
|
|
||||||
return ret ? 0 : 1;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
struct foo {
|
|
||||||
int baz;
|
|
||||||
double bar;
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
return (sizeof(foo::bar) == 4) ? 0 : 1;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
static_assert(0 < 1, "your ordering of integers is screwed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
int main(void)
|
|
||||||
{
|
|
||||||
static_assert(1 < 0, "your ordering of integers is screwed");
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
int Accumulate()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename... Ts>
|
|
||||||
int Accumulate(T v, Ts... vs)
|
|
||||||
{
|
|
||||||
return v + Accumulate(vs...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int... Is>
|
|
||||||
int CountElements()
|
|
||||||
{
|
|
||||||
return sizeof...(Is);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
int acc = Accumulate(1, 2, 3, 4, -5);
|
|
||||||
int count = CountElements<1,2,3,4,5>();
|
|
||||||
return ((acc == 5) && (count == 5)) ? 0 : 1;
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
|
|
||||||
project(Cxx11Features CXX)
|
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../Modules")
|
|
||||||
|
|
||||||
include(CheckCXX11Features)
|
|
||||||
|
|
||||||
foreach (flag IN ITEMS
|
|
||||||
HAS_CXX11_AUTO
|
|
||||||
HAS_CXX11_AUTO_RET_TYPE
|
|
||||||
HAS_CXX11_CLASS_OVERRIDE
|
|
||||||
HAS_CXX11_CONSTEXPR
|
|
||||||
HAS_CXX11_CSTDINT_H
|
|
||||||
HAS_CXX11_DECLTYPE
|
|
||||||
HAS_CXX11_FUNC
|
|
||||||
HAS_CXX11_INITIALIZER_LIST
|
|
||||||
HAS_CXX11_LAMBDA
|
|
||||||
HAS_CXX11_LIB_REGEX
|
|
||||||
HAS_CXX11_LONG_LONG
|
|
||||||
HAS_CXX11_NULLPTR
|
|
||||||
HAS_CXX11_RVALUE_REFERENCES
|
|
||||||
HAS_CXX11_SIZEOF_MEMBER
|
|
||||||
HAS_CXX11_STATIC_ASSERT
|
|
||||||
HAS_CXX11_VARIADIC_TEMPLATES
|
|
||||||
)
|
|
||||||
if (${flag})
|
|
||||||
add_definitions("-D${flag}")
|
|
||||||
message(STATUS "Compiler C++11 support flag ${flag} set")
|
|
||||||
endif ()
|
|
||||||
endforeach (flag)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${CXX11_COMPILER_FLAGS})
|
|
||||||
add_executable(CXX11Features cxx11features.cxx)
|
|
@ -1,57 +0,0 @@
|
|||||||
#if defined(HAS_CXX0X_CSTDINT_H)
|
|
||||||
#include <cstdint>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
struct thing {
|
|
||||||
unsigned char one;
|
|
||||||
#if defined(HAS_CXX0X_CSTDINT_H)
|
|
||||||
uint32_t four;
|
|
||||||
#endif
|
|
||||||
#if defined(HAS_CXX0X_LONG_LONG)
|
|
||||||
long long eight;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
#if defined (HAS_CXX0X_NULLPTR)
|
|
||||||
void *nix = nullptr;
|
|
||||||
#else /* HAS_CXX0X_NULLPTR */
|
|
||||||
void *nix = 0;
|
|
||||||
#endif /* HAS_CXX0X_NULLPTR */
|
|
||||||
|
|
||||||
#if defined(HAS_CXX0X_STATIC_ASSERT)
|
|
||||||
static_assert(1 < 42, "Your C++ compiler is b0rked");
|
|
||||||
#endif /* HAS_CXX0X_STATIC_ASSERT */
|
|
||||||
|
|
||||||
#if defined(HAS_CXX0X_FUNC)
|
|
||||||
const char *funcname = __func__;
|
|
||||||
printf("the name of main() function is: %s\n", funcname);
|
|
||||||
#endif /* HAS_CXX0X_FUNC */
|
|
||||||
|
|
||||||
#if defined(HAS_CXX0X_SIZEOF_MEMBER)
|
|
||||||
size_t onesize = sizeof(thing::one);
|
|
||||||
#if defined(HAS_CXX0X_STATIC_ASSERT)
|
|
||||||
static_assert(sizeof(thing::one) == 1, "Your char is not one byte long");
|
|
||||||
#endif /* HAS_CXX0X_STATIC_ASSERT */
|
|
||||||
|
|
||||||
#if defined(HAS_CXX0X_CSTDINT_H)
|
|
||||||
size_t foursize = sizeof(thing::four);
|
|
||||||
#if defined(HAS_CXX0X_STATIC_ASSERT)
|
|
||||||
static_assert(sizeof(thing::four) == 4, "Your uint32_t is not 32 bit long");
|
|
||||||
#endif /* HAS_CXX0X_STATIC_ASSERT */
|
|
||||||
#endif /* HAS_CXX0X_CSTDINT_H */
|
|
||||||
#if defined(HAS_CXX0X_LONG_LONG)
|
|
||||||
size_t eightsize = sizeof(thing::eight);
|
|
||||||
#if defined(HAS_CXX0X_STATIC_ASSERT)
|
|
||||||
static_assert(sizeof(thing::eight) == 8, "Your long long is not 64 bit long");
|
|
||||||
#endif /* HAS_CXX0X_STATIC_ASSERT */
|
|
||||||
#endif /* HAS_CXX0X_LONG_LONG */
|
|
||||||
#endif /* HAS_CXX0X_SIZEOF_MEMBER */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -46,17 +46,17 @@ use the function {\vcode vmime::make\_shared} instead of the {\vcode new}
|
|||||||
operator.
|
operator.
|
||||||
|
|
||||||
\begin{lstlisting}[caption={Smarts pointers and creating objects}]
|
\begin{lstlisting}[caption={Smarts pointers and creating objects}]
|
||||||
class myObject : public vmime::object
|
class myObject : public vmime::object {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
myObject(const vmime::string& name)
|
myObject(const vmime::string& name)
|
||||||
: m_name(name)
|
: m_name(name) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sayHello()
|
void sayHello() {
|
||||||
{
|
|
||||||
std::cout << "Hello " << m_name << std::endl;
|
std::cout << "Hello " << m_name << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,8 +65,8 @@ private:
|
|||||||
vmime::string m_name;
|
vmime::string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
vmime::shared_ptr <myObject> obj =
|
vmime::shared_ptr <myObject> obj =
|
||||||
vmime::make_shared <myObject>("world");
|
vmime::make_shared <myObject>("world");
|
||||||
|
|
||||||
@ -105,12 +105,12 @@ directly or indirectly to itself). The following example illustrates a
|
|||||||
typical problem of reference counting:
|
typical problem of reference counting:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
class parent : public vmime::object
|
class parent : public vmime::object {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void createChild(vmime::shared_ptr <child> c)
|
void createChild(vmime::shared_ptr <child> c) {
|
||||||
{
|
|
||||||
m_child = c;
|
m_child = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,13 +119,13 @@ private:
|
|||||||
vmime::shared_ptr <child> m_child;
|
vmime::shared_ptr <child> m_child;
|
||||||
};
|
};
|
||||||
|
|
||||||
class child : public vmime::object
|
class child : public vmime::object {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
child(vmime::shared_ptr <parent> p)
|
child(vmime::shared_ptr <parent> p)
|
||||||
: m_parent(p)
|
: m_parent(p) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -133,8 +133,8 @@ private:
|
|||||||
vmime::shared_ptr <parent> m_parent;
|
vmime::shared_ptr <parent> m_parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
vmime::shared_ptr <parent> p = vmime::make_shared <parent>();
|
vmime::shared_ptr <parent> p = vmime::make_shared <parent>();
|
||||||
vmime::shared_ptr <child> c = vmime::make_shared <child>();
|
vmime::shared_ptr <child> c = vmime::make_shared <child>();
|
||||||
|
|
||||||
@ -179,30 +179,31 @@ Following is an example code for catching VMime exceptions and writing error
|
|||||||
messages to the console:
|
messages to the console:
|
||||||
|
|
||||||
\begin{lstlisting}[caption={Catching VMime exceptions}]
|
\begin{lstlisting}[caption={Catching VMime exceptions}]
|
||||||
std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
std::ostream& operator<<(std::ostream& os, const vmime::exception& e) {
|
||||||
{
|
|
||||||
os << "* vmime::exceptions::" << e.name() << std::endl;
|
os << "* vmime::exceptions::" << e.name() << std::endl;
|
||||||
os << " what = " << e.what() << std::endl;
|
os << " what = " << e.what() << std::endl;
|
||||||
|
|
||||||
// Recursively print all encapsuled exceptions
|
// Recursively print all encapsuled exceptions
|
||||||
if (e.other() != NULL)
|
if (e.other() != NULL) {
|
||||||
os << *e.other();
|
os << *e.other();
|
||||||
|
}
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// ...some call to VMime...
|
// ...some call to VMime...
|
||||||
}
|
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << e; // VMime exception
|
std::cerr << e; // VMime exception
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << e.what(); // standard exception
|
std::cerr << e.what(); // standard exception
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
@ -250,7 +251,8 @@ vmime::datetime d1("Sat, 08 Oct 2005 14:07:52 +0200");
|
|||||||
vmime::datetime d2(
|
vmime::datetime d2(
|
||||||
/* date */ 2005, vmime::datetime::OCTOBER, 8,
|
/* date */ 2005, vmime::datetime::OCTOBER, 8,
|
||||||
/* time */ 14, 7, 52,
|
/* time */ 14, 7, 52,
|
||||||
/* zone */ vmime::datetime::GMT2);
|
/* zone */ vmime::datetime::GMT2
|
||||||
|
);
|
||||||
|
|
||||||
// Getting day of week
|
// Getting day of week
|
||||||
const int dow = d2.getWeekDay(); // 'dow' should be datetime::SATURDAY
|
const int dow = d2.getWeekDay(); // 'dow' should be datetime::SATURDAY
|
||||||
@ -275,7 +277,8 @@ media type with:
|
|||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
vmime::mediaType theType(
|
vmime::mediaType theType(
|
||||||
/* top-level type */ vmime::mediaTypes::IMAGE,
|
/* top-level type */ vmime::mediaTypes::IMAGE,
|
||||||
/* sub-type */ vmime::mediaTypes::IMAGE_JPEG);
|
/* sub-type */ vmime::mediaTypes::IMAGE_JPEG
|
||||||
|
);
|
||||||
|
|
||||||
// theType.getType() is "image"
|
// theType.getType() is "image"
|
||||||
// theType.getSubType() is "jpeg"
|
// theType.getSubType() is "jpeg"
|
||||||
@ -594,8 +597,9 @@ std::ifstream* fileStream = new std::ifstream();
|
|||||||
|
|
||||||
fileStream->open("/home/vincent/paris.jpg", std::ios::binary);
|
fileStream->open("/home/vincent/paris.jpg", std::ios::binary);
|
||||||
|
|
||||||
if (!*fileStream)
|
if (!*fileStream) {
|
||||||
// handle error
|
// handle error
|
||||||
|
}
|
||||||
|
|
||||||
vmime::shared_ptr <utility::stream> dataStream =
|
vmime::shared_ptr <utility::stream> dataStream =
|
||||||
vmime::make_shared <vmime::utility::inputStreamPointerAdapter>(fileStream);
|
vmime::make_shared <vmime::utility::inputStreamPointerAdapter>(fileStream);
|
||||||
@ -608,13 +612,12 @@ vmime::shared_ptr <contentHandler> data =
|
|||||||
vmime::make_shared <vmime::streamContentHandler>(dataStream, 0);
|
vmime::make_shared <vmime::streamContentHandler>(dataStream, 0);
|
||||||
|
|
||||||
// Now create the attachment
|
// Now create the attachment
|
||||||
ref <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>
|
ref <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>(
|
||||||
(
|
|
||||||
/* attachment data */ data,
|
/* attachment data */ data,
|
||||||
/* content type */ vmime::mediaType("image/jpeg"),
|
/* content type */ vmime::mediaType("image/jpeg"),
|
||||||
/* description */ vmime::text("Holiday photo"),
|
/* description */ vmime::text("Holiday photo"),
|
||||||
/* filename */ vmime::word("paris.jpg")
|
/* filename */ vmime::word("paris.jpg")
|
||||||
);
|
);
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
You will see later that the {\vcode vmime::fileAttachment} class already
|
You will see later that the {\vcode vmime::fileAttachment} class already
|
||||||
@ -647,10 +650,11 @@ vmime::shared_ptr <const vmime::contentHandler> cth = body->getContents();
|
|||||||
|
|
||||||
// Then, extract and convert the contents
|
// Then, extract and convert the contents
|
||||||
vmime::utility::outputStreamAdapter out(std::cout);
|
vmime::utility::outputStreamAdapter out(std::cout);
|
||||||
vmime::utility::charsetFilteredOutputStream fout
|
vmime::utility::charsetFilteredOutputStream fout(
|
||||||
(/* source charset */ body->getCharset(),
|
/* source charset */ body->getCharset(),
|
||||||
/* dest charset */ vmime::charset("utf-8"),
|
/* dest charset */ vmime::charset("utf-8"),
|
||||||
/* dest stream */ out);
|
/* dest stream */ out
|
||||||
|
);
|
||||||
|
|
||||||
cth->extract(fout);
|
cth->extract(fout);
|
||||||
|
|
||||||
@ -778,8 +782,8 @@ vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
|
|||||||
|
|
||||||
std::cout << "Available encoders:" << std::endl;
|
std::cout << "Available encoders:" << std::endl;
|
||||||
|
|
||||||
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
|
for (int i = 0 ; i < ef->getEncoderCount() ; ++i) {
|
||||||
{
|
|
||||||
// Output encoder name
|
// Output encoder name
|
||||||
vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
|
vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
|
||||||
enc = ef->getEncoderAt(i);
|
enc = ef->getEncoderAt(i);
|
||||||
@ -792,8 +796,9 @@ for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
|
|||||||
std::vector <vmime::string> props = e->getAvailableProperties();
|
std::vector <vmime::string> props = e->getAvailableProperties();
|
||||||
std::vector <vmime::string>::const_iterator it;
|
std::vector <vmime::string>::const_iterator it;
|
||||||
|
|
||||||
for (it = props.begin() ; it != props.end() ; ++it)
|
for (it = props.begin() ; it != props.end() ; ++it) {
|
||||||
std::cout << " - " << *it << std::endl;
|
std::cout << " - " << *it << std::endl;
|
||||||
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@ want SASL\footnote{Simple Authentication and Security Layer} support ;
|
|||||||
\item either the \href{http://www.openssl.org}{OpenSSL library} or the
|
\item either the \href{http://www.openssl.org}{OpenSSL library} or the
|
||||||
\href{http://www.gnu.org/software/gnutls/}{GNU TLS Library} if you
|
\href{http://www.gnu.org/software/gnutls/}{GNU TLS Library} if you
|
||||||
want SSL and TLS\footnote{Transport Layer Security} support ;
|
want SSL and TLS\footnote{Transport Layer Security} support ;
|
||||||
\item the \href{http://www.boost.org}{Boost C++ library} if you are not using
|
|
||||||
C++11 (or your compiler does not support it), for {\vcode shared\_ptr<>}.
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
% ============================================================================
|
% ============================================================================
|
||||||
|
@ -55,7 +55,7 @@ General Public License\footnote{See Appendix \ref{appendix_license} and
|
|||||||
\url{http://www.gnu.org/copyleft/gpl.html}} (GPL) version 3:
|
\url{http://www.gnu.org/copyleft/gpl.html}} (GPL) version 3:
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
Copyright (C) 2002-2013 Vincent Richard
|
Copyright (C) 2002 Vincent Richard
|
||||||
|
|
||||||
VMime library is free software; you can redistribute it and/or
|
VMime library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License as
|
modify it under the terms of the GNU General Public License as
|
||||||
@ -79,7 +79,7 @@ GNU Free Documentation
|
|||||||
License\footnote{See \url{http://www.gnu.org/copyleft/fdl.html}} (FDL):
|
License\footnote{See \url{http://www.gnu.org/copyleft/fdl.html}} (FDL):
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
Copyright (C) 2004-2013 Vincent Richard
|
Copyright (C) 2004 Vincent Richard
|
||||||
|
|
||||||
Permission is granted to copy, distribute and/or modify
|
Permission is granted to copy, distribute and/or modify
|
||||||
this document under the terms of the GNU Free Documentation
|
this document under the terms of the GNU Free Documentation
|
||||||
|
119
doc/book/msg.tex
119
doc/book/msg.tex
@ -94,8 +94,8 @@ vmime::messageParser mp(msg);
|
|||||||
std::cout << "Message has " << mp.getAttachmentCount()
|
std::cout << "Message has " << mp.getAttachmentCount()
|
||||||
<< " attachment(s)" << std::endl;
|
<< " attachment(s)" << std::endl;
|
||||||
|
|
||||||
for (int i = 0 ; i < mp.getAttachmentCount() ; ++i)
|
for (int i = 0 ; i < mp.getAttachmentCount() ; ++i) {
|
||||||
{
|
|
||||||
vmime::shared_ptr <const vmime::attachment> att = mp.getAttachmentAt(i);
|
vmime::shared_ptr <const vmime::attachment> att = mp.getAttachmentAt(i);
|
||||||
std::cout << " - " << att->getType().generate() << std::endl;
|
std::cout << " - " << att->getType().generate() << std::endl;
|
||||||
}
|
}
|
||||||
@ -104,13 +104,13 @@ for (int i = 0 ; i < mp.getAttachmentCount() ; ++i)
|
|||||||
std::cout << "Message has " << mp.getTextPartCount()
|
std::cout << "Message has " << mp.getTextPartCount()
|
||||||
<< " text part(s)" << std::endl;
|
<< " text part(s)" << std::endl;
|
||||||
|
|
||||||
for (int i = 0 ; i < mp.getTextPartCount() ; ++i)
|
for (int i = 0 ; i < mp.getTextPartCount() ; ++i) {
|
||||||
{
|
|
||||||
vmime::shared_ptr <const vmime::textPart> tp = mp.getTextPartAt(i);
|
vmime::shared_ptr <const vmime::textPart> tp = mp.getTextPartAt(i);
|
||||||
|
|
||||||
// text/html
|
// text/html
|
||||||
if (tp->getType().getSubType() == vmime::mediaTypes::TEXT_HTML)
|
if (tp->getType().getSubType() == vmime::mediaTypes::TEXT_HTML) {
|
||||||
{
|
|
||||||
vmime::shared_ptr <const vmime::htmlTextPart> htp =
|
vmime::shared_ptr <const vmime::htmlTextPart> htp =
|
||||||
vmime::dynamicCast <const vmime::htmlTextPart>(tp);
|
vmime::dynamicCast <const vmime::htmlTextPart>(tp);
|
||||||
|
|
||||||
@ -118,18 +118,18 @@ for (int i = 0 ; i < mp.getTextPartCount() ; ++i)
|
|||||||
// Plain text is in tp->getPlainText()
|
// Plain text is in tp->getPlainText()
|
||||||
|
|
||||||
// Enumerate embedded objects
|
// Enumerate embedded objects
|
||||||
for (int j = 0 ; j < htp->getObjectCount() ; ++j)
|
for (int j = 0 ; j < htp->getObjectCount() ; ++j) {
|
||||||
{
|
|
||||||
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj =
|
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj =
|
||||||
htp->getObjectAt(j);
|
htp->getObjectAt(j);
|
||||||
|
|
||||||
// Identifier (Content-Id or Content-Location) is obj->getId()
|
// Identifier (Content-Id or Content-Location) is obj->getId()
|
||||||
// Object data is in obj->getData()
|
// Object data is in obj->getData()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// text/plain or anything else
|
// text/plain or anything else
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Text is in tp->getText()
|
// Text is in tp->getText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,8 +172,7 @@ hdr->appendField(subjectField);
|
|||||||
vmime::shared_ptr <vmime::headerField> fromField =
|
vmime::shared_ptr <vmime::headerField> fromField =
|
||||||
hfFactory->create(vmime::fields::FROM);
|
hfFactory->create(vmime::fields::FROM);
|
||||||
|
|
||||||
fromField->setValue
|
fromField->setValue(vmime::make_shared <vmime::mailbox>("me@vmime.org"));
|
||||||
(vmime::make_shared <vmime::mailbox>("me@vmime.org"));
|
|
||||||
hdr->appendField(fromField);
|
hdr->appendField(fromField);
|
||||||
|
|
||||||
// Append a 'To:' field
|
// Append a 'To:' field
|
||||||
@ -190,8 +189,11 @@ toField->setValue(recipients);
|
|||||||
hdr->appendField(toField);
|
hdr->appendField(toField);
|
||||||
|
|
||||||
// Set the body contents
|
// Set the body contents
|
||||||
bdy->setContents(vmime::make_shared <vmime::stringContentHandler>
|
bdy->setContents(
|
||||||
("This is the text of your message..."));
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
|
"This is the text of your message..."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Output raw message data to standard output
|
// Output raw message data to standard output
|
||||||
vmime::utility::outputStreamAdapter out(std::cout);
|
vmime::utility::outputStreamAdapter out(std::cout);
|
||||||
@ -207,19 +209,23 @@ previous example, using the {\vcode vmime::messageBuilder} object:
|
|||||||
|
|
||||||
\begin{lstlisting}[caption={Building a simple message
|
\begin{lstlisting}[caption={Building a simple message
|
||||||
using {\vcode vmime::messageBuilder}}]
|
using {\vcode vmime::messageBuilder}}]
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
// Fill in some header fields and message body
|
// Fill in some header fields and message body
|
||||||
mb.setSubject(vmime::text("Message subject"));
|
mb.setSubject(vmime::text("Message subject"));
|
||||||
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
|
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
|
||||||
mb.getRecipients().appendAddress
|
mb.getRecipients().appendAddress(
|
||||||
(vmime::make_shared <vmime::mailbox>("you@vmime.org"));
|
vmime::make_shared <vmime::mailbox>("you@vmime.org")
|
||||||
|
);
|
||||||
|
|
||||||
mb.getTextPart()->setCharset(vmime::charsets::ISO8859_15);
|
mb.getTextPart()->setCharset(vmime::charsets::ISO8859_15);
|
||||||
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>
|
mb.getTextPart()->setText(
|
||||||
("This is the text of your message..."));
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
|
"This is the text of your message..."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Message construction
|
// Message construction
|
||||||
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
||||||
@ -227,15 +233,15 @@ try
|
|||||||
// Output raw message data to standard output
|
// Output raw message data to standard output
|
||||||
vmime::utility::outputStreamAdapter out(std::cout);
|
vmime::utility::outputStreamAdapter out(std::cout);
|
||||||
msg->generate(out);
|
msg->generate(out);
|
||||||
}
|
|
||||||
// VMime exception
|
// VMime exception
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << "vmime::exception: " << e.what() << std::endl;
|
std::cerr << "vmime::exception: " << e.what() << std::endl;
|
||||||
}
|
|
||||||
// Standard exception
|
// Standard exception
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << "std::exception: " << e.what() << std::endl;
|
std::cerr << "std::exception: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
@ -250,8 +256,7 @@ previous example to attach a file to the message:
|
|||||||
{\vcode vmime::messageBuilder}}]
|
{\vcode vmime::messageBuilder}}]
|
||||||
// Create an attachment
|
// Create an attachment
|
||||||
vmime::shared_ptr <vmime::fileAttachment> att =
|
vmime::shared_ptr <vmime::fileAttachment> att =
|
||||||
vmime::make_shared <vmime::fileAttachment>
|
vmime::make_shared <vmime::fileAttachment>(
|
||||||
(
|
|
||||||
/* full path to file */ "/home/vincent/paris.jpg",
|
/* full path to file */ "/home/vincent/paris.jpg",
|
||||||
/* content type */ vmime::mediaType("image/jpeg),
|
/* content type */ vmime::mediaType("image/jpeg),
|
||||||
/* description */ vmime::text("My holidays in Paris")
|
/* description */ vmime::text("My holidays in Paris")
|
||||||
@ -259,8 +264,9 @@ vmime::shared_ptr <vmime::fileAttachment> att =
|
|||||||
|
|
||||||
// You can also set some infos about the file
|
// You can also set some infos about the file
|
||||||
att->getFileInfo().setFilename("paris.jpg");
|
att->getFileInfo().setFilename("paris.jpg");
|
||||||
att->getFileInfo().setCreationDate
|
att->getFileInfo().setCreationDate(
|
||||||
(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
|
vmime::datetime("30 Apr 2003 14:30:00 +0200")
|
||||||
|
);
|
||||||
|
|
||||||
// Add this attachment to the message
|
// Add this attachment to the message
|
||||||
mb.appendAttachment(att);
|
mb.appendAttachment(att);
|
||||||
@ -283,14 +289,19 @@ using the {\vcode vmime::messageBuilder}}]
|
|||||||
// Fill in some header fields
|
// Fill in some header fields
|
||||||
mb.setSubject(vmime::text("An HTML message"));
|
mb.setSubject(vmime::text("An HTML message"));
|
||||||
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
|
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
|
||||||
mb.getRecipients().appendAddress
|
mb.getRecipients().appendAddress(
|
||||||
(vmime::make_shared <vmime::mailbox>("you@vmime.org"));
|
vmime::make_shared <vmime::mailbox>("you@vmime.org")
|
||||||
|
);
|
||||||
|
|
||||||
// Set the content-type to "text/html": a text part factory must be
|
// Set the content-type to "text/html": a text part factory must be
|
||||||
// available for the type you are using. The following code will make
|
// available for the type you are using. The following code will make
|
||||||
// the message builder construct the two text parts.
|
// the message builder construct the two text parts.
|
||||||
mb.constructTextPart(vmime::mediaType
|
mb.constructTextPart(
|
||||||
(vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML));
|
vmime::mediaType(
|
||||||
|
vmime::mediaTypes::TEXT,
|
||||||
|
vmime::mediaTypes::TEXT_HTML
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Set contents of the text parts; the message is available in two formats:
|
// Set contents of the text parts; the message is available in two formats:
|
||||||
// HTML and plain text. The HTML format also includes an embedded image.
|
// HTML and plain text. The HTML format also includes an embedded image.
|
||||||
@ -306,12 +317,18 @@ const vmime::string id = textPart->addObject("<...image data...>",
|
|||||||
// -- Set the text
|
// -- Set the text
|
||||||
textPart->setCharset(vmime::charsets::ISO8859_15);
|
textPart->setCharset(vmime::charsets::ISO8859_15);
|
||||||
|
|
||||||
textPart->setText(vmime::make_shared <vmime::stringContentHandler>
|
textPart->setText(
|
||||||
("This is the <b>HTML text</b>, and the image:<br/>"
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
"<img src=\"") + id + vmime::string("\"/>"));
|
"This is the <b>HTML text</b>, and the image:<br/>"
|
||||||
|
"<img src=\"") + id + vmime::string("\"/>"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
textPart->setPlainText(vmime::make_shared <vmime::stringContentHandler>
|
textPart->setPlainText(
|
||||||
("This is the plain text."));
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
|
"This is the plain text."
|
||||||
|
)
|
||||||
|
);
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
This will create a message having the following structure:
|
This will create a message having the following structure:
|
||||||
@ -336,11 +353,18 @@ vmime::shared_ptr <vmime::utility::file> imageFile =
|
|||||||
fs->create(fs->stringToPath("/path/to/image.jpg"));
|
fs->create(fs->stringToPath("/path/to/image.jpg"));
|
||||||
|
|
||||||
vmime::shared_ptr <vmime::contentHandler> imageCts =
|
vmime::shared_ptr <vmime::contentHandler> imageCts =
|
||||||
vmime::make_shared <vmime::streamContentHandler>
|
vmime::make_shared <vmime::streamContentHandler>(
|
||||||
(imageFile->getFileReader()->getInputStream(), imageFile->getLength());
|
imageFile->getFileReader()->getInputStream(),
|
||||||
|
imageFile->getLength()
|
||||||
|
);
|
||||||
|
|
||||||
const vmime::string cid = textPart.addObject(imageCts,
|
const vmime::string cid = textPart.addObject(
|
||||||
vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
|
imageCts,
|
||||||
|
vmime::mediaType(
|
||||||
|
vmime::mediaTypes::IMAGE,
|
||||||
|
vmime::mediaTypes::IMAGE_JPEG
|
||||||
|
)
|
||||||
|
);
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
@ -361,8 +385,8 @@ extract its contents to the standard output:
|
|||||||
\begin{lstlisting}[caption={Testing if a body part is an attachment}]
|
\begin{lstlisting}[caption={Testing if a body part is an attachment}]
|
||||||
vmime::shared_ptr <vmime::bodyPart> part; // suppose we have a body part
|
vmime::shared_ptr <vmime::bodyPart> part; // suppose we have a body part
|
||||||
|
|
||||||
if (vmime::attachmentHelper::isBodyPartAnAttachment(part))
|
if (vmime::attachmentHelper::isBodyPartAnAttachment(part)) {
|
||||||
{
|
|
||||||
// The body part contains an attachment, get it
|
// The body part contains an attachment, get it
|
||||||
vmime::shared_ptr <const vmime::attachment> attach =
|
vmime::shared_ptr <const vmime::attachment> attach =
|
||||||
attachmentHelper::getBodyPartAttachment(part);
|
attachmentHelper::getBodyPartAttachment(part);
|
||||||
@ -394,8 +418,7 @@ vmime::shared_ptr <vmime::message> msg; // suppose we have a message
|
|||||||
|
|
||||||
// Create an attachment
|
// Create an attachment
|
||||||
vmime::shared_ptr <vmime::fileAttachment> att =
|
vmime::shared_ptr <vmime::fileAttachment> att =
|
||||||
vmime::make_shared <vmime::fileAttachment>
|
vmime::make_shared <vmime::fileAttachment>(
|
||||||
(
|
|
||||||
/* full path to file */ "/home/vincent/paris.jpg",
|
/* full path to file */ "/home/vincent/paris.jpg",
|
||||||
/* content type */ vmime::mediaType("image/jpeg),
|
/* content type */ vmime::mediaType("image/jpeg),
|
||||||
/* description */ vmime::text("My holidays in Paris")
|
/* description */ vmime::text("My holidays in Paris")
|
||||||
|
235
doc/book/net.tex
235
doc/book/net.tex
@ -300,10 +300,10 @@ The following example shows how to use a custom authenticator to request
|
|||||||
the user to enter her/his credentials:
|
the user to enter her/his credentials:
|
||||||
|
|
||||||
\begin{lstlisting}[caption={A simple interactive authenticator}]
|
\begin{lstlisting}[caption={A simple interactive authenticator}]
|
||||||
class myAuthenticator : public vmime::security::defaultAuthenticator
|
class myAuthenticator : public vmime::security::defaultAuthenticator {
|
||||||
{
|
|
||||||
const string getUsername() const
|
const string getUsername() const {
|
||||||
{
|
|
||||||
std::cout << "Enter your username: " << std::endl;
|
std::cout << "Enter your username: " << std::endl;
|
||||||
|
|
||||||
vmime::string res;
|
vmime::string res;
|
||||||
@ -312,8 +312,8 @@ class myAuthenticator : public vmime::security::defaultAuthenticator
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const string getPassword() const
|
const string getPassword() const {
|
||||||
{
|
|
||||||
std::cout << "Enter your password: " << std::endl;
|
std::cout << "Enter your password: " << std::endl;
|
||||||
|
|
||||||
vmime::string res;
|
vmime::string res;
|
||||||
@ -331,9 +331,10 @@ This is how to use it:
|
|||||||
vmime::shared_ptr <vmime::net::session> sess = vmime::net::session::create();
|
vmime::shared_ptr <vmime::net::session> sess = vmime::net::session::create();
|
||||||
|
|
||||||
// Next, initialize a service which will use our authenticator
|
// Next, initialize a service which will use our authenticator
|
||||||
vmime::shared_ptr <vmime::net::store> st =
|
vmime::shared_ptr <vmime::net::store> st = sess->getStore(
|
||||||
sess->getStore(vmime::utility::url("imap://imap.example.com"),
|
vmime::utility::url("imap://imap.example.com"),
|
||||||
/* use our authenticator */ vmime::make_shared <myAuthenticator>());
|
/* use our authenticator */ vmime::make_shared <myAuthenticator>()
|
||||||
|
);
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
\vnote{An authenticator object should be used with one and only one service
|
\vnote{An authenticator object should be used with one and only one service
|
||||||
@ -354,14 +355,15 @@ use the SASL-specific methods {\vcode getAcceptableMechanisms()} and
|
|||||||
implementation of an SASL authenticator.
|
implementation of an SASL authenticator.
|
||||||
|
|
||||||
\begin{lstlisting}[caption={A simple SASL authenticator}]
|
\begin{lstlisting}[caption={A simple SASL authenticator}]
|
||||||
class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator
|
class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator {
|
||||||
{
|
|
||||||
typedef vmime::security::sasl::SASLMechanism mechanism; // save us typing
|
typedef vmime::security::sasl::SASLMechanism mechanism; // save us typing
|
||||||
|
|
||||||
const std::vector <vmime::shared_ptr <mechanism> > getAcceptableMechanisms
|
const std::vector <vmime::shared_ptr <mechanism> > getAcceptableMechanisms(
|
||||||
(const std::vector <vmime::shared_ptr <mechanism> >& available,
|
const std::vector <vmime::shared_ptr <mechanism> >& available,
|
||||||
vmime::shared_ptr <mechanism> suggested) const
|
const vmime::shared_ptr <mechanism>& suggested
|
||||||
{
|
) const {
|
||||||
|
|
||||||
// Here, you can sort the SASL mechanisms in the order they will be
|
// Here, you can sort the SASL mechanisms in the order they will be
|
||||||
// tried. If no SASL mechanism is acceptable (ie. for example, not
|
// tried. If no SASL mechanism is acceptable (ie. for example, not
|
||||||
// enough secure), you can return an empty list.
|
// enough secure), you can return an empty list.
|
||||||
@ -372,8 +374,8 @@ class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticat
|
|||||||
getAcceptableMechanisms(available, suggested);
|
getAcceptableMechanisms(available, suggested);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSASLMechanism(vmime::shared_ptr <mechanism> mech)
|
void setSASLMechanism(const vmime::shared_ptr <mechanism>& mech) {
|
||||||
{
|
|
||||||
// This is called when the authentication process is going to
|
// This is called when the authentication process is going to
|
||||||
// try the specified mechanism.
|
// try the specified mechanism.
|
||||||
//
|
//
|
||||||
@ -435,7 +437,8 @@ tr->send(
|
|||||||
/* expeditor */ from,
|
/* expeditor */ from,
|
||||||
/* recipient(s) */ to,
|
/* recipient(s) */ to,
|
||||||
/* data */ is,
|
/* data */ is,
|
||||||
/* total length */ msgData.length());
|
/* total length */ msgData.length()
|
||||||
|
);
|
||||||
|
|
||||||
// We have finished using the service
|
// We have finished using the service
|
||||||
tr->disconnect();
|
tr->disconnect();
|
||||||
@ -556,22 +559,26 @@ std::vector <ref <vmime::net::message> > allMessages =
|
|||||||
folder->getMessages(vmime::net::messageSet::byNumber(1, -1));
|
folder->getMessages(vmime::net::messageSet::byNumber(1, -1));
|
||||||
// -1 is a special value to mean "the number of the last message in the folder"
|
// -1 is a special value to mean "the number of the last message in the folder"
|
||||||
|
|
||||||
folder->fetchMessages(allMessages,
|
folder->fetchMessages(
|
||||||
|
allMessages,
|
||||||
vmime::net::fetchAttributes::FLAGS |
|
vmime::net::fetchAttributes::FLAGS |
|
||||||
vmime::net::fetchAttributes::ENVELOPE);
|
vmime::net::fetchAttributes::ENVELOPE
|
||||||
|
);
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < allMessages.size() ; ++i) {
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < allMessages.size() ; ++i)
|
|
||||||
{
|
|
||||||
vmime::shared_ptr <vmime::net::message> msg = allMessages[i];
|
vmime::shared_ptr <vmime::net::message> msg = allMessages[i];
|
||||||
|
|
||||||
const int flags = msg->getFlags();
|
const int flags = msg->getFlags();
|
||||||
|
|
||||||
std::cout << "Message " << i << ":" << std::endl;
|
std::cout << "Message " << i << ":" << std::endl;
|
||||||
|
|
||||||
if (flags & vmime::net::message::FLAG_SEEN)
|
if (flags & vmime::net::message::FLAG_SEEN) {
|
||||||
std::cout << " - is read" << std::endl;
|
std::cout << " - is read" << std::endl;
|
||||||
if (flags & vmime::net::message::FLAG_DELETED)
|
}
|
||||||
|
if (flags & vmime::net::message::FLAG_DELETED) {
|
||||||
std::cout << " - is deleted" << std::endl;
|
std::cout << " - is deleted" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
vmime::shared_ptr <const vmime::header> hdr = msg->getHeader();
|
vmime::shared_ptr <const vmime::header> hdr = msg->getHeader();
|
||||||
|
|
||||||
@ -698,8 +705,8 @@ running.
|
|||||||
An interface called {\vcode timeoutHandler} is provided:
|
An interface called {\vcode timeoutHandler} is provided:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
class timeoutHandler : public object
|
class timeoutHandler : public object {
|
||||||
{
|
|
||||||
/** Called to test if the time limit has been reached.
|
/** Called to test if the time limit has been reached.
|
||||||
*
|
*
|
||||||
* @return true if the timeout delay is elapsed
|
* @return true if the timeout delay is elapsed
|
||||||
@ -738,27 +745,27 @@ is thrown.
|
|||||||
The following example shows how to implement a simple timeout handler:
|
The following example shows how to implement a simple timeout handler:
|
||||||
|
|
||||||
\begin{lstlisting}[caption={Implementing a simple timeout handler}]
|
\begin{lstlisting}[caption={Implementing a simple timeout handler}]
|
||||||
class myTimeoutHandler : public vmime::net::timeoutHandler
|
class myTimeoutHandler : public vmime::net::timeoutHandler {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
myTimeoutHandler()
|
myTimeoutHandler() {
|
||||||
{
|
|
||||||
m_startTime = time(NULL);
|
m_startTime = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isTimeOut()
|
const bool isTimeOut() {
|
||||||
{
|
|
||||||
return (time(NULL) >= m_startTime + 30); // 30 seconds timeout
|
return time(NULL) >= m_startTime + 30; // 30 seconds timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetTimeOut()
|
void resetTimeOut() {
|
||||||
{
|
|
||||||
m_startTime = time(NULL);
|
m_startTime = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool handleTimeOut()
|
const bool handleTimeOut() {
|
||||||
{
|
|
||||||
std::cout << "Operation timed out." << std::endl;
|
std::cout << "Operation timed out." << std::endl;
|
||||||
<< "Press [Y] to continue, or [N] to "
|
<< "Press [Y] to continue, or [N] to "
|
||||||
<< "cancel the operation." << std::endl;
|
<< "cancel the operation." << std::endl;
|
||||||
@ -766,7 +773,7 @@ public:
|
|||||||
std::string response;
|
std::string response;
|
||||||
std::cin >> response;
|
std::cin >> response;
|
||||||
|
|
||||||
return (response == "y" || response == "Y");
|
return response == "y" || response == "Y";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -781,12 +788,12 @@ is required because the service can use several connections to the server
|
|||||||
simultaneously, and each connection needs its own timeout handler.
|
simultaneously, and each connection needs its own timeout handler.
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
|
class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ref <timeoutHandler> create()
|
ref <timeoutHandler> create() {
|
||||||
{
|
|
||||||
return vmime::make_shared <myTimeoutHandler>();
|
return vmime::make_shared <myTimeoutHandler>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -918,30 +925,19 @@ First, we need some code to load existing X.509 certificates:
|
|||||||
|
|
||||||
\begin{lstlisting}[caption={Reading a X.509 certificate from a file}]
|
\begin{lstlisting}[caption={Reading a X.509 certificate from a file}]
|
||||||
vmime::shared_ptr <vmime::security::cert::X509Certificate>
|
vmime::shared_ptr <vmime::security::cert::X509Certificate>
|
||||||
loadX509CertificateFromFile(const std::string& path)
|
loadX509CertificateFromFile(const std::string& path) {
|
||||||
{
|
|
||||||
std::ifstream certFile;
|
std::ifstream certFile;
|
||||||
certFile.open(path.c_str(), std::ios::in | std::ios::binary);
|
certFile.open(path.c_str(), std::ios::in | std::ios::binary);
|
||||||
|
|
||||||
if (!certFile)
|
if (!certFile) {
|
||||||
{
|
|
||||||
// ...handle error...
|
// ...handle error...
|
||||||
}
|
}
|
||||||
|
|
||||||
vmime::utility::inputStreamAdapter is(certFile);
|
vmime::utility::inputStreamAdapter is(certFile);
|
||||||
vmime::shared_ptr <vmime::security::cert::X509Certificate> cert;
|
vmime::shared_ptr <vmime::security::cert::X509Certificate> cert;
|
||||||
|
|
||||||
// Try DER format
|
cert = vmime::security::cert::X509Certificate::import(is);
|
||||||
cert = vmime::security::cert::X509Certificate::import
|
|
||||||
(is, vmime::security::cert::X509Certificate::FORMAT_DER);
|
|
||||||
|
|
||||||
if (cert != NULL)
|
|
||||||
return cert;
|
|
||||||
|
|
||||||
// Try PEM format
|
|
||||||
is.reset();
|
|
||||||
cert = vmime::security::cert::X509Certificate::import
|
|
||||||
(is, vmime::security::cert::X509Certificate::FORMAT_PEM);
|
|
||||||
|
|
||||||
return cert;
|
return cert;
|
||||||
}
|
}
|
||||||
@ -988,12 +984,12 @@ use this in a production application as this is obviously a serious security
|
|||||||
issue):
|
issue):
|
||||||
|
|
||||||
\begin{lstlisting}[caption={A custom certificate verifier}]
|
\begin{lstlisting}[caption={A custom certificate verifier}]
|
||||||
class myCertVerifier : public vmime::security::cert::certificateVerifier
|
class myCertVerifier : public vmime::security::cert::certificateVerifier {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void verify(vmime::shared_ptr <certificateChain> certs)
|
void verify(const vmime::shared_ptr <certificateChain>& certs) {
|
||||||
{
|
|
||||||
// Obtain the subject's certificate
|
// Obtain the subject's certificate
|
||||||
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
|
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
|
||||||
|
|
||||||
@ -1006,8 +1002,9 @@ public:
|
|||||||
std::string answer;
|
std::string answer;
|
||||||
std::getline(std::cin, answer);
|
std::getline(std::cin, answer);
|
||||||
|
|
||||||
if (answer.length() != 0 && (answer[0] == 'Y' || answer[0] == 'y'))
|
if (answer.length() != 0 && (answer[0] == 'Y' || answer[0] == 'y')) {
|
||||||
return; // OK, we trust the certificate
|
return; // OK, we trust the certificate
|
||||||
|
}
|
||||||
|
|
||||||
// Don't trust this certificate
|
// Don't trust this certificate
|
||||||
throw vmime::security::cert::certificateException();
|
throw vmime::security::cert::certificateException();
|
||||||
@ -1090,3 +1087,117 @@ The following constants are available:
|
|||||||
\hline
|
\hline
|
||||||
\end{tabularx}
|
\end{tabularx}
|
||||||
|
|
||||||
|
|
||||||
|
% ============================================================================
|
||||||
|
\section{Tracing connection}
|
||||||
|
|
||||||
|
Connection tracing is used to log what is sent and received on the wire
|
||||||
|
between the client and the server, and may help debugging.
|
||||||
|
|
||||||
|
First, you have to create your own tracer, which must implement the
|
||||||
|
{\vcode vmime::net::tracer} interface. Here is an example of a tracer which
|
||||||
|
simply logs to the standard output:
|
||||||
|
|
||||||
|
\begin{lstlisting}[caption={A simple tracer}]
|
||||||
|
class myTracer : public vmime::net::tracer {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
myTracer(const vmime::string& proto, const int connectionId)
|
||||||
|
: m_proto(proto),
|
||||||
|
m_connectionId(connectionId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by VMime to trace what is sent on the socket
|
||||||
|
void traceSend(const vmime::string& line) {
|
||||||
|
|
||||||
|
std::cout << "[" << m_proto << ":" << m_connectionId
|
||||||
|
<< "] C: " << line << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by VMime to trace what is received from the socket
|
||||||
|
void traceReceive(const vmime::string& line) {
|
||||||
|
|
||||||
|
std::cout << "[" < < m_proto << ":" << m_connectionId
|
||||||
|
<< "] S: " << line << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const vmime::string m_proto;
|
||||||
|
const int m_connectionId;
|
||||||
|
};
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Also create a factory class, used to instanciate your tracer objects:
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
class myTracerFactory : public vmime::net::tracerFactory {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
vmime::shared_ptr <vmime::net::tracer> create(
|
||||||
|
const vmime::shared_ptr <vmime::net::service>& serv,
|
||||||
|
const int connectionId
|
||||||
|
) {
|
||||||
|
|
||||||
|
return vmime::make_shared <myTracer>(
|
||||||
|
serv->getProtocolName(), connectionId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
Next, we have to tell VMime to use it. When you create your service
|
||||||
|
(either store or transport), simply call the {\vcode setTracerFactory}
|
||||||
|
on the service and pass an instance of your factory class:
|
||||||
|
|
||||||
|
\begin{lstlisting}[caption={Enabling tracer on a connection}]
|
||||||
|
vmime::shared_ptr <vmime::net::transport> store =
|
||||||
|
session->getStore("imaps://user:password@imap.myserver.com");
|
||||||
|
|
||||||
|
// Enable tracing communication between client and server
|
||||||
|
store->setTracerFactory(vmime::make_shared <myTracerFactory>());
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
That's all! Now, everything which is sent on/received from the socket
|
||||||
|
will be logged using your tracer object. Here is an example of a trace
|
||||||
|
session for IMAP:
|
||||||
|
|
||||||
|
\begin{verbatim}
|
||||||
|
[imaps:1] S: * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR
|
||||||
|
LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.
|
||||||
|
[imaps:1] C: a001 AUTHENTICATE PLAIN
|
||||||
|
[imaps:1] S: +
|
||||||
|
[imaps:1] C: {...SASL exchange: 52 bytes of data...}
|
||||||
|
[imaps:1] S: a001 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR
|
||||||
|
LOGIN-REFERRALS ID ENABLE IDLE SORT SPECIAL-USE QUOTA] Logged in
|
||||||
|
[imaps:1] C: a002 LIST "" ""
|
||||||
|
[imaps:1] S: * LIST (\Noselect) "." ""
|
||||||
|
[imaps:1] S: a002 OK List completed.
|
||||||
|
[imaps:1] C: a003 CAPABILITY
|
||||||
|
[imaps:1] S: * CAPABILITY IMAP4rev1 LITERAL+ SASL-IR
|
||||||
|
LOGIN-REFERRALS ID ENABLE IDLE SORT SPECIAL-USE QUOTA
|
||||||
|
[imaps:1] S: a003 OK Capability completed.
|
||||||
|
[imaps:1] C: a003 SELECT INBOX (CONDSTORE)
|
||||||
|
[imaps:1] S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft
|
||||||
|
$NotJunk NonJunk JunkRecorded $MDNSent NotJunk $Forwarded
|
||||||
|
Junk $Junk Forwarded $MailFlagBit1)
|
||||||
|
[imaps:1] S: * OK [PERMANENTFLAGS (\Answered \Flagged \Deleted
|
||||||
|
\Seen \Draft $NotJunk NonJunk JunkRecorded $MDNSent NotJunk
|
||||||
|
$Forwarded Junk $Junk Forwarded $MailFlagBit1 \*)]
|
||||||
|
Flags permitted.
|
||||||
|
[imaps:1] S: * 104 EXISTS
|
||||||
|
[imaps:1] S: * 0 RECENT
|
||||||
|
[imaps:1] S: * OK [UNSEEN 6] First unseen.
|
||||||
|
[imaps:1] S: * OK [UIDVALIDITY 1268127585] UIDs valid
|
||||||
|
[imaps:1] S: * OK [UIDNEXT 32716] Predicted next UID
|
||||||
|
[imaps:1] S: * OK [HIGHESTMODSEQ 148020] Highest
|
||||||
|
[imaps:1] S: a003 OK [READ-WRITE] Select completed.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
Please note that no sensitive data (ie. login or password) will be traced.
|
||||||
|
Same, {\em blob} data such as message content or SASL exchanges will be logged
|
||||||
|
as a marker which indicates how many bytes were sent/received (eg. "{...SASL
|
||||||
|
exchange: 52 bytes of data...}"").
|
||||||
|
@ -26,7 +26,7 @@ You can simply build your program with:
|
|||||||
to use the static version, or with:
|
to use the static version, or with:
|
||||||
|
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
$ g++ `pkg-config --cflags --libs vmime` -o myprog myprog.cpp
|
$ g++ `pkg-config --cflags vmime` -o myprog myprog.cpp `pkg-config --libs vmime`
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
to use the shared version.
|
to use the shared version.
|
||||||
@ -82,8 +82,8 @@ So, if your platform is POSIX, your program should look like this:
|
|||||||
#include <vmime/vmime.hpp>
|
#include <vmime/vmime.hpp>
|
||||||
#include <vmime/platforms/posix/posixHandler.hpp>
|
#include <vmime/platforms/posix/posixHandler.hpp>
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
vmime::platform::
|
vmime::platform::
|
||||||
setHandler <vmime::platforms::posix::posixHandler>();
|
setHandler <vmime::platforms::posix::posixHandler>();
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -39,23 +39,20 @@
|
|||||||
#include "vmime/platforms/posix/posixHandler.hpp"
|
#include "vmime/platforms/posix/posixHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Set the global C and C++ locale to the user-configured locale.
|
// Set the global C and C++ locale to the user-configured locale.
|
||||||
// The locale should use UTF-8 encoding for these tests to run successfully.
|
// The locale should use UTF-8 encoding for these tests to run successfully.
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::locale::global(std::locale(""));
|
std::locale::global(std::locale(""));
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception &)
|
|
||||||
{
|
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
// Fill in the basic fields
|
// Fill in the basic fields
|
||||||
@ -74,9 +71,12 @@ int main()
|
|||||||
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
||||||
|
|
||||||
// Message body
|
// Message body
|
||||||
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
|
mb.getTextPart()->setText(
|
||||||
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
"I'm writing this short text to test message construction " \
|
"I'm writing this short text to test message construction " \
|
||||||
"using the vmime::messageBuilder component."));
|
"using the vmime::messageBuilder component."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Construction
|
// Construction
|
||||||
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
||||||
@ -87,20 +87,21 @@ int main()
|
|||||||
|
|
||||||
vmime::utility::outputStreamAdapter out(std::cout);
|
vmime::utility::outputStreamAdapter out(std::cout);
|
||||||
msg->generate(out);
|
msg->generate(out);
|
||||||
}
|
|
||||||
// VMime exception
|
// VMime exception
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "vmime::exception: " << e.what() << std::endl;
|
std::cout << "vmime::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
|
||||||
// Standard exception
|
// Standard exception
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "std::exception: " << e.what() << std::endl;
|
std::cout << "std::exception: " << e.what() << std::endl;
|
||||||
//throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -39,23 +39,20 @@
|
|||||||
#include "vmime/platforms/posix/posixHandler.hpp"
|
#include "vmime/platforms/posix/posixHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Set the global C and C++ locale to the user-configured locale.
|
// Set the global C and C++ locale to the user-configured locale.
|
||||||
// The locale should use UTF-8 encoding for these tests to run successfully.
|
// The locale should use UTF-8 encoding for these tests to run successfully.
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::locale::global(std::locale(""));
|
std::locale::global(std::locale(""));
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception &)
|
|
||||||
{
|
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
// Fill in the basic fields
|
// Fill in the basic fields
|
||||||
@ -74,13 +71,16 @@ int main()
|
|||||||
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
||||||
|
|
||||||
// Message body
|
// Message body
|
||||||
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
|
mb.getTextPart()->setText(
|
||||||
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
"I'm writing this short text to test message construction " \
|
"I'm writing this short text to test message construction " \
|
||||||
"with attachment, using the vmime::messageBuilder component."));
|
"with attachment, using the vmime::messageBuilder component."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Adding an attachment
|
// Adding an attachment
|
||||||
vmime::shared_ptr <vmime::fileAttachment> a = vmime::make_shared <vmime::fileAttachment>
|
vmime::shared_ptr <vmime::fileAttachment> a =
|
||||||
(
|
vmime::make_shared <vmime::fileAttachment>(
|
||||||
__FILE__, // full path to file
|
__FILE__, // full path to file
|
||||||
vmime::mediaType("application/octet-stream"), // content type
|
vmime::mediaType("application/octet-stream"), // content type
|
||||||
vmime::text("My first attachment") // description
|
vmime::text("My first attachment") // description
|
||||||
@ -101,20 +101,21 @@ int main()
|
|||||||
std::cout << "==================" << std::endl;
|
std::cout << "==================" << std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << dataToSend << std::endl;
|
std::cout << dataToSend << std::endl;
|
||||||
}
|
|
||||||
// VMime exception
|
// VMime exception
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "vmime::exception: " << e.what() << std::endl;
|
std::cout << "vmime::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
|
||||||
// Standard exception
|
// Standard exception
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "std::exception: " << e.what() << std::endl;
|
std::cout << "std::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -39,23 +39,20 @@
|
|||||||
#include "vmime/platforms/posix/posixHandler.hpp"
|
#include "vmime/platforms/posix/posixHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Set the global C and C++ locale to the user-configured locale.
|
// Set the global C and C++ locale to the user-configured locale.
|
||||||
// The locale should use UTF-8 encoding for these tests to run successfully.
|
// The locale should use UTF-8 encoding for these tests to run successfully.
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::locale::global(std::locale(""));
|
std::locale::global(std::locale(""));
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception &)
|
|
||||||
{
|
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
// Fill in the basic fields
|
// Fill in the basic fields
|
||||||
@ -74,12 +71,17 @@ int main()
|
|||||||
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
||||||
|
|
||||||
// Set the content-type to "text/html"
|
// Set the content-type to "text/html"
|
||||||
mb.constructTextPart(vmime::mediaType
|
mb.constructTextPart(
|
||||||
(vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML));
|
vmime::mediaType(
|
||||||
|
vmime::mediaTypes::TEXT,
|
||||||
|
vmime::mediaTypes::TEXT_HTML
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Fill in the text part: the message is available in two formats: HTML and plain text.
|
// Fill in the text part: the message is available in two formats: HTML and plain text.
|
||||||
// HTML text part also includes an inline image (embedded into the message).
|
// HTML text part also includes an inline image (embedded into the message).
|
||||||
vmime::htmlTextPart& textPart = *vmime::dynamicCast <vmime::htmlTextPart>(mb.getTextPart());
|
vmime::htmlTextPart& textPart =
|
||||||
|
*vmime::dynamicCast <vmime::htmlTextPart>(mb.getTextPart());
|
||||||
|
|
||||||
// -- embed an image (the returned "CID" (content identifier) is used to reference
|
// -- embed an image (the returned "CID" (content identifier) is used to reference
|
||||||
// -- the image into HTML content).
|
// -- the image into HTML content).
|
||||||
@ -93,18 +95,33 @@ int main()
|
|||||||
imageFile->getFileReader();
|
imageFile->getFileReader();
|
||||||
|
|
||||||
vmime::shared_ptr <vmime::contentHandler> imageCts =
|
vmime::shared_ptr <vmime::contentHandler> imageCts =
|
||||||
vmime::make_shared <vmime::streamContentHandler>
|
vmime::make_shared <vmime::streamContentHandler>(
|
||||||
(fileReader->getInputStream(), imageFile->getLength());
|
fileReader->getInputStream(),
|
||||||
|
imageFile->getLength()
|
||||||
|
);
|
||||||
|
|
||||||
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj = textPart.addObject
|
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj =
|
||||||
(imageCts, vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
|
textPart.addObject(
|
||||||
|
imageCts,
|
||||||
|
vmime::mediaType(
|
||||||
|
vmime::mediaTypes::IMAGE,
|
||||||
|
vmime::mediaTypes::IMAGE_JPEG
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// -- message text
|
// -- message text
|
||||||
textPart.setText(vmime::make_shared <vmime::stringContentHandler>
|
textPart.setText(
|
||||||
(vmime::string("This is the <b>HTML text</b>.<br/>"
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
"<img src=\"") + obj->getReferenceId() + vmime::string("\"/>")));
|
vmime::string("This is the <b>HTML text</b>.<br/>"
|
||||||
textPart.setPlainText(vmime::make_shared <vmime::stringContentHandler>
|
"<img src=\"") + obj->getReferenceId() + vmime::string("\"/>")
|
||||||
("This is the plain text (without HTML formatting)."));
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
textPart.setPlainText(
|
||||||
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
|
"This is the plain text (without HTML formatting)."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// Construction
|
// Construction
|
||||||
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
||||||
@ -116,20 +133,21 @@ int main()
|
|||||||
std::cout << "==================" << std::endl;
|
std::cout << "==================" << std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << dataToSend << std::endl;
|
std::cout << dataToSend << std::endl;
|
||||||
}
|
|
||||||
// VMime exception
|
// VMime exception
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "vmime::exception: " << e.what() << std::endl;
|
std::cout << "vmime::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
|
||||||
// Standard exception
|
// Standard exception
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "std::exception: " << e.what() << std::endl;
|
std::cout << "std::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -39,71 +39,70 @@
|
|||||||
#include "vmime/platforms/posix/posixHandler.hpp"
|
#include "vmime/platforms/posix/posixHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Set the global C and C++ locale to the user-configured locale.
|
// Set the global C and C++ locale to the user-configured locale.
|
||||||
// The locale should use UTF-8 encoding for these tests to run successfully.
|
// The locale should use UTF-8 encoding for these tests to run successfully.
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::locale::global(std::locale(""));
|
std::locale::global(std::locale(""));
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception &)
|
|
||||||
{
|
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
vmime::messageParser mp("<...MIME message content...>");
|
vmime::messageParser mp("<...MIME message content...>");
|
||||||
|
|
||||||
// Enumerate text parts
|
// Enumerate text parts
|
||||||
for (size_t i = 0 ; i < mp.getTextPartCount() ; ++i)
|
for (size_t i = 0 ; i < mp.getTextPartCount() ; ++i) {
|
||||||
{
|
|
||||||
const vmime::textPart& part = *mp.getTextPartAt(i);
|
const vmime::textPart& part = *mp.getTextPartAt(i);
|
||||||
|
|
||||||
// Output content-type of the part
|
// Output content-type of the part
|
||||||
std::cout << part.getType().generate() << std::endl;
|
std::cout << part.getType().generate() << std::endl;
|
||||||
|
|
||||||
// text/html
|
// text/html
|
||||||
if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML)
|
if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML) {
|
||||||
{
|
|
||||||
const vmime::htmlTextPart& hp = dynamic_cast<const vmime::htmlTextPart&>(part);
|
const vmime::htmlTextPart& hp = dynamic_cast<const vmime::htmlTextPart&>(part);
|
||||||
|
|
||||||
// HTML text is in "hp.getText()"
|
// HTML text is in "hp.getText()"
|
||||||
// Corresponding plain text is in "hp.getPlainText()"
|
// Corresponding plain text is in "hp.getPlainText()"
|
||||||
|
|
||||||
// Enumerate embedded objects (eg. images)
|
// Enumerate embedded objects (eg. images)
|
||||||
for (size_t j = 0 ; j < hp.getObjectCount() ; ++j)
|
for (size_t j = 0 ; j < hp.getObjectCount() ; ++j) {
|
||||||
{
|
|
||||||
const vmime::htmlTextPart::embeddedObject& obj = *hp.getObjectAt(j);
|
const vmime::htmlTextPart::embeddedObject& obj = *hp.getObjectAt(j);
|
||||||
|
|
||||||
// Identifier (content-id or content-location) is in "obj.getId()"
|
// Identifier (content-id or content-location) is in "obj.getId()"
|
||||||
// Object data is in "obj.getData()"
|
// Object data is in "obj.getData()"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// text/plain
|
// text/plain
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const vmime::textPart& tp = dynamic_cast<const vmime::textPart&>(part);
|
const vmime::textPart& tp = dynamic_cast<const vmime::textPart&>(part);
|
||||||
|
|
||||||
// Text is in "tp.getText()"
|
// Text is in "tp.getText()"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// VMime exception
|
// VMime exception
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "vmime::exception: " << e.what() << std::endl;
|
std::cout << "vmime::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
|
||||||
// Standard exception
|
// Standard exception
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "std::exception: " << e.what() << std::endl;
|
std::cout << "std::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -39,28 +39,25 @@
|
|||||||
#include "vmime/platforms/posix/posixHandler.hpp"
|
#include "vmime/platforms/posix/posixHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Set the global C and C++ locale to the user-configured locale.
|
// Set the global C and C++ locale to the user-configured locale.
|
||||||
// The locale should use UTF-8 encoding for these tests to run successfully.
|
// The locale should use UTF-8 encoding for these tests to run successfully.
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::locale::global(std::locale(""));
|
std::locale::global(std::locale(""));
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception &)
|
|
||||||
{
|
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
vmime::messageParser mp("<...MIME message content...>");
|
vmime::messageParser mp("<...MIME message content...>");
|
||||||
|
|
||||||
// Enumerate attachments
|
// Enumerate attachments
|
||||||
for (size_t i = 0 ; i < mp.getAttachmentCount() ; ++i)
|
for (size_t i = 0 ; i < mp.getAttachmentCount() ; ++i) {
|
||||||
{
|
|
||||||
const vmime::attachment& att = *mp.getAttachmentAt(i);
|
const vmime::attachment& att = *mp.getAttachmentAt(i);
|
||||||
|
|
||||||
// Media type (content type) is in "att.getType()"
|
// Media type (content type) is in "att.getType()"
|
||||||
@ -68,19 +65,21 @@ int main()
|
|||||||
// Description is in "att.getDescription()"
|
// Description is in "att.getDescription()"
|
||||||
// Data is in "att.getData()"
|
// Data is in "att.getData()"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// VMime exception
|
// VMime exception
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "vmime::exception: " << e.what() << std::endl;
|
std::cout << "vmime::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
|
||||||
// Standard exception
|
// Standard exception
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cout << "std::exception: " << e.what() << std::endl;
|
std::cout << "std::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -46,22 +46,23 @@ static vmime::shared_ptr <vmime::net::session> g_session = vmime::net::session::
|
|||||||
* @param type service type (vmime::net::service::TYPE_STORE or
|
* @param type service type (vmime::net::service::TYPE_STORE or
|
||||||
* vmime::net::service::TYPE_TRANSPORT)
|
* vmime::net::service::TYPE_TRANSPORT)
|
||||||
*/
|
*/
|
||||||
static const std::string findAvailableProtocols(const vmime::net::service::Type type)
|
static const std::string findAvailableProtocols(const vmime::net::service::Type type) {
|
||||||
{
|
|
||||||
vmime::shared_ptr <vmime::net::serviceFactory> sf =
|
vmime::shared_ptr <vmime::net::serviceFactory> sf =
|
||||||
vmime::net::serviceFactory::getInstance();
|
vmime::net::serviceFactory::getInstance();
|
||||||
|
|
||||||
std::ostringstream res;
|
std::ostringstream res;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i)
|
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) {
|
||||||
{
|
|
||||||
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
||||||
|
|
||||||
if (serv.getType() == type)
|
if (serv.getType() == type) {
|
||||||
{
|
|
||||||
if (count != 0)
|
if (count != 0) {
|
||||||
res << ", ";
|
res << ", ";
|
||||||
|
}
|
||||||
|
|
||||||
res << serv.getName();
|
res << serv.getName();
|
||||||
++count;
|
++count;
|
||||||
@ -73,14 +74,14 @@ static const std::string findAvailableProtocols(const vmime::net::service::Type
|
|||||||
|
|
||||||
|
|
||||||
// Exception helper
|
// Exception helper
|
||||||
static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) {
|
||||||
{
|
|
||||||
os << "* vmime::exceptions::" << e.name() << std::endl;
|
os << "* vmime::exceptions::" << e.name() << std::endl;
|
||||||
os << " what = " << e.what() << std::endl;
|
os << " what = " << e.what() << std::endl;
|
||||||
|
|
||||||
// More information for special exceptions
|
// More information for special exceptions
|
||||||
if (dynamic_cast <const vmime::exceptions::command_error*>(&e))
|
if (dynamic_cast <const vmime::exceptions::command_error*>(&e)) {
|
||||||
{
|
|
||||||
const vmime::exceptions::command_error& cee =
|
const vmime::exceptions::command_error& cee =
|
||||||
dynamic_cast <const vmime::exceptions::command_error&>(e);
|
dynamic_cast <const vmime::exceptions::command_error&>(e);
|
||||||
|
|
||||||
@ -88,32 +89,32 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
|||||||
os << " response = " << cee.response() << std::endl;
|
os << " response = " << cee.response() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e))
|
if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e)) {
|
||||||
{
|
|
||||||
const vmime::exceptions::invalid_response& ir =
|
const vmime::exceptions::invalid_response& ir =
|
||||||
dynamic_cast <const vmime::exceptions::invalid_response&>(e);
|
dynamic_cast <const vmime::exceptions::invalid_response&>(e);
|
||||||
|
|
||||||
os << " response = " << ir.response() << std::endl;
|
os << " response = " << ir.response() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_cast <const vmime::exceptions::connection_greeting_error*>(&e))
|
if (dynamic_cast <const vmime::exceptions::connection_greeting_error*>(&e)) {
|
||||||
{
|
|
||||||
const vmime::exceptions::connection_greeting_error& cgee =
|
const vmime::exceptions::connection_greeting_error& cgee =
|
||||||
dynamic_cast <const vmime::exceptions::connection_greeting_error&>(e);
|
dynamic_cast <const vmime::exceptions::connection_greeting_error&>(e);
|
||||||
|
|
||||||
os << " response = " << cgee.response() << std::endl;
|
os << " response = " << cgee.response() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_cast <const vmime::exceptions::authentication_error*>(&e))
|
if (dynamic_cast <const vmime::exceptions::authentication_error*>(&e)) {
|
||||||
{
|
|
||||||
const vmime::exceptions::authentication_error& aee =
|
const vmime::exceptions::authentication_error& aee =
|
||||||
dynamic_cast <const vmime::exceptions::authentication_error&>(e);
|
dynamic_cast <const vmime::exceptions::authentication_error&>(e);
|
||||||
|
|
||||||
os << " response = " << aee.response() << std::endl;
|
os << " response = " << aee.response() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dynamic_cast <const vmime::exceptions::filesystem_exception*>(&e))
|
if (dynamic_cast <const vmime::exceptions::filesystem_exception*>(&e)) {
|
||||||
{
|
|
||||||
const vmime::exceptions::filesystem_exception& fse =
|
const vmime::exceptions::filesystem_exception& fse =
|
||||||
dynamic_cast <const vmime::exceptions::filesystem_exception&>(e);
|
dynamic_cast <const vmime::exceptions::filesystem_exception&>(e);
|
||||||
|
|
||||||
@ -121,8 +122,9 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
|||||||
getFileSystemFactory()->pathToString(fse.path()) << std::endl;
|
getFileSystemFactory()->pathToString(fse.path()) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.other() != NULL)
|
if (e.other()) {
|
||||||
os << *e.other();
|
os << *e.other();
|
||||||
|
}
|
||||||
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
@ -133,16 +135,21 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
|
|||||||
* @param s structure object
|
* @param s structure object
|
||||||
* @param level current depth
|
* @param level current depth
|
||||||
*/
|
*/
|
||||||
static void printStructure(vmime::shared_ptr <const vmime::net::messageStructure> s, const int level = 0)
|
static void printStructure(
|
||||||
{
|
vmime::shared_ptr <const vmime::net::messageStructure> s,
|
||||||
for (size_t i = 0 ; i < s->getPartCount() ; ++i)
|
const int level = 0
|
||||||
{
|
) {
|
||||||
|
|
||||||
|
for (size_t i = 0 ; i < s->getPartCount() ; ++i) {
|
||||||
|
|
||||||
vmime::shared_ptr <const vmime::net::messagePart> part = s->getPartAt(i);
|
vmime::shared_ptr <const vmime::net::messagePart> part = s->getPartAt(i);
|
||||||
|
|
||||||
for (int j = 0 ; j < level * 2 ; ++j)
|
for (int j = 0 ; j < level * 2 ; ++j) {
|
||||||
std::cout << " ";
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << (part->getNumber() + 1) << ". "
|
std::cout
|
||||||
|
<< (part->getNumber() + 1) << ". "
|
||||||
<< part->getType().generate()
|
<< part->getType().generate()
|
||||||
<< " [" << part->getSize() << " byte(s)]"
|
<< " [" << part->getSize() << " byte(s)]"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@ -152,16 +159,16 @@ static void printStructure(vmime::shared_ptr <const vmime::net::messageStructure
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::folder> f)
|
static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::folder> f) {
|
||||||
{
|
|
||||||
const vmime::string n = f->getName().getBuffer();
|
const vmime::string n = f->getName().getBuffer();
|
||||||
|
|
||||||
if (n.empty()) // root folder
|
if (n.empty()) { // root folder
|
||||||
{
|
|
||||||
return "/";
|
return "/";
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
vmime::shared_ptr <vmime::net::folder> p = f->getParent();
|
vmime::shared_ptr <vmime::net::folder> p = f->getParent();
|
||||||
return getFolderPathString(p) + n + "/";
|
return getFolderPathString(p) + n + "/";
|
||||||
}
|
}
|
||||||
@ -172,38 +179,43 @@ static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::fo
|
|||||||
*
|
*
|
||||||
* @param folder current folder
|
* @param folder current folder
|
||||||
*/
|
*/
|
||||||
static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const int level = 0)
|
static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const int level = 0) {
|
||||||
{
|
|
||||||
for (int j = 0 ; j < level * 2 ; ++j)
|
for (int j = 0 ; j < level * 2 ; ++j) {
|
||||||
std::cout << " ";
|
std::cout << " ";
|
||||||
|
}
|
||||||
|
|
||||||
const vmime::net::folderAttributes attr = folder->getAttributes();
|
const vmime::net::folderAttributes attr = folder->getAttributes();
|
||||||
std::ostringstream attrStr;
|
std::ostringstream attrStr;
|
||||||
|
|
||||||
if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL)
|
if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL) {
|
||||||
attrStr << " \\use:All";
|
attrStr << " \\use:All";
|
||||||
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ARCHIVE)
|
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ARCHIVE) {
|
||||||
attrStr << " \\use:Archive";
|
attrStr << " \\use:Archive";
|
||||||
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS)
|
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS) {
|
||||||
attrStr << " \\use:Drafts";
|
attrStr << " \\use:Drafts";
|
||||||
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_FLAGGED)
|
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_FLAGGED) {
|
||||||
attrStr << " \\use:Flagged";
|
attrStr << " \\use:Flagged";
|
||||||
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK)
|
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK) {
|
||||||
attrStr << " \\use:Junk";
|
attrStr << " \\use:Junk";
|
||||||
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_SENT)
|
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_SENT) {
|
||||||
attrStr << " \\use:Sent";
|
attrStr << " \\use:Sent";
|
||||||
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH)
|
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH) {
|
||||||
attrStr << " \\use:Trash";
|
attrStr << " \\use:Trash";
|
||||||
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_IMPORTANT)
|
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_IMPORTANT) {
|
||||||
attrStr << " \\use:Important";
|
attrStr << " \\use:Important";
|
||||||
|
}
|
||||||
|
|
||||||
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN)
|
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN) {
|
||||||
attrStr << " \\flag:HasChildren";
|
attrStr << " \\flag:HasChildren";
|
||||||
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN)
|
}
|
||||||
|
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN) {
|
||||||
attrStr << " \\flag:NoOpen";
|
attrStr << " \\flag:NoOpen";
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0, n = attr.getUserFlags().size() ; i < n ; ++i)
|
for (size_t i = 0, n = attr.getUserFlags().size() ; i < n ; ++i) {
|
||||||
attrStr << " \\" << attr.getUserFlags()[i];
|
attrStr << " \\" << attr.getUserFlags()[i];
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << getFolderPathString(folder);
|
std::cout << getFolderPathString(folder);
|
||||||
std::cout << " " << attrStr.str();
|
std::cout << " " << attrStr.str();
|
||||||
@ -211,8 +223,9 @@ static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const in
|
|||||||
|
|
||||||
std::vector <vmime::shared_ptr <vmime::net::folder> > subFolders = folder->getFolders(false);
|
std::vector <vmime::shared_ptr <vmime::net::folder> > subFolders = folder->getFolders(false);
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < subFolders.size() ; ++i)
|
for (unsigned int i = 0 ; i < subFolders.size() ; ++i) {
|
||||||
printFolders(subFolders[i], level + 1);
|
printFolders(subFolders[i], level + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -220,12 +233,13 @@ static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const in
|
|||||||
*
|
*
|
||||||
* @param choices menu choices
|
* @param choices menu choices
|
||||||
*/
|
*/
|
||||||
static unsigned int printMenu(const std::vector <std::string>& choices)
|
static unsigned int printMenu(const std::vector <std::string>& choices) {
|
||||||
{
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < choices.size() ; ++i)
|
for (unsigned int i = 0 ; i < choices.size() ; ++i) {
|
||||||
std::cout << " " << (i + 1) << ". " << choices[i] << std::endl;
|
std::cout << " " << (i + 1) << ". " << choices[i] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << " Your choice? [1-" << choices.size() << "] ";
|
std::cout << " Your choice? [1-" << choices.size() << "] ";
|
||||||
@ -241,19 +255,20 @@ static unsigned int printMenu(const std::vector <std::string>& choices)
|
|||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
if (choice < 1 || choice > choices.size())
|
if (choice < 1 || choice > choices.size()) {
|
||||||
return 0;
|
return 0;
|
||||||
else
|
} else {
|
||||||
return choice;
|
return choice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Send a message interactively.
|
/** Send a message interactively.
|
||||||
*/
|
*/
|
||||||
static void sendMessage()
|
static void sendMessage() {
|
||||||
{
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// Request user to enter an URL
|
// Request user to enter an URL
|
||||||
std::cout << "Enter an URL to connect to transport service." << std::endl;
|
std::cout << "Enter an URL to connect to transport service." << std::endl;
|
||||||
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_TRANSPORT) << std::endl;
|
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_TRANSPORT) << std::endl;
|
||||||
@ -268,10 +283,11 @@ static void sendMessage()
|
|||||||
|
|
||||||
vmime::shared_ptr <vmime::net::transport> tr;
|
vmime::shared_ptr <vmime::net::transport> tr;
|
||||||
|
|
||||||
if (url.getUsername().empty() || url.getPassword().empty())
|
if (url.getUsername().empty() || url.getPassword().empty()) {
|
||||||
tr = g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>());
|
tr = g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>());
|
||||||
else
|
} else {
|
||||||
tr = g_session->getTransport(url);
|
tr = g_session->getTransport(url);
|
||||||
|
}
|
||||||
|
|
||||||
#if VMIME_HAVE_TLS_SUPPORT
|
#if VMIME_HAVE_TLS_SUPPORT
|
||||||
|
|
||||||
@ -283,15 +299,17 @@ static void sendMessage()
|
|||||||
|
|
||||||
// Set the object responsible for verifying certificates, in the
|
// Set the object responsible for verifying certificates, in the
|
||||||
// case a secured connection is used (TLS/SSL)
|
// case a secured connection is used (TLS/SSL)
|
||||||
tr->setCertificateVerifier
|
tr->setCertificateVerifier(
|
||||||
(vmime::make_shared <interactiveCertificateVerifier>());
|
vmime::make_shared <interactiveCertificateVerifier>()
|
||||||
|
);
|
||||||
|
|
||||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||||
|
|
||||||
// You can also set some properties (see example7 to know the properties
|
// You can also set some properties (see example7 to know the properties
|
||||||
// available for each service). For example, for SMTP:
|
// available for each service). For example, for SMTP:
|
||||||
if (!url.getUsername().empty() || !url.getPassword().empty())
|
if (!url.getUsername().empty() || !url.getPassword().empty()) {
|
||||||
tr->setProperty("options.need-authentication", true);
|
tr->setProperty("options.need-authentication", true);
|
||||||
|
}
|
||||||
|
|
||||||
// Trace communication between client and server
|
// Trace communication between client and server
|
||||||
vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
|
vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
|
||||||
@ -307,8 +325,8 @@ static void sendMessage()
|
|||||||
vmime::mailbox from(fromString);
|
vmime::mailbox from(fromString);
|
||||||
vmime::mailboxList to;
|
vmime::mailboxList to;
|
||||||
|
|
||||||
for (bool cont = true ; cont ; )
|
for (bool cont = true ; cont ; ) {
|
||||||
{
|
|
||||||
std::cout << "Enter email of the recipient (empty to stop): ";
|
std::cout << "Enter email of the recipient (empty to stop): ";
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
@ -317,24 +335,26 @@ static void sendMessage()
|
|||||||
|
|
||||||
cont = (toString.size() != 0);
|
cont = (toString.size() != 0);
|
||||||
|
|
||||||
if (cont)
|
if (cont) {
|
||||||
to.appendMailbox(vmime::make_shared <vmime::mailbox>(toString));
|
to.appendMailbox(vmime::make_shared <vmime::mailbox>(toString));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "Enter message data, including headers (end with '.' on a single line):" << std::endl;
|
std::cout << "Enter message data, including headers (end with '.' on a single line):" << std::endl;
|
||||||
|
|
||||||
std::ostringstream data;
|
std::ostringstream data;
|
||||||
|
|
||||||
for (bool cont = true ; cont ; )
|
for (bool cont = true ; cont ; ) {
|
||||||
{
|
|
||||||
std::string line;
|
std::string line;
|
||||||
std::getline(std::cin, line);
|
std::getline(std::cin, line);
|
||||||
|
|
||||||
if (line == ".")
|
if (line == ".") {
|
||||||
cont = false;
|
cont = false;
|
||||||
else
|
} else {
|
||||||
data << line << "\r\n";
|
data << line << "\r\n";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Connect to server
|
// Connect to server
|
||||||
tr->connect();
|
tr->connect();
|
||||||
@ -357,15 +377,15 @@ static void sendMessage()
|
|||||||
std::cout << traceStream->str();
|
std::cout << traceStream->str();
|
||||||
|
|
||||||
tr->disconnect();
|
tr->disconnect();
|
||||||
}
|
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << e << std::endl;
|
std::cerr << e << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "std::exception: " << e.what() << std::endl;
|
std::cerr << "std::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
@ -375,10 +395,10 @@ static void sendMessage()
|
|||||||
|
|
||||||
/** Connect to a message store interactively.
|
/** Connect to a message store interactively.
|
||||||
*/
|
*/
|
||||||
static void connectStore()
|
static void connectStore() {
|
||||||
{
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
// Request user to enter an URL
|
// Request user to enter an URL
|
||||||
std::cout << "Enter an URL to connect to store service." << std::endl;
|
std::cout << "Enter an URL to connect to store service." << std::endl;
|
||||||
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_STORE) << std::endl;
|
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_STORE) << std::endl;
|
||||||
@ -396,10 +416,11 @@ static void connectStore()
|
|||||||
// session properties "auth.username" and "auth.password".
|
// session properties "auth.username" and "auth.password".
|
||||||
vmime::shared_ptr <vmime::net::store> st;
|
vmime::shared_ptr <vmime::net::store> st;
|
||||||
|
|
||||||
if (url.getUsername().empty() || url.getPassword().empty())
|
if (url.getUsername().empty() || url.getPassword().empty()) {
|
||||||
st = g_session->getStore(url, vmime::make_shared <interactiveAuthenticator>());
|
st = g_session->getStore(url, vmime::make_shared <interactiveAuthenticator>());
|
||||||
else
|
} else {
|
||||||
st = g_session->getStore(url);
|
st = g_session->getStore(url);
|
||||||
|
}
|
||||||
|
|
||||||
#if VMIME_HAVE_TLS_SUPPORT
|
#if VMIME_HAVE_TLS_SUPPORT
|
||||||
|
|
||||||
@ -411,8 +432,9 @@ static void connectStore()
|
|||||||
|
|
||||||
// Set the object responsible for verifying certificates, in the
|
// Set the object responsible for verifying certificates, in the
|
||||||
// case a secured connection is used (TLS/SSL)
|
// case a secured connection is used (TLS/SSL)
|
||||||
st->setCertificateVerifier
|
st->setCertificateVerifier(
|
||||||
(vmime::make_shared <interactiveCertificateVerifier>());
|
vmime::make_shared <interactiveCertificateVerifier>()
|
||||||
|
);
|
||||||
|
|
||||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||||
|
|
||||||
@ -441,13 +463,13 @@ static void connectStore()
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << count << " message(s) in your inbox" << std::endl;
|
std::cout << count << " message(s) in your inbox" << std::endl;
|
||||||
|
|
||||||
for (bool cont = true ; cont ; )
|
for (bool cont = true ; cont ; ) {
|
||||||
{
|
|
||||||
typedef std::map <vmime::size_t, vmime::shared_ptr <vmime::net::message> > MessageList;
|
typedef std::map <vmime::size_t, vmime::shared_ptr <vmime::net::message> > MessageList;
|
||||||
MessageList msgList;
|
MessageList msgList;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::vector <std::string> choices;
|
std::vector <std::string> choices;
|
||||||
|
|
||||||
choices.push_back("Show message flags");
|
choices.push_back("Show message flags");
|
||||||
@ -470,8 +492,8 @@ static void connectStore()
|
|||||||
vmime::shared_ptr <vmime::net::message> msg;
|
vmime::shared_ptr <vmime::net::message> msg;
|
||||||
|
|
||||||
if (choice == 1 || choice == 2 || choice == 3 || choice == 4 ||
|
if (choice == 1 || choice == 2 || choice == 3 || choice == 4 ||
|
||||||
choice == 5 || choice == 6 || choice == 11)
|
choice == 5 || choice == 6 || choice == 11) {
|
||||||
{
|
|
||||||
std::cout << "Enter message number: ";
|
std::cout << "Enter message number: ";
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
@ -483,20 +505,20 @@ static void connectStore()
|
|||||||
vmime::size_t num = 0;
|
vmime::size_t num = 0;
|
||||||
iss >> num;
|
iss >> num;
|
||||||
|
|
||||||
if (num < 1 || num > f->getMessageCount())
|
if (num < 1 || num > f->getMessageCount()) {
|
||||||
{
|
|
||||||
std::cerr << "Invalid message number." << std::endl;
|
std::cerr << "Invalid message number." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageList::iterator it = msgList.find(num);
|
MessageList::iterator it = msgList.find(num);
|
||||||
|
|
||||||
if (it != msgList.end())
|
if (it != msgList.end()) {
|
||||||
{
|
|
||||||
msg = (*it).second;
|
msg = (*it).second;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
msg = f->getMessage(num);
|
msg = f->getMessage(num);
|
||||||
msgList.insert(MessageList::value_type(num, msg));
|
msgList.insert(MessageList::value_type(num, msg));
|
||||||
}
|
}
|
||||||
@ -504,25 +526,31 @@ static void connectStore()
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (choice)
|
switch (choice) {
|
||||||
{
|
|
||||||
// Show message flags
|
// Show message flags
|
||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
f->fetchMessage(msg, vmime::net::fetchAttributes::FLAGS);
|
f->fetchMessage(msg, vmime::net::fetchAttributes::FLAGS);
|
||||||
|
|
||||||
if (msg->getFlags() & vmime::net::message::FLAG_SEEN)
|
if (msg->getFlags() & vmime::net::message::FLAG_SEEN) {
|
||||||
std::cout << "FLAG_SEEN" << std::endl;
|
std::cout << "FLAG_SEEN" << std::endl;
|
||||||
if (msg->getFlags() & vmime::net::message::FLAG_RECENT)
|
}
|
||||||
|
if (msg->getFlags() & vmime::net::message::FLAG_RECENT) {
|
||||||
std::cout << "FLAG_RECENT" << std::endl;
|
std::cout << "FLAG_RECENT" << std::endl;
|
||||||
if (msg->getFlags() & vmime::net::message::FLAG_REPLIED)
|
}
|
||||||
|
if (msg->getFlags() & vmime::net::message::FLAG_REPLIED) {
|
||||||
std::cout << "FLAG_REPLIED" << std::endl;
|
std::cout << "FLAG_REPLIED" << std::endl;
|
||||||
if (msg->getFlags() & vmime::net::message::FLAG_DELETED)
|
}
|
||||||
|
if (msg->getFlags() & vmime::net::message::FLAG_DELETED) {
|
||||||
std::cout << "FLAG_DELETED" << std::endl;
|
std::cout << "FLAG_DELETED" << std::endl;
|
||||||
if (msg->getFlags() & vmime::net::message::FLAG_MARKED)
|
}
|
||||||
|
if (msg->getFlags() & vmime::net::message::FLAG_MARKED) {
|
||||||
std::cout << "FLAG_MARKED" << std::endl;
|
std::cout << "FLAG_MARKED" << std::endl;
|
||||||
if (msg->getFlags() & vmime::net::message::FLAG_PASSED)
|
}
|
||||||
|
if (msg->getFlags() & vmime::net::message::FLAG_PASSED) {
|
||||||
std::cout << "FLAG_PASSED" << std::endl;
|
std::cout << "FLAG_PASSED" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -541,8 +569,8 @@ static void connectStore()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Show message envelope
|
// Show message envelope
|
||||||
case 4:
|
case 4: {
|
||||||
{
|
|
||||||
vmime::net::fetchAttributes attr(vmime::net::fetchAttributes::ENVELOPE);
|
vmime::net::fetchAttributes attr(vmime::net::fetchAttributes::ENVELOPE);
|
||||||
|
|
||||||
// If you also want to fetch "Received: " fields:
|
// If you also want to fetch "Received: " fields:
|
||||||
@ -555,37 +583,38 @@ static void connectStore()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Extract whole message
|
// Extract whole message
|
||||||
case 5:
|
case 5: {
|
||||||
{
|
|
||||||
vmime::utility::outputStreamAdapter out(std::cout);
|
vmime::utility::outputStreamAdapter out(std::cout);
|
||||||
msg->extract(out);
|
msg->extract(out);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Extract attachments
|
// Extract attachments
|
||||||
case 6:
|
case 6: {
|
||||||
{
|
|
||||||
vmime::shared_ptr <vmime::message> parsedMsg = msg->getParsedMessage();
|
vmime::shared_ptr <vmime::message> parsedMsg = msg->getParsedMessage();
|
||||||
|
|
||||||
std::vector <vmime::shared_ptr <const vmime::attachment> > attchs =
|
std::vector <vmime::shared_ptr <const vmime::attachment> > attchs =
|
||||||
vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg);
|
vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg);
|
||||||
|
|
||||||
if (attchs.size() > 0)
|
if (attchs.size() > 0) {
|
||||||
{
|
|
||||||
std::cout << attchs.size() << " attachments found." << std::endl;
|
std::cout << attchs.size() << " attachments found." << std::endl;
|
||||||
|
|
||||||
for (std::vector <vmime::shared_ptr <const vmime::attachment> >::iterator
|
for (std::vector <vmime::shared_ptr <const vmime::attachment> >::iterator
|
||||||
it = attchs.begin() ; it != attchs.end() ; ++it)
|
it = attchs.begin() ; it != attchs.end() ; ++it) {
|
||||||
{
|
|
||||||
vmime::shared_ptr <const vmime::attachment> att = *it;
|
vmime::shared_ptr <const vmime::attachment> att = *it;
|
||||||
|
|
||||||
// Get attachment size
|
// Get attachment size
|
||||||
vmime::size_t size = 0;
|
vmime::size_t size = 0;
|
||||||
|
|
||||||
if (att->getData()->isEncoded())
|
if (att->getData()->isEncoded()) {
|
||||||
size = att->getData()->getEncoding().getEncoder()->getDecodedSize(att->getData()->getLength());
|
size = att->getData()->getEncoding().getEncoder()->getDecodedSize(att->getData()->getLength());
|
||||||
else
|
} else {
|
||||||
size = att->getData()->getLength();
|
size = att->getData()->getLength();
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << "Found attachment '" << att->getName().getBuffer() << "'"
|
std::cout << "Found attachment '" << att->getName().getBuffer() << "'"
|
||||||
<< ", size is " << size << " bytes:" << std::endl;
|
<< ", size is " << size << " bytes:" << std::endl;
|
||||||
@ -618,17 +647,17 @@ static void connectStore()
|
|||||||
att->getData()->extract(*output.get());
|
att->getData()->extract(*output.get());
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
std::cout << "No attachments found." << std::endl;
|
std::cout << "No attachments found." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Status
|
// Status
|
||||||
case 7:
|
case 7: {
|
||||||
{
|
|
||||||
vmime::size_t count, unseen;
|
vmime::size_t count, unseen;
|
||||||
f->status(count, unseen);
|
f->status(count, unseen);
|
||||||
|
|
||||||
@ -636,17 +665,16 @@ static void connectStore()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// List folders
|
// List folders
|
||||||
case 8:
|
case 8: {
|
||||||
{
|
|
||||||
vmime::shared_ptr <vmime::net::folder>
|
vmime::shared_ptr <vmime::net::folder> root = st->getRootFolder();
|
||||||
root = st->getRootFolder();
|
|
||||||
|
|
||||||
printFolders(root);
|
printFolders(root);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Change folder
|
// Change folder
|
||||||
case 9:
|
case 9: {
|
||||||
{
|
|
||||||
std::cout << "Enter folder path (eg. /root/subfolder):" << std::endl;
|
std::cout << "Enter folder path (eg. /root/subfolder):" << std::endl;
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
@ -655,20 +683,22 @@ static void connectStore()
|
|||||||
|
|
||||||
vmime::shared_ptr <vmime::net::folder> newFolder = st->getRootFolder();
|
vmime::shared_ptr <vmime::net::folder> newFolder = st->getRootFolder();
|
||||||
|
|
||||||
for (std::string::size_type s = 0, p = 0 ; ; s = p + 1)
|
for (std::string::size_type s = 0, p = 0 ; ; s = p + 1) {
|
||||||
{
|
|
||||||
p = path.find_first_of('/', s);
|
p = path.find_first_of('/', s);
|
||||||
|
|
||||||
const std::string x = (p == std::string::npos)
|
const std::string x = (p == std::string::npos)
|
||||||
? std::string(path.begin() + s, path.end())
|
? std::string(path.begin() + s, path.end())
|
||||||
: std::string(path.begin() + s, path.begin() + p);
|
: std::string(path.begin() + s, path.begin() + p);
|
||||||
|
|
||||||
if (!x.empty())
|
if (!x.empty()) {
|
||||||
newFolder = newFolder->getFolder(vmime::utility::path::component(x));
|
newFolder = newFolder->getFolder(vmime::utility::path::component(x));
|
||||||
|
}
|
||||||
|
|
||||||
if (p == std::string::npos)
|
if (p == std::string::npos) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newFolder->open(vmime::net::folder::MODE_READ_WRITE);
|
newFolder->open(vmime::net::folder::MODE_READ_WRITE);
|
||||||
|
|
||||||
@ -683,8 +713,8 @@ static void connectStore()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Add message
|
// Add message
|
||||||
case 10:
|
case 10: {
|
||||||
{
|
|
||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||||
@ -694,32 +724,35 @@ static void connectStore()
|
|||||||
mb.setRecipients(to);
|
mb.setRecipients(to);
|
||||||
|
|
||||||
mb.setSubject(vmime::text("Test message from VMime example6"));
|
mb.setSubject(vmime::text("Test message from VMime example6"));
|
||||||
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
|
mb.getTextPart()->setText(
|
||||||
"Body of test message from VMime example6."));
|
vmime::make_shared <vmime::stringContentHandler>(
|
||||||
|
"Body of test message from VMime example6."
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
||||||
|
|
||||||
vmime::net::messageSet set = f->addMessage(msg);
|
vmime::net::messageSet set = f->addMessage(msg);
|
||||||
|
|
||||||
if (set.isEmpty())
|
if (set.isEmpty()) {
|
||||||
{
|
|
||||||
std::cout << "Message has successfully been added, "
|
std::cout << "Message has successfully been added, "
|
||||||
<< "but its UID/number is not known." << std::endl;
|
<< "but its UID/number is not known." << std::endl;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const vmime::net::messageRange& range = set.getRangeAt(0);
|
const vmime::net::messageRange& range = set.getRangeAt(0);
|
||||||
|
|
||||||
if (set.isUIDSet())
|
if (set.isUIDSet()) {
|
||||||
{
|
|
||||||
const vmime::net::message::uid uid =
|
const vmime::net::message::uid uid =
|
||||||
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
|
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
std::cout << "Message has successfully been added, "
|
std::cout << "Message has successfully been added, "
|
||||||
<< "its UID is '" << uid << "'." << std::endl;
|
<< "its UID is '" << uid << "'." << std::endl;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const vmime::size_t number =
|
const vmime::size_t number =
|
||||||
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
|
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
@ -731,30 +764,30 @@ static void connectStore()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Copy message
|
// Copy message
|
||||||
case 11:
|
case 11: {
|
||||||
{
|
|
||||||
vmime::net::messageSet set = f->copyMessages(f->getFullPath(),
|
vmime::net::messageSet set = f->copyMessages(f->getFullPath(),
|
||||||
vmime::net::messageSet::byNumber(msg->getNumber()));
|
vmime::net::messageSet::byNumber(msg->getNumber()));
|
||||||
|
|
||||||
if (set.isEmpty())
|
if (set.isEmpty()) {
|
||||||
{
|
|
||||||
std::cout << "Message has successfully been copied, "
|
std::cout << "Message has successfully been copied, "
|
||||||
<< "but its UID/number is not known." << std::endl;
|
<< "but its UID/number is not known." << std::endl;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const vmime::net::messageRange& range = set.getRangeAt(0);
|
const vmime::net::messageRange& range = set.getRangeAt(0);
|
||||||
|
|
||||||
if (set.isUIDSet())
|
if (set.isUIDSet()) {
|
||||||
{
|
|
||||||
const vmime::net::message::uid uid =
|
const vmime::net::message::uid uid =
|
||||||
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
|
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
std::cout << "Message has successfully been copied, "
|
std::cout << "Message has successfully been copied, "
|
||||||
<< "its UID is '" << uid << "'." << std::endl;
|
<< "its UID is '" << uid << "'." << std::endl;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const vmime::size_t number =
|
const vmime::size_t number =
|
||||||
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
|
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
@ -808,35 +841,37 @@ static void connectStore()
|
|||||||
{
|
{
|
||||||
vmime::shared_ptr <vmime::net::folder> g = st->getFolder(vmime::net::folder::path("TEMP"));
|
vmime::shared_ptr <vmime::net::folder> g = st->getFolder(vmime::net::folder::path("TEMP"));
|
||||||
|
|
||||||
if (!g->exists())
|
if (!g->exists()) {
|
||||||
g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES);
|
g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES);
|
||||||
|
}
|
||||||
|
|
||||||
f->copyMessages(g->getFullPath());
|
f->copyMessages(g->getFullPath());
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << e << std::endl;
|
std::cerr << e << std::endl;
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "std::exception: " << e.what() << std::endl;
|
std::cerr << "std::exception: " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // for(cont)
|
} // for(cont)
|
||||||
|
|
||||||
st->disconnect();
|
st->disconnect();
|
||||||
}
|
|
||||||
catch (vmime::exception& e)
|
} catch (vmime::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << e << std::endl;
|
std::cerr << e << std::endl;
|
||||||
throw;
|
throw;
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
} catch (std::exception& e) {
|
||||||
{
|
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "std::exception: " << e.what() << std::endl;
|
std::cerr << "std::exception: " << e.what() << std::endl;
|
||||||
throw;
|
throw;
|
||||||
@ -848,16 +883,16 @@ static void connectStore()
|
|||||||
*
|
*
|
||||||
* @return true to quit the program, false to continue
|
* @return true to quit the program, false to continue
|
||||||
*/
|
*/
|
||||||
static bool menu()
|
static bool menu() {
|
||||||
{
|
|
||||||
std::vector <std::string> items;
|
std::vector <std::string> items;
|
||||||
|
|
||||||
items.push_back("Connect to a message store");
|
items.push_back("Connect to a message store");
|
||||||
items.push_back("Send a message");
|
items.push_back("Send a message");
|
||||||
items.push_back("Quit");
|
items.push_back("Quit");
|
||||||
|
|
||||||
switch (printMenu(items))
|
switch (printMenu(items)) {
|
||||||
{
|
|
||||||
// Connect to store
|
// Connect to store
|
||||||
case 1:
|
case 1:
|
||||||
|
|
||||||
@ -883,25 +918,21 @@ static bool menu()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
// Set the global C and C++ locale to the user-configured locale.
|
// Set the global C and C++ locale to the user-configured locale.
|
||||||
// The locale should use UTF-8 encoding for these tests to run successfully.
|
// The locale should use UTF-8 encoding for these tests to run successfully.
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::locale::global(std::locale(""));
|
std::locale::global(std::locale(""));
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception &)
|
|
||||||
{
|
|
||||||
std::setlocale(LC_ALL, "");
|
std::setlocale(LC_ALL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (bool quit = false ; !quit ; )
|
for (bool quit = false ; !quit ; ) {
|
||||||
{
|
|
||||||
// Loop on main menu
|
// Loop on main menu
|
||||||
quit = menu();
|
quit = menu();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,52 +3,57 @@
|
|||||||
#if VMIME_HAVE_SASL_SUPPORT
|
#if VMIME_HAVE_SASL_SUPPORT
|
||||||
|
|
||||||
// SASL authentication handler
|
// SASL authentication handler
|
||||||
class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator
|
class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator {
|
||||||
{
|
|
||||||
const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> > getAcceptableMechanisms
|
const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >
|
||||||
(const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >& available,
|
getAcceptableMechanisms(
|
||||||
vmime::shared_ptr <vmime::security::sasl::SASLMechanism> suggested) const
|
const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >& available,
|
||||||
{
|
const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& suggested
|
||||||
|
) const {
|
||||||
|
|
||||||
std::cout << std::endl << "Available SASL mechanisms:" << std::endl;
|
std::cout << std::endl << "Available SASL mechanisms:" << std::endl;
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < available.size() ; ++i)
|
for (unsigned int i = 0 ; i < available.size() ; ++i) {
|
||||||
{
|
|
||||||
std::cout << " " << available[i]->getName();
|
std::cout << " " << available[i]->getName();
|
||||||
|
|
||||||
if (suggested && available[i]->getName() == suggested->getName())
|
if (suggested && available[i]->getName() == suggested->getName()) {
|
||||||
std::cout << "(suggested)";
|
std::cout << "(suggested)";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << std::endl << std::endl;
|
std::cout << std::endl << std::endl;
|
||||||
|
|
||||||
return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested);
|
return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSASLMechanism(vmime::shared_ptr <vmime::security::sasl::SASLMechanism> mech)
|
void setSASLMechanism(const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& mech) {
|
||||||
{
|
|
||||||
std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl;
|
std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl;
|
||||||
|
|
||||||
defaultSASLAuthenticator::setSASLMechanism(mech);
|
defaultSASLAuthenticator::setSASLMechanism(mech);
|
||||||
}
|
}
|
||||||
|
|
||||||
const vmime::string getUsername() const
|
const vmime::string getUsername() const {
|
||||||
{
|
|
||||||
if (m_username.empty())
|
if (m_username.empty()) {
|
||||||
m_username = getUserInput("Username");
|
m_username = getUserInput("Username");
|
||||||
|
}
|
||||||
|
|
||||||
return m_username;
|
return m_username;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vmime::string getPassword() const
|
const vmime::string getPassword() const {
|
||||||
{
|
|
||||||
if (m_password.empty())
|
if (m_password.empty()) {
|
||||||
m_password = getUserInput("Password");
|
m_password = getUserInput("Password");
|
||||||
|
}
|
||||||
|
|
||||||
return m_password;
|
return m_password;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const vmime::string getUserInput(const std::string& prompt)
|
static const vmime::string getUserInput(const std::string& prompt) {
|
||||||
{
|
|
||||||
std::cout << prompt << ": ";
|
std::cout << prompt << ": ";
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
@ -67,26 +72,28 @@ private:
|
|||||||
#else // !VMIME_HAVE_SASL_SUPPORT
|
#else // !VMIME_HAVE_SASL_SUPPORT
|
||||||
|
|
||||||
// Simple authentication handler
|
// Simple authentication handler
|
||||||
class interactiveAuthenticator : public vmime::security::defaultAuthenticator
|
class interactiveAuthenticator : public vmime::security::defaultAuthenticator {
|
||||||
{
|
|
||||||
const vmime::string getUsername() const
|
const vmime::string getUsername() const {
|
||||||
{
|
|
||||||
if (m_username.empty())
|
if (m_username.empty()) {
|
||||||
m_username = getUserInput("Username");
|
m_username = getUserInput("Username");
|
||||||
|
}
|
||||||
|
|
||||||
return m_username;
|
return m_username;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vmime::string getPassword() const
|
const vmime::string getPassword() const {
|
||||||
{
|
|
||||||
if (m_password.empty())
|
if (m_password.empty()) {
|
||||||
m_password = getUserInput("Password");
|
m_password = getUserInput("Password");
|
||||||
|
}
|
||||||
|
|
||||||
return m_password;
|
return m_password;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const vmime::string getUserInput(const std::string& prompt)
|
static const vmime::string getUserInput(const std::string& prompt) {
|
||||||
{
|
|
||||||
std::cout << prompt << ": ";
|
std::cout << prompt << ": ";
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
|
|
||||||
@ -103,4 +110,3 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif // VMIME_HAVE_SASL_SUPPORT
|
#endif // VMIME_HAVE_SASL_SUPPORT
|
||||||
|
|
||||||
|
@ -3,20 +3,23 @@
|
|||||||
#if VMIME_HAVE_TLS_SUPPORT
|
#if VMIME_HAVE_TLS_SUPPORT
|
||||||
|
|
||||||
// Certificate verifier (TLS/SSL)
|
// Certificate verifier (TLS/SSL)
|
||||||
class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier
|
class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void verify(vmime::shared_ptr <vmime::security::cert::certificateChain> chain, const vmime::string& hostname)
|
void verify(
|
||||||
{
|
const vmime::shared_ptr <vmime::security::cert::certificateChain>& chain,
|
||||||
try
|
const vmime::string& hostname
|
||||||
{
|
) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
setX509TrustedCerts(m_trustedCerts);
|
setX509TrustedCerts(m_trustedCerts);
|
||||||
|
|
||||||
defaultCertificateVerifier::verify(chain, hostname);
|
defaultCertificateVerifier::verify(chain, hostname);
|
||||||
}
|
|
||||||
catch (vmime::security::cert::certificateException&)
|
} catch (vmime::security::cert::certificateException&) {
|
||||||
{
|
|
||||||
// Obtain subject's certificate
|
// Obtain subject's certificate
|
||||||
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
|
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
|
||||||
|
|
||||||
@ -29,13 +32,14 @@ public:
|
|||||||
std::getline(std::cin, answer);
|
std::getline(std::cin, answer);
|
||||||
|
|
||||||
if (answer.length() != 0 &&
|
if (answer.length() != 0 &&
|
||||||
(answer[0] == 'Y' || answer[0] == 'y'))
|
(answer[0] == 'Y' || answer[0] == 'y')) {
|
||||||
{
|
|
||||||
// Accept it, and remember user's choice for later
|
// Accept it, and remember user's choice for later
|
||||||
if (cert->getType() == "X.509")
|
if (cert->getType() == "X.509") {
|
||||||
{
|
|
||||||
m_trustedCerts.push_back(vmime::dynamicCast
|
m_trustedCerts.push_back(
|
||||||
<vmime::security::cert::X509Certificate>(cert));
|
vmime::dynamicCast <vmime::security::cert::X509Certificate>(cert)
|
||||||
|
);
|
||||||
|
|
||||||
setX509TrustedCerts(m_trustedCerts);
|
setX509TrustedCerts(m_trustedCerts);
|
||||||
defaultCertificateVerifier::verify(chain, hostname);
|
defaultCertificateVerifier::verify(chain, hostname);
|
||||||
@ -44,8 +48,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw vmime::security::cert::certificateException
|
throw vmime::security::cert::certificateException("User did not accept the certificate.");
|
||||||
("User did not accept the certificate.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,4 +62,3 @@ std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> >
|
|||||||
interactiveCertificateVerifier::m_trustedCerts;
|
interactiveCertificateVerifier::m_trustedCerts;
|
||||||
|
|
||||||
#endif // VMIME_HAVE_TLS_SUPPORT
|
#endif // VMIME_HAVE_TLS_SUPPORT
|
||||||
|
|
||||||
|
@ -5,17 +5,17 @@
|
|||||||
* Used to stop the current operation after too much time, or if the user
|
* Used to stop the current operation after too much time, or if the user
|
||||||
* requested cancellation.
|
* requested cancellation.
|
||||||
*/
|
*/
|
||||||
class timeoutHandler : public vmime::net::timeoutHandler
|
class timeoutHandler : public vmime::net::timeoutHandler {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
timeoutHandler()
|
timeoutHandler()
|
||||||
: m_start(time(NULL))
|
: m_start(time(NULL)) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isTimeOut()
|
bool isTimeOut() {
|
||||||
{
|
|
||||||
// This is a cancellation point: return true if you want to cancel
|
// This is a cancellation point: return true if you want to cancel
|
||||||
// the current operation. If you return true, handleTimeOut() will
|
// the current operation. If you return true, handleTimeOut() will
|
||||||
// be called just after this, and before actually cancelling the
|
// be called just after this, and before actually cancelling the
|
||||||
@ -25,15 +25,15 @@ public:
|
|||||||
return (time(NULL) - m_start) >= 10; // seconds
|
return (time(NULL) - m_start) >= 10; // seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetTimeOut()
|
void resetTimeOut() {
|
||||||
{
|
|
||||||
// Called at the beginning of an operation (eg. connecting,
|
// Called at the beginning of an operation (eg. connecting,
|
||||||
// a read() or a write() on a socket...)
|
// a read() or a write() on a socket...)
|
||||||
m_start = time(NULL);
|
m_start = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handleTimeOut()
|
bool handleTimeOut() {
|
||||||
{
|
|
||||||
// If isTimeOut() returned true, this function will be called. This
|
// If isTimeOut() returned true, this function will be called. This
|
||||||
// allows you to interact with the user, ie. display a prompt to
|
// allows you to interact with the user, ie. display a prompt to
|
||||||
// know whether he wants to cancel the operation.
|
// know whether he wants to cancel the operation.
|
||||||
@ -49,13 +49,12 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
|
class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
vmime::shared_ptr <vmime::net::timeoutHandler> create()
|
vmime::shared_ptr <vmime::net::timeoutHandler> create() {
|
||||||
{
|
|
||||||
return vmime::make_shared <timeoutHandler>();
|
return vmime::make_shared <timeoutHandler>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,25 +1,29 @@
|
|||||||
|
|
||||||
/** Tracer used to demonstrate logging communication between client and server.
|
/** Tracer used to demonstrate logging communication between client and server.
|
||||||
*/
|
*/
|
||||||
|
class myTracer : public vmime::net::tracer {
|
||||||
|
|
||||||
class myTracer : public vmime::net::tracer
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
myTracer(vmime::shared_ptr <std::ostringstream> stream,
|
myTracer(
|
||||||
vmime::shared_ptr <vmime::net::service> serv, const int connectionId)
|
const vmime::shared_ptr <std::ostringstream>& stream,
|
||||||
: m_stream(stream), m_service(serv), m_connectionId(connectionId)
|
const vmime::shared_ptr <vmime::net::service>& serv,
|
||||||
{
|
const int connectionId
|
||||||
|
)
|
||||||
|
: m_stream(stream),
|
||||||
|
m_service(serv),
|
||||||
|
m_connectionId(connectionId) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void traceSend(const vmime::string& line)
|
void traceSend(const vmime::string& line) {
|
||||||
{
|
|
||||||
*m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId
|
*m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId
|
||||||
<< "] C: " << line << std::endl;
|
<< "] C: " << line << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void traceReceive(const vmime::string& line)
|
void traceReceive(const vmime::string& line) {
|
||||||
{
|
|
||||||
*m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId
|
*m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId
|
||||||
<< "] S: " << line << std::endl;
|
<< "] S: " << line << std::endl;
|
||||||
}
|
}
|
||||||
@ -31,18 +35,21 @@ private:
|
|||||||
const int m_connectionId;
|
const int m_connectionId;
|
||||||
};
|
};
|
||||||
|
|
||||||
class myTracerFactory : public vmime::net::tracerFactory
|
|
||||||
{
|
class myTracerFactory : public vmime::net::tracerFactory {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
myTracerFactory(vmime::shared_ptr <std::ostringstream> stream)
|
myTracerFactory(const vmime::shared_ptr <std::ostringstream>& stream)
|
||||||
: m_stream(stream)
|
: m_stream(stream) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vmime::shared_ptr <vmime::net::tracer> create
|
vmime::shared_ptr <vmime::net::tracer> create(
|
||||||
(vmime::shared_ptr <vmime::net::service> serv, const int connectionId)
|
const vmime::shared_ptr <vmime::net::service>& serv,
|
||||||
{
|
const int connectionId
|
||||||
|
) {
|
||||||
|
|
||||||
return vmime::make_shared <myTracer>(m_stream, serv, connectionId);
|
return vmime::make_shared <myTracer>(m_stream, serv, connectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,4 +57,3 @@ private:
|
|||||||
|
|
||||||
vmime::shared_ptr <std::ostringstream> m_stream;
|
vmime::shared_ptr <std::ostringstream> m_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -39,16 +39,16 @@
|
|||||||
#include "vmime/platforms/posix/posixHandler.hpp"
|
#include "vmime/platforms/posix/posixHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
|
||||||
// Enumerate encoders
|
// Enumerate encoders
|
||||||
vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
|
vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
|
||||||
vmime::utility::encoder::encoderFactory::getInstance();
|
vmime::utility::encoder::encoderFactory::getInstance();
|
||||||
|
|
||||||
std::cout << "Available encoders:" << std::endl;
|
std::cout << "Available encoders:" << std::endl;
|
||||||
|
|
||||||
for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i)
|
for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i) {
|
||||||
{
|
|
||||||
vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
|
vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
|
||||||
enc = ef->getEncoderAt(i);
|
enc = ef->getEncoderAt(i);
|
||||||
|
|
||||||
@ -59,9 +59,10 @@ int main()
|
|||||||
|
|
||||||
std::vector <vmime::string> props = e->getAvailableProperties();
|
std::vector <vmime::string> props = e->getAvailableProperties();
|
||||||
|
|
||||||
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
|
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it) {
|
||||||
std::cout << " - " << *it << std::endl;
|
std::cout << " - " << *it << std::endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
@ -71,8 +72,8 @@ int main()
|
|||||||
|
|
||||||
std::cout << "Available messaging services:" << std::endl;
|
std::cout << "Available messaging services:" << std::endl;
|
||||||
|
|
||||||
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i)
|
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) {
|
||||||
{
|
|
||||||
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
||||||
|
|
||||||
std::cout << " * " << serv.getName() << std::endl;
|
std::cout << " * " << serv.getName() << std::endl;
|
||||||
@ -81,16 +82,15 @@ int main()
|
|||||||
serv.getInfos().getAvailableProperties();
|
serv.getInfos().getAvailableProperties();
|
||||||
|
|
||||||
for (std::vector <vmime::net::serviceInfos::property>::const_iterator it = props.begin() ;
|
for (std::vector <vmime::net::serviceInfos::property>::const_iterator it = props.begin() ;
|
||||||
it != props.end() ; ++it)
|
it != props.end() ; ++it) {
|
||||||
{
|
|
||||||
const vmime::net::serviceInfos::property& p = *it;
|
const vmime::net::serviceInfos::property& p = *it;
|
||||||
|
|
||||||
const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName();
|
const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName();
|
||||||
|
|
||||||
vmime::string type;
|
vmime::string type;
|
||||||
|
|
||||||
switch (p.getType())
|
switch (p.getType()) {
|
||||||
{
|
|
||||||
case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
|
case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
|
||||||
case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
|
case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
|
||||||
case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break;
|
case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break;
|
||||||
@ -99,10 +99,12 @@ int main()
|
|||||||
|
|
||||||
vmime::string flags;
|
vmime::string flags;
|
||||||
|
|
||||||
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED)
|
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED) {
|
||||||
flags += " FLAG_REQUIRED";
|
flags += " FLAG_REQUIRED";
|
||||||
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN)
|
}
|
||||||
|
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN) {
|
||||||
flags += " FLAG_HIDDEN";
|
flags += " FLAG_HIDDEN";
|
||||||
|
}
|
||||||
|
|
||||||
std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName();
|
std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName();
|
||||||
std::cout << " (type=" << type << ", flags=" << flags;
|
std::cout << " (type=" << type << ", flags=" << flags;
|
||||||
@ -111,5 +113,6 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -53,8 +53,12 @@ vmime::shared_ptr <vmime::message> currentMessage;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void insertRowInModel(GtkTreeStore* model, vmime::shared_ptr <vmime::component> comp, GtkTreeIter* parent = NULL)
|
void insertRowInModel(
|
||||||
{
|
GtkTreeStore* model,
|
||||||
|
vmime::shared_ptr <vmime::component> comp,
|
||||||
|
GtkTreeIter* parent = NULL
|
||||||
|
) {
|
||||||
|
|
||||||
GtkTreeIter iter;
|
GtkTreeIter iter;
|
||||||
|
|
||||||
gtk_tree_store_append(model, &iter, parent);
|
gtk_tree_store_append(model, &iter, parent);
|
||||||
@ -62,15 +66,14 @@ void insertRowInModel(GtkTreeStore* model, vmime::shared_ptr <vmime::component>
|
|||||||
|
|
||||||
const std::vector <vmime::shared_ptr <vmime::component> > children = comp->getChildComponents();
|
const std::vector <vmime::shared_ptr <vmime::component> > children = comp->getChildComponents();
|
||||||
|
|
||||||
for (int i = 0 ; i < children.size() ; ++i)
|
for (int i = 0 ; i < children.size() ; ++i) {
|
||||||
{
|
|
||||||
insertRowInModel(model, children[i], &iter);
|
insertRowInModel(model, children[i], &iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void updateTreeView()
|
void updateTreeView() {
|
||||||
{
|
|
||||||
GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));
|
GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));
|
||||||
|
|
||||||
g_object_ref(model);
|
g_object_ref(model);
|
||||||
@ -85,8 +88,8 @@ void updateTreeView()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData)
|
static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData) {
|
||||||
{
|
|
||||||
GtkTreePath* path = NULL;
|
GtkTreePath* path = NULL;
|
||||||
GtkTreeViewColumn* col = NULL;
|
GtkTreeViewColumn* col = NULL;
|
||||||
|
|
||||||
@ -112,19 +115,18 @@ static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void destroy(GtkWidget* widget, gpointer data)
|
static void destroy(GtkWidget* widget, gpointer data) {
|
||||||
{
|
|
||||||
gtk_main_quit();
|
gtk_main_quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void openFile(const std::string& filename)
|
void openFile(const std::string& filename) {
|
||||||
{
|
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
file.open(filename.c_str(), std::ios::in | std::ios::binary);
|
file.open(filename.c_str(), std::ios::in | std::ios::binary);
|
||||||
|
|
||||||
if (!file)
|
if (!file) {
|
||||||
{
|
|
||||||
std::cerr << "Can't open file '" << filename << "'." << std::endl;
|
std::cerr << "Can't open file '" << filename << "'." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -132,12 +134,10 @@ void openFile(const std::string& filename)
|
|||||||
vmime::string data;
|
vmime::string data;
|
||||||
char buffer[16384];
|
char buffer[16384];
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
file.read(buffer, sizeof(buffer));
|
file.read(buffer, sizeof(buffer));
|
||||||
data += vmime::string(buffer, file.gcount());
|
data += vmime::string(buffer, file.gcount());
|
||||||
}
|
} while (file.gcount());
|
||||||
while (file.gcount());
|
|
||||||
|
|
||||||
vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
|
vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
|
||||||
msg->parse(data);
|
msg->parse(data);
|
||||||
@ -147,13 +147,13 @@ void openFile(const std::string& filename)
|
|||||||
char* convData = g_convert_with_fallback(data.c_str(), data.length(),
|
char* convData = g_convert_with_fallback(data.c_str(), data.length(),
|
||||||
"UTF-8", "ISO-8859-1", "?", NULL, NULL, NULL);
|
"UTF-8", "ISO-8859-1", "?", NULL, NULL, NULL);
|
||||||
|
|
||||||
if (convData == NULL)
|
if (!convData) {
|
||||||
{
|
|
||||||
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)),
|
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)),
|
||||||
"GLib UTF-8 conversion error.", -1);
|
"GLib UTF-8 conversion error.", -1);
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)),
|
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)),
|
||||||
convData, strlen(convData));
|
convData, strlen(convData));
|
||||||
|
|
||||||
@ -164,16 +164,19 @@ void openFile(const std::string& filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void onFileOpen()
|
static void onFileOpen() {
|
||||||
{
|
|
||||||
GtkWidget* dlg = gtk_file_chooser_dialog_new
|
GtkWidget* dlg = gtk_file_chooser_dialog_new(
|
||||||
("Open Message File", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
|
"Open Message File",
|
||||||
|
GTK_WINDOW(window),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||||
NULL);
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) {
|
||||||
|
|
||||||
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT)
|
|
||||||
{
|
|
||||||
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
|
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
|
||||||
|
|
||||||
openFile(filename);
|
openFile(filename);
|
||||||
@ -187,8 +190,7 @@ static void onFileOpen()
|
|||||||
|
|
||||||
|
|
||||||
// UI definitions
|
// UI definitions
|
||||||
static const GtkActionEntry uiActions[] =
|
static const GtkActionEntry uiActions[] = {
|
||||||
{
|
|
||||||
{ "FileMenu", NULL, "_File" },
|
{ "FileMenu", NULL, "_File" },
|
||||||
{ "FileOpen", GTK_STOCK_OPEN, "_Open...", "<control>O", NULL, G_CALLBACK(onFileOpen) },
|
{ "FileOpen", GTK_STOCK_OPEN, "_Open...", "<control>O", NULL, G_CALLBACK(onFileOpen) },
|
||||||
{ "FileExit", GTK_STOCK_QUIT, "_Exit", "<control>Q", NULL, G_CALLBACK(gtk_main_quit) }
|
{ "FileExit", GTK_STOCK_QUIT, "_Exit", "<control>Q", NULL, G_CALLBACK(gtk_main_quit) }
|
||||||
@ -205,8 +207,8 @@ static const char* uiDefinition =
|
|||||||
"</ui>";
|
"</ui>";
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[]) {
|
||||||
{
|
|
||||||
// VMime initialization
|
// VMime initialization
|
||||||
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
|
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
|
||||||
|
|
||||||
@ -290,5 +292,3 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -29,12 +29,11 @@
|
|||||||
#include "vmime/parserHelpers.hpp"
|
#include "vmime/parserHelpers.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
address::address()
|
address::address() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,10 +65,15 @@ address-list = (address *("," address)) / obs-addr-list
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
shared_ptr <address> address::parseNext
|
shared_ptr <address> address::parseNext(
|
||||||
(const parsingContext& ctx, const string& buffer, const size_t position,
|
const parsingContext& ctx,
|
||||||
const size_t end, size_t* newPosition, bool *isLastAddressOfGroup)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition,
|
||||||
|
bool *isLastAddressOfGroup
|
||||||
|
) {
|
||||||
|
|
||||||
bool escaped = false;
|
bool escaped = false;
|
||||||
bool quoted = false;
|
bool quoted = false;
|
||||||
bool quotedRFC2047 = false;
|
bool quotedRFC2047 = false;
|
||||||
@ -78,36 +82,45 @@ shared_ptr <address> address::parseNext
|
|||||||
bool stop = false;
|
bool stop = false;
|
||||||
int commentLevel = 0;
|
int commentLevel = 0;
|
||||||
|
|
||||||
if (isLastAddressOfGroup)
|
if (isLastAddressOfGroup) {
|
||||||
*isLastAddressOfGroup = false;
|
*isLastAddressOfGroup = false;
|
||||||
|
}
|
||||||
|
|
||||||
size_t pos = position;
|
size_t pos = position;
|
||||||
|
|
||||||
while (pos < end && parserHelpers::isSpace(buffer[pos]))
|
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
|
||||||
++pos;
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t start = pos;
|
const size_t start = pos;
|
||||||
|
|
||||||
while (!stop && pos < end)
|
while (!stop && pos < end) {
|
||||||
{
|
|
||||||
if (escaped)
|
if (escaped) {
|
||||||
{
|
|
||||||
escaped = false;
|
escaped = false;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
switch (buffer[pos])
|
switch (buffer[pos]) {
|
||||||
{
|
|
||||||
case '\\':
|
case '\\':
|
||||||
|
|
||||||
escaped = true;
|
escaped = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
|
|
||||||
quoted = !quoted;
|
quoted = !quoted;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
|
|
||||||
inRouteAddr = true;
|
inRouteAddr = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>':
|
case '>':
|
||||||
|
|
||||||
inRouteAddr = false;
|
inRouteAddr = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -118,15 +131,15 @@ shared_ptr <address> address::parseNext
|
|||||||
|
|
||||||
case ')':
|
case ')':
|
||||||
|
|
||||||
if (commentLevel > 0)
|
if (commentLevel > 0) {
|
||||||
--commentLevel;
|
--commentLevel;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
|
|
||||||
if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?')
|
if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?') {
|
||||||
{
|
|
||||||
++pos;
|
++pos;
|
||||||
quotedRFC2047 = true;
|
quotedRFC2047 = true;
|
||||||
}
|
}
|
||||||
@ -135,8 +148,7 @@ shared_ptr <address> address::parseNext
|
|||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
|
|
||||||
if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=')
|
if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=') {
|
||||||
{
|
|
||||||
++pos;
|
++pos;
|
||||||
quotedRFC2047 = false;
|
quotedRFC2047 = false;
|
||||||
}
|
}
|
||||||
@ -145,20 +157,22 @@ shared_ptr <address> address::parseNext
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr)
|
if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr) {
|
||||||
{
|
|
||||||
switch (buffer[pos])
|
switch (buffer[pos]) {
|
||||||
{
|
|
||||||
case ';':
|
case ';':
|
||||||
|
|
||||||
if (isGroup)
|
if (isGroup) {
|
||||||
{
|
|
||||||
if (pos + 1 < end && buffer[pos + 1] == ',')
|
if (pos + 1 < end && buffer[pos + 1] == ',') {
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isLastAddressOfGroup)
|
if (isLastAddressOfGroup) {
|
||||||
*isLastAddressOfGroup = true;
|
*isLastAddressOfGroup = true;
|
||||||
|
}
|
||||||
|
|
||||||
stop = true;
|
stop = true;
|
||||||
break;
|
break;
|
||||||
@ -170,7 +184,10 @@ shared_ptr <address> address::parseNext
|
|||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
|
|
||||||
if (!isGroup) stop = true;
|
if (!isGroup) {
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,32 +198,35 @@ shared_ptr <address> address::parseNext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stop)
|
if (!stop) {
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
{
|
|
||||||
if (pos == end)
|
if (pos == end) {
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
else
|
} else {
|
||||||
*newPosition = pos + 1; // ',' or ';'
|
*newPosition = pos + 1; // ',' or ';'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parse extracted address (mailbox or group)
|
// Parse extracted address (mailbox or group)
|
||||||
if (pos != start)
|
if (pos != start) {
|
||||||
{
|
|
||||||
shared_ptr <address> parsedAddress;
|
shared_ptr <address> parsedAddress;
|
||||||
|
|
||||||
if (isGroup)
|
if (isGroup) {
|
||||||
parsedAddress = make_shared <mailboxGroup>();
|
parsedAddress = make_shared <mailboxGroup>();
|
||||||
else
|
} else {
|
||||||
parsedAddress = make_shared <mailbox>();
|
parsedAddress = make_shared <mailbox>();
|
||||||
|
}
|
||||||
|
|
||||||
parsedAddress->parse(ctx, buffer, start, pos, NULL);
|
parsedAddress->parse(ctx, buffer, start, pos, NULL);
|
||||||
parsedAddress->setParsedBounds(start, pos);
|
parsedAddress->setParsedBounds(start, pos);
|
||||||
|
|
||||||
return (parsedAddress);
|
return parsedAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -29,8 +29,7 @@
|
|||||||
#include "vmime/headerFieldValue.hpp"
|
#include "vmime/headerFieldValue.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Abstract class representing a mailbox or a group of mailboxes.
|
/** Abstract class representing a mailbox or a group of mailboxes.
|
||||||
@ -38,9 +37,8 @@ namespace vmime
|
|||||||
* This class define a common behaviour for the mailbox
|
* This class define a common behaviour for the mailbox
|
||||||
* and mailboxGroup classes.
|
* and mailboxGroup classes.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT address : public headerFieldValue {
|
||||||
|
|
||||||
class VMIME_EXPORT address : public headerFieldValue
|
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
address();
|
address();
|
||||||
@ -74,10 +72,14 @@ public:
|
|||||||
* of a group (end delimiter was found), or false otherwise (may be set to NULL)
|
* of a group (end delimiter was found), or false otherwise (may be set to NULL)
|
||||||
* @return a new address object, or null if no more address is available in the input buffer
|
* @return a new address object, or null if no more address is available in the input buffer
|
||||||
*/
|
*/
|
||||||
static shared_ptr <address> parseNext
|
static shared_ptr <address> parseNext(
|
||||||
(const parsingContext& ctx, const string& buffer,
|
const parsingContext& ctx,
|
||||||
const size_t position, const size_t end,
|
const string& buffer,
|
||||||
size_t* newPosition, bool *isLastAddressOfGroup);
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition,
|
||||||
|
bool *isLastAddressOfGroup
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -28,181 +28,204 @@
|
|||||||
#include "vmime/mailboxGroup.hpp"
|
#include "vmime/mailboxGroup.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
addressList::addressList()
|
addressList::addressList() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addressList::addressList(const addressList& addrList)
|
addressList::addressList(const addressList& addrList)
|
||||||
: headerFieldValue()
|
: headerFieldValue() {
|
||||||
{
|
|
||||||
copyFrom(addrList);
|
copyFrom(addrList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addressList::~addressList()
|
addressList::~addressList() {
|
||||||
{
|
|
||||||
removeAllAddresses();
|
removeAllAddresses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::parseImpl
|
void addressList::parseImpl(
|
||||||
(const parsingContext& ctx, const string& buffer, const size_t position,
|
const parsingContext& ctx,
|
||||||
const size_t end, size_t* newPosition)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
removeAllAddresses();
|
removeAllAddresses();
|
||||||
|
|
||||||
size_t pos = position;
|
size_t pos = position;
|
||||||
|
|
||||||
while (pos < end)
|
while (pos < end) {
|
||||||
{
|
|
||||||
shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL);
|
shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL);
|
||||||
|
|
||||||
if (parsedAddress != NULL)
|
if (parsedAddress) {
|
||||||
m_list.push_back(parsedAddress);
|
m_list.push_back(parsedAddress);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setParsedBounds(position, end);
|
setParsedBounds(position, end);
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::generateImpl
|
void addressList::generateImpl(
|
||||||
(const generationContext& ctx, utility::outputStream& os,
|
const generationContext& ctx,
|
||||||
const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t curLinePos,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
size_t pos = curLinePos;
|
size_t pos = curLinePos;
|
||||||
|
|
||||||
generationContext tmpCtx(ctx);
|
generationContext tmpCtx(ctx);
|
||||||
tmpCtx.setMaxLineLength(tmpCtx.getMaxLineLength() - 2);
|
tmpCtx.setMaxLineLength(tmpCtx.getMaxLineLength() - 2);
|
||||||
|
|
||||||
if (!m_list.empty())
|
if (!m_list.empty()) {
|
||||||
{
|
|
||||||
for (std::vector <shared_ptr <address> >::const_iterator i = m_list.begin() ; ; )
|
for (std::vector <shared_ptr <address> >::const_iterator i = m_list.begin() ; ; ) {
|
||||||
{
|
|
||||||
(*i)->generate(ctx, os, pos, &pos);
|
(*i)->generate(ctx, os, pos, &pos);
|
||||||
|
|
||||||
if (++i == m_list.end())
|
if (++i == m_list.end()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
os << ", ";
|
os << ", ";
|
||||||
pos += 2;
|
pos += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newLinePos)
|
if (newLinePos) {
|
||||||
*newLinePos = pos;
|
*newLinePos = pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::copyFrom(const component& other)
|
void addressList::copyFrom(const component& other) {
|
||||||
{
|
|
||||||
const addressList& addrList = dynamic_cast <const addressList&>(other);
|
const addressList& addrList = dynamic_cast <const addressList&>(other);
|
||||||
|
|
||||||
removeAllAddresses();
|
removeAllAddresses();
|
||||||
|
|
||||||
for (std::vector <shared_ptr <address> >::const_iterator it = addrList.m_list.begin() ;
|
for (std::vector <shared_ptr <address> >::const_iterator it = addrList.m_list.begin() ;
|
||||||
it != addrList.m_list.end() ; ++it)
|
it != addrList.m_list.end() ; ++it) {
|
||||||
{
|
|
||||||
m_list.push_back(vmime::clone(*it));
|
m_list.push_back(vmime::clone(*it));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addressList& addressList::operator=(const addressList& other)
|
addressList& addressList::operator=(const addressList& other) {
|
||||||
{
|
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addressList& addressList::operator=(const mailboxList& other)
|
addressList& addressList::operator=(const mailboxList& other) {
|
||||||
{
|
|
||||||
removeAllAddresses();
|
removeAllAddresses();
|
||||||
|
|
||||||
for (size_t i = 0 ; i < other.getMailboxCount() ; ++i)
|
for (size_t i = 0 ; i < other.getMailboxCount() ; ++i) {
|
||||||
m_list.push_back(dynamicCast <address>(other.getMailboxAt(i)->clone()));
|
m_list.push_back(dynamicCast <address>(other.getMailboxAt(i)->clone()));
|
||||||
|
}
|
||||||
|
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component> addressList::clone() const
|
shared_ptr <component> addressList::clone() const {
|
||||||
{
|
|
||||||
return make_shared <addressList>(*this);
|
return make_shared <addressList>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::appendAddress(shared_ptr <address> addr)
|
void addressList::appendAddress(const shared_ptr <address> &addr) {
|
||||||
{
|
|
||||||
m_list.push_back(addr);
|
m_list.push_back(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::insertAddressBefore(shared_ptr <address> beforeAddress, shared_ptr <address> addr)
|
void addressList::insertAddressBefore(const shared_ptr <address>& beforeAddress, const shared_ptr <address>& addr) {
|
||||||
{
|
|
||||||
const std::vector <shared_ptr <address> >::iterator it = std::find
|
|
||||||
(m_list.begin(), m_list.end(), beforeAddress);
|
|
||||||
|
|
||||||
if (it == m_list.end())
|
const std::vector <shared_ptr <address> >::iterator it = std::find(
|
||||||
|
m_list.begin(), m_list.end(), beforeAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
if (it == m_list.end()) {
|
||||||
throw std::out_of_range("Invalid position");
|
throw std::out_of_range("Invalid position");
|
||||||
|
}
|
||||||
|
|
||||||
m_list.insert(it, addr);
|
m_list.insert(it, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::insertAddressBefore(const size_t pos, shared_ptr <address> addr)
|
void addressList::insertAddressBefore(const size_t pos, const shared_ptr <address>& addr) {
|
||||||
{
|
|
||||||
if (pos >= m_list.size())
|
if (pos >= m_list.size()) {
|
||||||
throw std::out_of_range("Invalid position");
|
throw std::out_of_range("Invalid position");
|
||||||
|
}
|
||||||
|
|
||||||
m_list.insert(m_list.begin() + pos, addr);
|
m_list.insert(m_list.begin() + pos, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::insertAddressAfter(shared_ptr <address> afterAddress, shared_ptr <address> addr)
|
void addressList::insertAddressAfter(
|
||||||
{
|
const shared_ptr <address>& afterAddress,
|
||||||
const std::vector <shared_ptr <address> >::iterator it = std::find
|
const shared_ptr <address>& addr
|
||||||
(m_list.begin(), m_list.end(), afterAddress);
|
) {
|
||||||
|
|
||||||
if (it == m_list.end())
|
const std::vector <shared_ptr <address> >::iterator it = std::find(
|
||||||
|
m_list.begin(), m_list.end(), afterAddress
|
||||||
|
);
|
||||||
|
|
||||||
|
if (it == m_list.end()) {
|
||||||
throw std::out_of_range("Invalid position");
|
throw std::out_of_range("Invalid position");
|
||||||
|
}
|
||||||
|
|
||||||
m_list.insert(it + 1, addr);
|
m_list.insert(it + 1, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::insertAddressAfter(const size_t pos, shared_ptr <address> addr)
|
void addressList::insertAddressAfter(const size_t pos, const shared_ptr <address>& addr) {
|
||||||
{
|
|
||||||
if (pos >= m_list.size())
|
if (pos >= m_list.size()) {
|
||||||
throw std::out_of_range("Invalid position");
|
throw std::out_of_range("Invalid position");
|
||||||
|
}
|
||||||
|
|
||||||
m_list.insert(m_list.begin() + pos + 1, addr);
|
m_list.insert(m_list.begin() + pos + 1, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::removeAddress(shared_ptr <address> addr)
|
void addressList::removeAddress(const shared_ptr <address>& addr) {
|
||||||
{
|
|
||||||
const std::vector <shared_ptr <address> >::iterator it = std::find
|
|
||||||
(m_list.begin(), m_list.end(), addr);
|
|
||||||
|
|
||||||
if (it == m_list.end())
|
const std::vector <shared_ptr <address> >::iterator it = std::find(
|
||||||
|
m_list.begin(), m_list.end(), addr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (it == m_list.end()) {
|
||||||
throw std::out_of_range("Invalid position");
|
throw std::out_of_range("Invalid position");
|
||||||
|
}
|
||||||
|
|
||||||
m_list.erase(it);
|
m_list.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::removeAddress(const size_t pos)
|
void addressList::removeAddress(const size_t pos) {
|
||||||
{
|
|
||||||
if (pos >= m_list.size())
|
if (pos >= m_list.size()) {
|
||||||
throw std::out_of_range("Invalid position");
|
throw std::out_of_range("Invalid position");
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector <shared_ptr <address> >::iterator it = m_list.begin() + pos;
|
const std::vector <shared_ptr <address> >::iterator it = m_list.begin() + pos;
|
||||||
|
|
||||||
@ -210,90 +233,90 @@ void addressList::removeAddress(const size_t pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::removeAllAddresses()
|
void addressList::removeAllAddresses() {
|
||||||
{
|
|
||||||
m_list.clear();
|
m_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t addressList::getAddressCount() const
|
size_t addressList::getAddressCount() const {
|
||||||
{
|
|
||||||
return (m_list.size());
|
return m_list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool addressList::isEmpty() const
|
bool addressList::isEmpty() const {
|
||||||
{
|
|
||||||
return (m_list.empty());
|
return m_list.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <address> addressList::getAddressAt(const size_t pos)
|
shared_ptr <address> addressList::getAddressAt(const size_t pos) {
|
||||||
{
|
|
||||||
return (m_list[pos]);
|
return m_list[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const shared_ptr <const address> addressList::getAddressAt(const size_t pos) const
|
const shared_ptr <const address> addressList::getAddressAt(const size_t pos) const {
|
||||||
{
|
|
||||||
return (m_list[pos]);
|
return m_list[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <const address> > addressList::getAddressList() const
|
const std::vector <shared_ptr <const address> > addressList::getAddressList() const {
|
||||||
{
|
|
||||||
std::vector <shared_ptr <const address> > list;
|
std::vector <shared_ptr <const address> > list;
|
||||||
|
|
||||||
list.reserve(m_list.size());
|
list.reserve(m_list.size());
|
||||||
|
|
||||||
for (std::vector <shared_ptr <address> >::const_iterator it = m_list.begin() ;
|
for (std::vector <shared_ptr <address> >::const_iterator it = m_list.begin() ;
|
||||||
it != m_list.end() ; ++it)
|
it != m_list.end() ; ++it) {
|
||||||
{
|
|
||||||
list.push_back(*it);
|
list.push_back(*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (list);
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <address> > addressList::getAddressList()
|
const std::vector <shared_ptr <address> > addressList::getAddressList() {
|
||||||
{
|
|
||||||
return (m_list);
|
return m_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <component> > addressList::getChildComponents()
|
const std::vector <shared_ptr <component> > addressList::getChildComponents() {
|
||||||
{
|
|
||||||
std::vector <shared_ptr <component> > list;
|
std::vector <shared_ptr <component> > list;
|
||||||
|
|
||||||
copy_vector(m_list, list);
|
copy_vector(m_list, list);
|
||||||
|
|
||||||
return (list);
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <mailboxList> addressList::toMailboxList() const
|
shared_ptr <mailboxList> addressList::toMailboxList() const {
|
||||||
{
|
|
||||||
shared_ptr <mailboxList> res = make_shared <mailboxList>();
|
shared_ptr <mailboxList> res = make_shared <mailboxList>();
|
||||||
|
|
||||||
for (std::vector <shared_ptr <address> >::const_iterator it = m_list.begin() ;
|
for (std::vector <shared_ptr <address> >::const_iterator it = m_list.begin() ;
|
||||||
it != m_list.end() ; ++it)
|
it != m_list.end() ; ++it) {
|
||||||
{
|
|
||||||
shared_ptr <const address> addr = *it;
|
shared_ptr <const address> addr = *it;
|
||||||
|
|
||||||
if (addr->isGroup())
|
if (addr->isGroup()) {
|
||||||
{
|
|
||||||
const std::vector <shared_ptr <const mailbox> > mailboxes =
|
const std::vector <shared_ptr <const mailbox> > mailboxes =
|
||||||
dynamicCast <const mailboxGroup>(addr)->getMailboxList();
|
dynamicCast <const mailboxGroup>(addr)->getMailboxList();
|
||||||
|
|
||||||
for (std::vector <shared_ptr <const mailbox> >::const_iterator jt = mailboxes.begin() ;
|
for (std::vector <shared_ptr <const mailbox> >::const_iterator jt = mailboxes.begin() ;
|
||||||
jt != mailboxes.end() ; ++jt)
|
jt != mailboxes.end() ; ++jt) {
|
||||||
{
|
|
||||||
res->appendMailbox(vmime::clone(*jt));
|
res->appendMailbox(vmime::clone(*jt));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
res->appendMailbox(dynamicCast <mailbox>(addr->clone()));
|
res->appendMailbox(dynamicCast <mailbox>(addr->clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -31,8 +31,7 @@
|
|||||||
#include "vmime/address.hpp"
|
#include "vmime/address.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class mailboxList;
|
class mailboxList;
|
||||||
@ -40,9 +39,8 @@ class mailboxList;
|
|||||||
|
|
||||||
/** A list of addresses.
|
/** A list of addresses.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT addressList : public headerFieldValue {
|
||||||
|
|
||||||
class VMIME_EXPORT addressList : public headerFieldValue
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
addressList();
|
addressList();
|
||||||
@ -63,7 +61,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param addr address to append
|
* @param addr address to append
|
||||||
*/
|
*/
|
||||||
void appendAddress(shared_ptr <address> addr);
|
void appendAddress(const shared_ptr <address>& addr);
|
||||||
|
|
||||||
/** Insert a new address before the specified address.
|
/** Insert a new address before the specified address.
|
||||||
*
|
*
|
||||||
@ -71,7 +69,10 @@ public:
|
|||||||
* @param addr address to insert
|
* @param addr address to insert
|
||||||
* @throw std::out_of_range if the address is not in the list
|
* @throw std::out_of_range if the address is not in the list
|
||||||
*/
|
*/
|
||||||
void insertAddressBefore(shared_ptr <address> beforeAddress, shared_ptr <address> addr);
|
void insertAddressBefore(
|
||||||
|
const shared_ptr <address>& beforeAddress,
|
||||||
|
const shared_ptr <address>& addr
|
||||||
|
);
|
||||||
|
|
||||||
/** Insert a new address before the specified position.
|
/** Insert a new address before the specified position.
|
||||||
*
|
*
|
||||||
@ -80,7 +81,7 @@ public:
|
|||||||
* @param addr address to insert
|
* @param addr address to insert
|
||||||
* @throw std::out_of_range if the position is out of range
|
* @throw std::out_of_range if the position is out of range
|
||||||
*/
|
*/
|
||||||
void insertAddressBefore(const size_t pos, shared_ptr <address> addr);
|
void insertAddressBefore(const size_t pos, const shared_ptr <address>& addr);
|
||||||
|
|
||||||
/** Insert a new address after the specified address.
|
/** Insert a new address after the specified address.
|
||||||
*
|
*
|
||||||
@ -88,7 +89,10 @@ public:
|
|||||||
* @param addr address to insert
|
* @param addr address to insert
|
||||||
* @throw std::out_of_range if the address is not in the list
|
* @throw std::out_of_range if the address is not in the list
|
||||||
*/
|
*/
|
||||||
void insertAddressAfter(shared_ptr <address> afterAddress, shared_ptr <address> addr);
|
void insertAddressAfter(
|
||||||
|
const shared_ptr <address>& afterAddress,
|
||||||
|
const shared_ptr <address>& addr
|
||||||
|
);
|
||||||
|
|
||||||
/** Insert a new address after the specified position.
|
/** Insert a new address after the specified position.
|
||||||
*
|
*
|
||||||
@ -96,14 +100,14 @@ public:
|
|||||||
* @param addr address to insert
|
* @param addr address to insert
|
||||||
* @throw std::out_of_range if the position is out of range
|
* @throw std::out_of_range if the position is out of range
|
||||||
*/
|
*/
|
||||||
void insertAddressAfter(const size_t pos, shared_ptr <address> addr);
|
void insertAddressAfter(const size_t pos, const shared_ptr <address>& addr);
|
||||||
|
|
||||||
/** Remove the specified address from the list.
|
/** Remove the specified address from the list.
|
||||||
*
|
*
|
||||||
* @param addr address to remove
|
* @param addr address to remove
|
||||||
* @throw std::out_of_range if the address is not in the list
|
* @throw std::out_of_range if the address is not in the list
|
||||||
*/
|
*/
|
||||||
void removeAddress(shared_ptr <address> addr);
|
void removeAddress(const shared_ptr <address>& addr);
|
||||||
|
|
||||||
/** Remove the address at the specified position.
|
/** Remove the address at the specified position.
|
||||||
*
|
*
|
||||||
@ -171,18 +175,20 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parseImpl
|
void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,15 +34,13 @@
|
|||||||
#include "vmime/encoding.hpp"
|
#include "vmime/encoding.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Base class for all types of attachment.
|
/** Base class for all types of attachment.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT attachment : public object {
|
||||||
|
|
||||||
class VMIME_EXPORT attachment : public object
|
|
||||||
{
|
|
||||||
friend class messageBuilder;
|
friend class messageBuilder;
|
||||||
friend class messageParser;
|
friend class messageParser;
|
||||||
friend class attachmentHelper;
|
friend class attachmentHelper;
|
||||||
@ -108,7 +106,7 @@ protected:
|
|||||||
*
|
*
|
||||||
* @param parent body part in which to generate the attachment
|
* @param parent body part in which to generate the attachment
|
||||||
*/
|
*/
|
||||||
virtual void generateIn(shared_ptr <bodyPart> parent) const = 0;
|
virtual void generateIn(const shared_ptr <bodyPart>& parent) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -33,36 +33,39 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool attachmentHelper::isBodyPartAnAttachment
|
bool attachmentHelper::isBodyPartAnAttachment(
|
||||||
(shared_ptr <const bodyPart> part, const unsigned int options)
|
const shared_ptr <const bodyPart>& part,
|
||||||
{
|
const unsigned int options
|
||||||
|
) {
|
||||||
|
|
||||||
// First, try with "Content-Disposition" field.
|
// First, try with "Content-Disposition" field.
|
||||||
// If not present, we will try with "Content-Type" field.
|
// If not present, we will try with "Content-Type" field.
|
||||||
shared_ptr <const contentDispositionField> cdf =
|
shared_ptr <const contentDispositionField> cdf =
|
||||||
part->getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
|
part->getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
|
||||||
|
|
||||||
if (cdf)
|
if (cdf) {
|
||||||
{
|
|
||||||
const contentDisposition disp = *cdf->getValue <contentDisposition>();
|
const contentDisposition disp = *cdf->getValue <contentDisposition>();
|
||||||
|
|
||||||
if (disp.getName() != contentDispositionTypes::INLINE)
|
if (disp.getName() != contentDispositionTypes::INLINE) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((options & INLINE_OBJECTS) == 0) {
|
||||||
|
|
||||||
if ((options & INLINE_OBJECTS) == 0)
|
|
||||||
{
|
|
||||||
// If the Content-Disposition is 'inline' and there is no
|
// If the Content-Disposition is 'inline' and there is no
|
||||||
// Content-Id or Content-Location field, it may be an attachment
|
// Content-Id or Content-Location field, it may be an attachment
|
||||||
if (!part->getHeader()->hasField(vmime::fields::CONTENT_ID) &&
|
if (!part->getHeader()->hasField(vmime::fields::CONTENT_ID) &&
|
||||||
!part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION))
|
!part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION)) {
|
||||||
{
|
|
||||||
// If this is the root part, it might not be an attachment
|
// If this is the root part, it might not be an attachment
|
||||||
if (part->getParentPart() == NULL)
|
if (!part->getParentPart()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -78,41 +81,47 @@ bool attachmentHelper::isBodyPartAnAttachment
|
|||||||
shared_ptr <const contentTypeField> ctf =
|
shared_ptr <const contentTypeField> ctf =
|
||||||
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||||
|
|
||||||
if (ctf)
|
if (ctf) {
|
||||||
{
|
|
||||||
type = *ctf->getValue <mediaType>();
|
type = *ctf->getValue <mediaType>();
|
||||||
|
|
||||||
if (ctf->hasParameter("name"))
|
if (ctf->hasParameter("name")) {
|
||||||
hasContentTypeName = true;
|
hasContentTypeName = true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
} else {
|
||||||
|
|
||||||
// If this is the root part and no Content-Type field is present,
|
// If this is the root part and no Content-Type field is present,
|
||||||
// then this may not be a MIME message, so do not assume it is
|
// then this may not be a MIME message, so do not assume it is
|
||||||
// an attachment
|
// an attachment
|
||||||
if (part->getParentPart() == NULL)
|
if (!part->getParentPart()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// No "Content-type" field: assume "application/octet-stream".
|
// No "Content-type" field: assume "application/octet-stream".
|
||||||
type = mediaType(mediaTypes::APPLICATION,
|
type = mediaType(
|
||||||
mediaTypes::APPLICATION_OCTET_STREAM);
|
mediaTypes::APPLICATION,
|
||||||
|
mediaTypes::APPLICATION_OCTET_STREAM
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.getType() != mediaTypes::TEXT &&
|
if (type.getType() != mediaTypes::TEXT &&
|
||||||
type.getType() != mediaTypes::MULTIPART)
|
type.getType() != mediaTypes::MULTIPART) {
|
||||||
{
|
|
||||||
// Compatibility with (obsolete) RFC-1341: if there is a "name" parameter
|
// Compatibility with (obsolete) RFC-1341: if there is a "name" parameter
|
||||||
// on the "Content-Type" field, then we assume it is an attachment
|
// on the "Content-Type" field, then we assume it is an attachment
|
||||||
if (hasContentTypeName)
|
if (hasContentTypeName) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((options & INLINE_OBJECTS) == 0) {
|
||||||
|
|
||||||
if ((options & INLINE_OBJECTS) == 0)
|
|
||||||
{
|
|
||||||
// If a "Content-Id" field is present, it might be an
|
// If a "Content-Id" field is present, it might be an
|
||||||
// embedded object (MHTML messages)
|
// embedded object (MHTML messages)
|
||||||
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID))
|
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -122,35 +131,40 @@ bool attachmentHelper::isBodyPartAnAttachment
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment
|
shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment(
|
||||||
(shared_ptr <const bodyPart> part, const unsigned int options)
|
const shared_ptr <const bodyPart>& part,
|
||||||
{
|
const unsigned int options
|
||||||
if (!isBodyPartAnAttachment(part, options))
|
) {
|
||||||
|
|
||||||
|
if (!isBodyPartAnAttachment(part, options)) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
mediaType type;
|
mediaType type;
|
||||||
|
|
||||||
shared_ptr <const contentTypeField> ctf =
|
shared_ptr <const contentTypeField> ctf =
|
||||||
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||||
|
|
||||||
if (ctf)
|
if (ctf) {
|
||||||
{
|
|
||||||
type = *ctf->getValue <mediaType>();
|
type = *ctf->getValue <mediaType>();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// No "Content-type" field: assume "application/octet-stream".
|
// No "Content-type" field: assume "application/octet-stream".
|
||||||
type = mediaType(mediaTypes::APPLICATION,
|
type = mediaType(
|
||||||
mediaTypes::APPLICATION_OCTET_STREAM);
|
mediaTypes::APPLICATION,
|
||||||
|
mediaTypes::APPLICATION_OCTET_STREAM
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.getType() == mediaTypes::MESSAGE &&
|
if (type.getType() == mediaTypes::MESSAGE &&
|
||||||
type.getSubType() == mediaTypes::MESSAGE_RFC822)
|
type.getSubType() == mediaTypes::MESSAGE_RFC822) {
|
||||||
{
|
|
||||||
return make_shared <generatedMessageAttachment>(part);
|
return make_shared <generatedMessageAttachment>(part);
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
return make_shared <bodyPartAttachment>(part);
|
return make_shared <bodyPartAttachment>(part);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,32 +172,36 @@ shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
const std::vector <shared_ptr <const attachment> >
|
const std::vector <shared_ptr <const attachment> >
|
||||||
attachmentHelper::findAttachmentsInMessage
|
attachmentHelper::findAttachmentsInMessage(
|
||||||
(shared_ptr <const message> msg, const unsigned int options)
|
const shared_ptr <const message>& msg,
|
||||||
{
|
const unsigned int options
|
||||||
|
) {
|
||||||
|
|
||||||
return findAttachmentsInBodyPart(msg, options);
|
return findAttachmentsInBodyPart(msg, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
const std::vector <shared_ptr <const attachment> >
|
const std::vector <shared_ptr <const attachment> >
|
||||||
attachmentHelper::findAttachmentsInBodyPart
|
attachmentHelper::findAttachmentsInBodyPart(
|
||||||
(shared_ptr <const bodyPart> part, const unsigned int options)
|
const shared_ptr <const bodyPart>& part,
|
||||||
{
|
const unsigned int options
|
||||||
|
) {
|
||||||
|
|
||||||
std::vector <shared_ptr <const attachment> > atts;
|
std::vector <shared_ptr <const attachment> > atts;
|
||||||
|
|
||||||
// Test this part
|
// Test this part
|
||||||
if (isBodyPartAnAttachment(part, options))
|
if (isBodyPartAnAttachment(part, options)) {
|
||||||
{
|
|
||||||
atts.push_back(getBodyPartAttachment(part, options));
|
atts.push_back(getBodyPartAttachment(part, options));
|
||||||
}
|
|
||||||
// Find in sub-parts
|
// Find in sub-parts
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
shared_ptr <const body> bdy = part->getBody();
|
shared_ptr <const body> bdy = part->getBody();
|
||||||
|
|
||||||
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i)
|
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) {
|
||||||
{
|
|
||||||
std::vector <shared_ptr <const attachment> > partAtts =
|
std::vector <shared_ptr <const attachment> > partAtts =
|
||||||
findAttachmentsInBodyPart(bdy->getPartAt(i), options);
|
findAttachmentsInBodyPart(bdy->getPartAt(i), options);
|
||||||
|
|
||||||
@ -196,35 +214,39 @@ const std::vector <shared_ptr <const attachment> >
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void attachmentHelper::addAttachment(shared_ptr <message> msg, shared_ptr <attachment> att)
|
void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shared_ptr <attachment>& att) {
|
||||||
{
|
|
||||||
// We simply search for a "multipart/mixed" part. If no one exists,
|
// We simply search for a "multipart/mixed" part. If no one exists,
|
||||||
// create it in the root part. This (very simple) algorithm should
|
// create it in the root part. This (very simple) algorithm should
|
||||||
// work in the most cases.
|
// work in the most cases.
|
||||||
|
|
||||||
vmime::mediaType mpMixed(vmime::mediaTypes::MULTIPART,
|
vmime::mediaType mpMixed(
|
||||||
vmime::mediaTypes::MULTIPART_MIXED);
|
vmime::mediaTypes::MULTIPART,
|
||||||
|
vmime::mediaTypes::MULTIPART_MIXED
|
||||||
|
);
|
||||||
|
|
||||||
shared_ptr <bodyPart> part = findBodyPart(msg, mpMixed);
|
shared_ptr <bodyPart> part = findBodyPart(msg, mpMixed);
|
||||||
|
|
||||||
if (part == NULL) // create it
|
if (!part) { // create it
|
||||||
{
|
|
||||||
if (msg->getBody()->getPartCount() != 0)
|
if (msg->getBody()->getPartCount() != 0) {
|
||||||
{
|
|
||||||
// Create a new container part for the parts that were in
|
// Create a new container part for the parts that were in
|
||||||
// the root part of the message
|
// the root part of the message
|
||||||
shared_ptr <bodyPart> container = make_shared <bodyPart>();
|
shared_ptr <bodyPart> container = make_shared <bodyPart>();
|
||||||
|
|
||||||
if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
|
if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) {
|
||||||
{
|
|
||||||
container->getHeader()->ContentType()->setValue
|
container->getHeader()->ContentType()->setValue(
|
||||||
(msg->getHeader()->ContentType()->getValue());
|
msg->getHeader()->ContentType()->getValue()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
|
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) {
|
||||||
{
|
|
||||||
container->getHeader()->ContentTransferEncoding()->setValue
|
container->getHeader()->ContentTransferEncoding()->setValue(
|
||||||
(msg->getHeader()->ContentTransferEncoding()->getValue());
|
msg->getHeader()->ContentTransferEncoding()->getValue()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move parts from the root part to this new part
|
// Move parts from the root part to this new part
|
||||||
@ -233,28 +255,31 @@ void attachmentHelper::addAttachment(shared_ptr <message> msg, shared_ptr <attac
|
|||||||
|
|
||||||
msg->getBody()->removeAllParts();
|
msg->getBody()->removeAllParts();
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < partList.size() ; ++i)
|
for (unsigned int i = 0 ; i < partList.size() ; ++i) {
|
||||||
container->getBody()->appendPart(partList[i]);
|
container->getBody()->appendPart(partList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
msg->getBody()->appendPart(container);
|
msg->getBody()->appendPart(container);
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// The message is a simple (RFC-822) message, and do not
|
// The message is a simple (RFC-822) message, and do not
|
||||||
// contains any MIME part. Move the contents from the
|
// contains any MIME part. Move the contents from the
|
||||||
// root to a new child part.
|
// root to a new child part.
|
||||||
shared_ptr <bodyPart> child = make_shared <bodyPart>();
|
shared_ptr <bodyPart> child = make_shared <bodyPart>();
|
||||||
|
|
||||||
if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
|
if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) {
|
||||||
{
|
|
||||||
child->getHeader()->ContentType()->setValue
|
child->getHeader()->ContentType()->setValue(
|
||||||
(msg->getHeader()->ContentType()->getValue());
|
msg->getHeader()->ContentType()->getValue()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
|
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) {
|
||||||
{
|
|
||||||
child->getHeader()->ContentTransferEncoding()->setValue
|
child->getHeader()->ContentTransferEncoding()->setValue(
|
||||||
(msg->getHeader()->ContentTransferEncoding()->getValue());
|
msg->getHeader()->ContentTransferEncoding()->getValue()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
child->getBody()->setContents(msg->getBody()->getContents());
|
child->getBody()->setContents(msg->getBody()->getContents());
|
||||||
@ -278,35 +303,37 @@ void attachmentHelper::addAttachment(shared_ptr <message> msg, shared_ptr <attac
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
shared_ptr <bodyPart> attachmentHelper::findBodyPart
|
shared_ptr <bodyPart> attachmentHelper::findBodyPart(
|
||||||
(shared_ptr <bodyPart> part, const mediaType& type)
|
const shared_ptr <bodyPart>& part,
|
||||||
{
|
const mediaType& type
|
||||||
if (part->getBody()->getContentType() == type)
|
) {
|
||||||
|
|
||||||
|
if (part->getBody()->getContentType() == type) {
|
||||||
return part;
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
// Try in sub-parts
|
// Try in sub-parts
|
||||||
shared_ptr <body> bdy = part->getBody();
|
shared_ptr <body> bdy = part->getBody();
|
||||||
|
|
||||||
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i)
|
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) {
|
||||||
{
|
|
||||||
shared_ptr <bodyPart> found =
|
|
||||||
findBodyPart(bdy->getPartAt(i), type);
|
|
||||||
|
|
||||||
if (found != NULL)
|
shared_ptr <bodyPart> found = findBodyPart(bdy->getPartAt(i), type);
|
||||||
|
|
||||||
|
if (found) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void attachmentHelper::addAttachment(shared_ptr <message> msg, shared_ptr <message> amsg)
|
void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shared_ptr <message>& amsg) {
|
||||||
{
|
|
||||||
shared_ptr <attachment> att = make_shared <parsedMessageAttachment>(amsg);
|
shared_ptr <attachment> att = make_shared <parsedMessageAttachment>(amsg);
|
||||||
addAttachment(msg, att);
|
addAttachment(msg, att);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -31,14 +31,13 @@
|
|||||||
#include "vmime/message.hpp"
|
#include "vmime/message.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Retrieve attachment information from message parts.
|
/** Retrieve attachment information from message parts.
|
||||||
*/
|
*/
|
||||||
class VMIME_EXPORT attachmentHelper
|
class VMIME_EXPORT attachmentHelper {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Options for use with the following functions:
|
/** Options for use with the following functions:
|
||||||
@ -46,8 +45,7 @@ public:
|
|||||||
* getBodyPartAttachment,
|
* getBodyPartAttachment,
|
||||||
* and isBodyPartAnAttachment.
|
* and isBodyPartAnAttachment.
|
||||||
*/
|
*/
|
||||||
enum FindOptions
|
enum FindOptions {
|
||||||
{
|
|
||||||
INLINE_OBJECTS = (1 << 0) /**< Recognize and return inline objects. The aim is to
|
INLINE_OBJECTS = (1 << 0) /**< Recognize and return inline objects. The aim is to
|
||||||
consider MHTML objects (parts with a "Content-Id" or
|
consider MHTML objects (parts with a "Content-Id" or
|
||||||
a "Content-Location", such as inline images) as attachments. */
|
a "Content-Location", such as inline images) as attachments. */
|
||||||
@ -59,7 +57,10 @@ public:
|
|||||||
* @param options search options (see FindOptions)
|
* @param options search options (see FindOptions)
|
||||||
* @return true if the part is an attachment, false otherwise
|
* @return true if the part is an attachment, false otherwise
|
||||||
*/
|
*/
|
||||||
static bool isBodyPartAnAttachment(shared_ptr <const bodyPart> part, const unsigned int options = 0);
|
static bool isBodyPartAnAttachment(
|
||||||
|
const shared_ptr <const bodyPart>& part,
|
||||||
|
const unsigned int options = 0
|
||||||
|
);
|
||||||
|
|
||||||
/** Return attachment information in the specified body part.
|
/** Return attachment information in the specified body part.
|
||||||
* If the specified body part does not contain attachment
|
* If the specified body part does not contain attachment
|
||||||
@ -69,8 +70,10 @@ public:
|
|||||||
* @param options search options (see FindOptions)
|
* @param options search options (see FindOptions)
|
||||||
* @return attachment found in the part, or NULL
|
* @return attachment found in the part, or NULL
|
||||||
*/
|
*/
|
||||||
static shared_ptr <const attachment>
|
static shared_ptr <const attachment> getBodyPartAttachment(
|
||||||
getBodyPartAttachment(shared_ptr <const bodyPart> part, const unsigned int options = 0);
|
const shared_ptr <const bodyPart>& part,
|
||||||
|
const unsigned int options = 0
|
||||||
|
);
|
||||||
|
|
||||||
/** Find all attachments contained in the specified part
|
/** Find all attachments contained in the specified part
|
||||||
* and all its children parts.
|
* and all its children parts.
|
||||||
@ -81,7 +84,10 @@ public:
|
|||||||
* @return a list of attachments found
|
* @return a list of attachments found
|
||||||
*/
|
*/
|
||||||
static const std::vector <shared_ptr <const attachment> >
|
static const std::vector <shared_ptr <const attachment> >
|
||||||
findAttachmentsInBodyPart(shared_ptr <const bodyPart> part, const unsigned int options = 0);
|
findAttachmentsInBodyPart(
|
||||||
|
const shared_ptr <const bodyPart>& part,
|
||||||
|
const unsigned int options = 0
|
||||||
|
);
|
||||||
|
|
||||||
/** Find all attachments contained in the specified message.
|
/** Find all attachments contained in the specified message.
|
||||||
* This is simply a recursive call to getBodyPartAttachment().
|
* This is simply a recursive call to getBodyPartAttachment().
|
||||||
@ -91,26 +97,37 @@ public:
|
|||||||
* @return a list of attachments found
|
* @return a list of attachments found
|
||||||
*/
|
*/
|
||||||
static const std::vector <shared_ptr <const attachment> >
|
static const std::vector <shared_ptr <const attachment> >
|
||||||
findAttachmentsInMessage(shared_ptr <const message> msg, const unsigned int options = 0);
|
findAttachmentsInMessage(
|
||||||
|
const shared_ptr <const message>& msg,
|
||||||
|
const unsigned int options = 0
|
||||||
|
);
|
||||||
|
|
||||||
/** Add an attachment to the specified message.
|
/** Add an attachment to the specified message.
|
||||||
*
|
*
|
||||||
* @param msg message into which to add the attachment
|
* @param msg message into which to add the attachment
|
||||||
* @param att attachment to add
|
* @param att attachment to add
|
||||||
*/
|
*/
|
||||||
static void addAttachment(shared_ptr <message> msg, shared_ptr <attachment> att);
|
static void addAttachment(
|
||||||
|
const shared_ptr <message>& msg,
|
||||||
|
const shared_ptr <attachment>& att
|
||||||
|
);
|
||||||
|
|
||||||
/** Add a message attachment to the specified message.
|
/** Add a message attachment to the specified message.
|
||||||
*
|
*
|
||||||
* @param msg message into which to add the attachment
|
* @param msg message into which to add the attachment
|
||||||
* @param amsg message to attach
|
* @param amsg message to attach
|
||||||
*/
|
*/
|
||||||
static void addAttachment(shared_ptr <message> msg, shared_ptr <message> amsg);
|
static void addAttachment(
|
||||||
|
const shared_ptr <message>& msg,
|
||||||
|
const shared_ptr <message>& amsg
|
||||||
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static shared_ptr <bodyPart> findBodyPart
|
static shared_ptr <bodyPart> findBodyPart(
|
||||||
(shared_ptr <bodyPart> part, const mediaType& type);
|
const shared_ptr <bodyPart>& part,
|
||||||
|
const mediaType& type
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -118,4 +135,3 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
#endif // VMIME_ATTACHMENTHELPER_HPP_INCLUDED
|
#endif // VMIME_ATTACHMENTHELPER_HPP_INCLUDED
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -48,8 +48,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** "Null" (empty) string.
|
/** "Null" (empty) string.
|
||||||
@ -108,8 +107,8 @@ nullPtrType null;
|
|||||||
|
|
||||||
|
|
||||||
// Line length limits
|
// Line length limits
|
||||||
namespace lineLengthLimits
|
namespace lineLengthLimits {
|
||||||
{
|
|
||||||
const size_t infinite = std::numeric_limits <size_t>::max();
|
const size_t infinite = std::numeric_limits <size_t>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,12 +133,10 @@ const size_t npos = std::numeric_limits <size_t>::max();
|
|||||||
// constructor, for example).
|
// constructor, for example).
|
||||||
//
|
//
|
||||||
|
|
||||||
class initializer
|
struct initializer {
|
||||||
{
|
|
||||||
public:
|
initializer() {
|
||||||
|
|
||||||
initializer()
|
|
||||||
{
|
|
||||||
parsingContext::getDefaultContext();
|
parsingContext::getDefaultContext();
|
||||||
generationContext::getDefaultContext();
|
generationContext::getDefaultContext();
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -37,8 +37,8 @@
|
|||||||
#include "vmime/constants.hpp"
|
#include "vmime/constants.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
class text;
|
class text;
|
||||||
class word;
|
class word;
|
||||||
class charset;
|
class charset;
|
||||||
@ -53,9 +53,9 @@ namespace vmime
|
|||||||
#ifndef VMIME_BUILDING_DOC
|
#ifndef VMIME_BUILDING_DOC
|
||||||
|
|
||||||
// Null pointer
|
// Null pointer
|
||||||
struct nullPtrType
|
struct nullPtrType {
|
||||||
{
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
operator shared_ptr <T>() { return shared_ptr <T>(); }
|
operator shared_ptr <T>() { return shared_ptr <T>(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -78,48 +78,49 @@ namespace vmime
|
|||||||
//
|
//
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline T const* cbegin(T const (&array)[N])
|
inline T const* cbegin(T const (&array)[N]) {
|
||||||
{
|
|
||||||
return (array);
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline T const* cend(T const (&array)[N])
|
inline T const* cend(T const (&array)[N]) {
|
||||||
{
|
|
||||||
return (array + N);
|
return array + N;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline T* begin(T (&array)[N])
|
inline T* begin(T (&array)[N]) {
|
||||||
{
|
|
||||||
return (array);
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline T* end(T (&array)[N])
|
inline T* end(T (&array)[N]) {
|
||||||
{
|
|
||||||
return (array + N);
|
return array + N;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline size_t count(T const (&/* array */)[N])
|
inline size_t count(T const (&/* array */)[N]) {
|
||||||
{
|
|
||||||
return (N);
|
return N;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Copy one vector to another, with type conversion
|
// Copy one vector to another, with type conversion
|
||||||
|
|
||||||
template <class T1, class T2>
|
template <class T1, class T2>
|
||||||
void copy_vector(const T1& v1, T2& v2)
|
void copy_vector(const T1& v1, T2& v2) {
|
||||||
{
|
|
||||||
const typename T1::size_type count = v1.size();
|
const typename T1::size_type count = v1.size();
|
||||||
|
|
||||||
v2.resize(count);
|
v2.resize(count);
|
||||||
|
|
||||||
for (typename T1::size_type i = 0 ; i < count ; ++i)
|
for (typename T1::size_type i = 0 ; i < count ; ++i) {
|
||||||
v2[i] = v1[i];
|
v2[i] = v1[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -154,12 +155,11 @@ namespace vmime
|
|||||||
character limit) for the sake of robustness.
|
character limit) for the sake of robustness.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace lineLengthLimits
|
namespace lineLengthLimits {
|
||||||
{
|
|
||||||
extern VMIME_EXPORT const size_t infinite;
|
extern VMIME_EXPORT const size_t infinite;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
|
||||||
max = 998,
|
max = 998,
|
||||||
convenient = 78
|
convenient = 78
|
||||||
};
|
};
|
||||||
@ -192,8 +192,8 @@ namespace vmime
|
|||||||
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
|
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
shared_ptr <T> clone(shared_ptr <T> obj)
|
shared_ptr <T> clone(const shared_ptr <T>& obj) {
|
||||||
{
|
|
||||||
return dynamic_pointer_cast <T>(obj->clone());
|
return dynamic_pointer_cast <T>(obj->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,8 +201,8 @@ namespace vmime
|
|||||||
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
|
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
shared_ptr <T> clone(shared_ptr <const T> obj)
|
shared_ptr <T> clone(const shared_ptr <const T>& obj) {
|
||||||
{
|
|
||||||
return dynamic_pointer_cast <T>(obj->clone());
|
return dynamic_pointer_cast <T>(obj->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,8 +210,8 @@ namespace vmime
|
|||||||
* This is an alias for dynamic_pointer_cast <T>(obj.clone()).
|
* This is an alias for dynamic_pointer_cast <T>(obj.clone()).
|
||||||
*/
|
*/
|
||||||
template <class T>
|
template <class T>
|
||||||
shared_ptr <T> clone(const T& obj)
|
shared_ptr <T> clone(const T& obj) {
|
||||||
{
|
|
||||||
return dynamic_pointer_cast <T>(obj.clone());
|
return dynamic_pointer_cast <T>(obj.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,24 +220,24 @@ namespace vmime
|
|||||||
* type Type, and DerivedType is derived from Type.
|
* type Type, and DerivedType is derived from Type.
|
||||||
*/
|
*/
|
||||||
template <class X, class Y>
|
template <class X, class Y>
|
||||||
shared_ptr <X> dynamicCast(shared_ptr <Y> obj)
|
shared_ptr <X> dynamicCast(const shared_ptr <Y>& obj) {
|
||||||
{
|
|
||||||
return dynamic_pointer_cast <X, Y>(obj);
|
return dynamic_pointer_cast <X, Y>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Const cast helper.
|
/** Const cast helper.
|
||||||
*/
|
*/
|
||||||
template <class X, class Y>
|
template <class X, class Y>
|
||||||
shared_ptr <X> constCast(const shared_ptr <Y>& obj)
|
shared_ptr <X> constCast(const shared_ptr <Y>& obj) {
|
||||||
{
|
|
||||||
return const_pointer_cast <X, Y>(obj);
|
return const_pointer_cast <X, Y>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Inherit from this class to indicate the subclass is not copyable,
|
/** Inherit from this class to indicate the subclass is not copyable,
|
||||||
* ie. you want to prohibit copy construction and copy assignment.
|
* ie. you want to prohibit copy construction and copy assignment.
|
||||||
*/
|
*/
|
||||||
class VMIME_EXPORT noncopyable
|
class VMIME_EXPORT noncopyable {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
noncopyable() { }
|
noncopyable() { }
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -37,8 +37,7 @@
|
|||||||
#include "vmime/contentHandler.hpp"
|
#include "vmime/contentHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class bodyPart;
|
class bodyPart;
|
||||||
@ -46,9 +45,8 @@ class bodyPart;
|
|||||||
|
|
||||||
/** Body section of a MIME part.
|
/** Body section of a MIME part.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT body : public component {
|
||||||
|
|
||||||
class VMIME_EXPORT body : public component
|
|
||||||
{
|
|
||||||
friend class bodyPart;
|
friend class bodyPart;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -60,7 +58,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param part part to append
|
* @param part part to append
|
||||||
*/
|
*/
|
||||||
void appendPart(shared_ptr <bodyPart> part);
|
void appendPart(const shared_ptr <bodyPart>& part);
|
||||||
|
|
||||||
/** Insert a new part before the specified part.
|
/** Insert a new part before the specified part.
|
||||||
*
|
*
|
||||||
@ -68,7 +66,10 @@ public:
|
|||||||
* @param part part to insert
|
* @param part part to insert
|
||||||
* @throw exceptions::no_such_part if the part is not in the list
|
* @throw exceptions::no_such_part if the part is not in the list
|
||||||
*/
|
*/
|
||||||
void insertPartBefore(shared_ptr <bodyPart> beforePart, shared_ptr <bodyPart> part);
|
void insertPartBefore(
|
||||||
|
const shared_ptr <bodyPart>& beforePart,
|
||||||
|
const shared_ptr <bodyPart>& part
|
||||||
|
);
|
||||||
|
|
||||||
/** Insert a new part before the specified position.
|
/** Insert a new part before the specified position.
|
||||||
*
|
*
|
||||||
@ -76,7 +77,7 @@ public:
|
|||||||
* the beginning of the list)
|
* the beginning of the list)
|
||||||
* @param part part to insert
|
* @param part part to insert
|
||||||
*/
|
*/
|
||||||
void insertPartBefore(const size_t pos, shared_ptr <bodyPart> part);
|
void insertPartBefore(const size_t pos, const shared_ptr <bodyPart>& part);
|
||||||
|
|
||||||
/** Insert a new part after the specified part.
|
/** Insert a new part after the specified part.
|
||||||
*
|
*
|
||||||
@ -84,21 +85,24 @@ public:
|
|||||||
* @param part part to insert
|
* @param part part to insert
|
||||||
* @throw exceptions::no_such_part if the part is not in the list
|
* @throw exceptions::no_such_part if the part is not in the list
|
||||||
*/
|
*/
|
||||||
void insertPartAfter(shared_ptr <bodyPart> afterPart, shared_ptr <bodyPart> part);
|
void insertPartAfter(
|
||||||
|
const shared_ptr <bodyPart>& afterPart,
|
||||||
|
const shared_ptr <bodyPart>& part
|
||||||
|
);
|
||||||
|
|
||||||
/** Insert a new part after the specified position.
|
/** Insert a new part after the specified position.
|
||||||
*
|
*
|
||||||
* @param pos position of the part before the new part
|
* @param pos position of the part before the new part
|
||||||
* @param part part to insert
|
* @param part part to insert
|
||||||
*/
|
*/
|
||||||
void insertPartAfter(const size_t pos, shared_ptr <bodyPart> part);
|
void insertPartAfter(const size_t pos, const shared_ptr <bodyPart>& part);
|
||||||
|
|
||||||
/** Remove the specified part from the list.
|
/** Remove the specified part from the list.
|
||||||
*
|
*
|
||||||
* @param part part to remove
|
* @param part part to remove
|
||||||
* @throw exceptions::no_such_part if the part is not in the list
|
* @throw exceptions::no_such_part if the part is not in the list
|
||||||
*/
|
*/
|
||||||
void removePart(shared_ptr <bodyPart> part);
|
void removePart(const shared_ptr <bodyPart>& part);
|
||||||
|
|
||||||
/** Remove the part at the specified position.
|
/** Remove the part at the specified position.
|
||||||
*
|
*
|
||||||
@ -182,14 +186,17 @@ public:
|
|||||||
*
|
*
|
||||||
* @param contents new body contents
|
* @param contents new body contents
|
||||||
*/
|
*/
|
||||||
void setContents(shared_ptr <const contentHandler> contents);
|
void setContents(const shared_ptr <const contentHandler>& contents);
|
||||||
|
|
||||||
/** Set the body contents and type.
|
/** Set the body contents and type.
|
||||||
*
|
*
|
||||||
* @param contents new body contents
|
* @param contents new body contents
|
||||||
* @param type type of contents
|
* @param type type of contents
|
||||||
*/
|
*/
|
||||||
void setContents(shared_ptr <const contentHandler> contents, const mediaType& type);
|
void setContents(
|
||||||
|
const shared_ptr <const contentHandler>& contents,
|
||||||
|
const mediaType& type
|
||||||
|
);
|
||||||
|
|
||||||
/** Set the body contents, type and charset.
|
/** Set the body contents, type and charset.
|
||||||
*
|
*
|
||||||
@ -197,7 +204,11 @@ public:
|
|||||||
* @param type type of contents
|
* @param type type of contents
|
||||||
* @param chset charset of contents
|
* @param chset charset of contents
|
||||||
*/
|
*/
|
||||||
void setContents(shared_ptr <const contentHandler> contents, const mediaType& type, const charset& chset);
|
void setContents(
|
||||||
|
const shared_ptr <const contentHandler>& contents,
|
||||||
|
const mediaType& type,
|
||||||
|
const charset& chset
|
||||||
|
);
|
||||||
|
|
||||||
/** Set the body contents, type, charset and encoding.
|
/** Set the body contents, type, charset and encoding.
|
||||||
*
|
*
|
||||||
@ -206,8 +217,12 @@ public:
|
|||||||
* @param chset charset of contents
|
* @param chset charset of contents
|
||||||
* @param enc contents encoding
|
* @param enc contents encoding
|
||||||
*/
|
*/
|
||||||
void setContents(shared_ptr <const contentHandler> contents, const mediaType& type,
|
void setContents(
|
||||||
const charset& chset, const encoding& enc);
|
const shared_ptr <const contentHandler>& contents,
|
||||||
|
const mediaType& type,
|
||||||
|
const charset& chset,
|
||||||
|
const encoding& enc
|
||||||
|
);
|
||||||
|
|
||||||
/** Set the MIME type and charset of contents.
|
/** Set the MIME type and charset of contents.
|
||||||
* If a charset is defined, it will not be modified.
|
* If a charset is defined, it will not be modified.
|
||||||
@ -301,7 +316,7 @@ private:
|
|||||||
|
|
||||||
bool isRootPart() const;
|
bool isRootPart() const;
|
||||||
|
|
||||||
void initNewPart(shared_ptr <bodyPart> part);
|
void initNewPart(const shared_ptr <bodyPart>& part);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -317,24 +332,30 @@ protected:
|
|||||||
* before the CRLF or "--" which follows)
|
* before the CRLF or "--" which follows)
|
||||||
* @return the position of the boundary string, or npos if not found
|
* @return the position of the boundary string, or npos if not found
|
||||||
*/
|
*/
|
||||||
size_t findNextBoundaryPosition
|
size_t findNextBoundaryPosition(
|
||||||
(shared_ptr <utility::parserInputStreamAdapter> parser, const string& boundary,
|
const shared_ptr <utility::parserInputStreamAdapter>& parser,
|
||||||
const size_t position, const size_t end,
|
const string& boundary,
|
||||||
size_t* boundaryStart, size_t* boundaryEnd);
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
|
||||||
void parseImpl
|
|
||||||
(const parsingContext& ctx,
|
|
||||||
shared_ptr <utility::parserInputStreamAdapter> parser,
|
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* boundaryStart,
|
||||||
|
size_t* boundaryEnd
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
// Component parsing & assembling
|
||||||
(const generationContext& ctx,
|
void parseImpl(
|
||||||
|
const parsingContext& ctx,
|
||||||
|
const shared_ptr <utility::parserInputStreamAdapter>& parser,
|
||||||
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
void generateImpl(
|
||||||
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -24,23 +24,26 @@
|
|||||||
#include "vmime/bodyPart.hpp"
|
#include "vmime/bodyPart.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
bodyPart::bodyPart()
|
bodyPart::bodyPart()
|
||||||
: m_header(make_shared <header>()),
|
: m_header(make_shared <header>()),
|
||||||
m_body(make_shared <body>()),
|
m_body(make_shared <body>()),
|
||||||
m_parent()
|
m_parent() {
|
||||||
{
|
|
||||||
m_body->setParentPart(this);
|
m_body->setParentPart(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::parseImpl
|
void bodyPart::parseImpl(
|
||||||
(const parsingContext& ctx, shared_ptr <utility::parserInputStreamAdapter> parser,
|
const parsingContext& ctx,
|
||||||
const size_t position, const size_t end, size_t* newPosition)
|
const shared_ptr <utility::parserInputStreamAdapter>& parser,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
// Parse the headers
|
// Parse the headers
|
||||||
size_t pos = position;
|
size_t pos = position;
|
||||||
m_header->parse(ctx, parser, pos, end, &pos);
|
m_header->parse(ctx, parser, pos, end, &pos);
|
||||||
@ -50,34 +53,39 @@ void bodyPart::parseImpl
|
|||||||
|
|
||||||
setParsedBounds(position, end);
|
setParsedBounds(position, end);
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::generateImpl
|
void bodyPart::generateImpl(
|
||||||
(const generationContext& ctx, utility::outputStream& os,
|
const generationContext& ctx,
|
||||||
const size_t /* curLinePos */, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t /* curLinePos */,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
m_header->generate(ctx, os);
|
m_header->generate(ctx, os);
|
||||||
|
|
||||||
os << CRLF;
|
os << CRLF;
|
||||||
|
|
||||||
m_body->generate(ctx, os);
|
m_body->generate(ctx, os);
|
||||||
|
|
||||||
if (newLinePos)
|
if (newLinePos) {
|
||||||
*newLinePos = 0;
|
*newLinePos = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t bodyPart::getGeneratedSize(const generationContext& ctx)
|
size_t bodyPart::getGeneratedSize(const generationContext& ctx) {
|
||||||
{
|
|
||||||
return m_header->getGeneratedSize(ctx) + 2 /* CRLF */ + m_body->getGeneratedSize(ctx);
|
return m_header->getGeneratedSize(ctx) + 2 /* CRLF */ + m_body->getGeneratedSize(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component> bodyPart::clone() const
|
shared_ptr <component> bodyPart::clone() const {
|
||||||
{
|
|
||||||
shared_ptr <bodyPart> p = make_shared <bodyPart>();
|
shared_ptr <bodyPart> p = make_shared <bodyPart>();
|
||||||
|
|
||||||
p->m_parent = NULL;
|
p->m_parent = NULL;
|
||||||
@ -85,12 +93,12 @@ shared_ptr <component> bodyPart::clone() const
|
|||||||
p->m_header->copyFrom(*m_header);
|
p->m_header->copyFrom(*m_header);
|
||||||
p->m_body->copyFrom(*m_body);
|
p->m_body->copyFrom(*m_body);
|
||||||
|
|
||||||
return (p);
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::copyFrom(const component& other)
|
void bodyPart::copyFrom(const component& other) {
|
||||||
{
|
|
||||||
const bodyPart& bp = dynamic_cast <const bodyPart&>(other);
|
const bodyPart& bp = dynamic_cast <const bodyPart&>(other);
|
||||||
|
|
||||||
m_header->copyFrom(*(bp.m_header));
|
m_header->copyFrom(*(bp.m_header));
|
||||||
@ -98,70 +106,71 @@ void bodyPart::copyFrom(const component& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bodyPart& bodyPart::operator=(const bodyPart& other)
|
bodyPart& bodyPart::operator=(const bodyPart& other) {
|
||||||
{
|
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const shared_ptr <const header> bodyPart::getHeader() const
|
const shared_ptr <const header> bodyPart::getHeader() const {
|
||||||
{
|
|
||||||
return (m_header);
|
return m_header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <header> bodyPart::getHeader()
|
shared_ptr <header> bodyPart::getHeader() {
|
||||||
{
|
|
||||||
return (m_header);
|
return m_header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::setHeader(shared_ptr <header> h)
|
void bodyPart::setHeader(const shared_ptr <header>& h) {
|
||||||
{
|
|
||||||
m_header = h;
|
m_header = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const shared_ptr <const body> bodyPart::getBody() const
|
const shared_ptr <const body> bodyPart::getBody() const {
|
||||||
{
|
|
||||||
return (m_body);
|
return m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <body> bodyPart::getBody()
|
shared_ptr <body> bodyPart::getBody() {
|
||||||
{
|
|
||||||
return (m_body);
|
return m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::setBody(shared_ptr <body> b)
|
void bodyPart::setBody(const shared_ptr <body>& b) {
|
||||||
{
|
|
||||||
bodyPart* oldPart = b->m_part;
|
bodyPart* oldPart = b->m_part;
|
||||||
|
|
||||||
m_body = b;
|
m_body = b;
|
||||||
m_body->setParentPart(this);
|
m_body->setParentPart(this);
|
||||||
|
|
||||||
// A body is associated to one and only one part
|
// A body is associated to one and only one part
|
||||||
if (oldPart != NULL)
|
if (oldPart) {
|
||||||
oldPart->setBody(make_shared <body>());
|
oldPart->setBody(make_shared <body>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bodyPart* bodyPart::getParentPart()
|
bodyPart* bodyPart::getParentPart() {
|
||||||
{
|
|
||||||
return m_parent;
|
return m_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bodyPart* bodyPart::getParentPart() const
|
const bodyPart* bodyPart::getParentPart() const {
|
||||||
{
|
|
||||||
return m_parent;
|
return m_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <bodyPart> bodyPart::createChildPart()
|
shared_ptr <bodyPart> bodyPart::createChildPart() {
|
||||||
{
|
|
||||||
shared_ptr <bodyPart> part = make_shared <bodyPart>();
|
shared_ptr <bodyPart> part = make_shared <bodyPart>();
|
||||||
part->m_parent = this;
|
part->m_parent = this;
|
||||||
|
|
||||||
@ -169,22 +178,21 @@ shared_ptr <bodyPart> bodyPart::createChildPart()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPart::importChildPart(shared_ptr <bodyPart> part)
|
void bodyPart::importChildPart(const shared_ptr <bodyPart>& part) {
|
||||||
{
|
|
||||||
part->m_parent = this;
|
part->m_parent = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <component> > bodyPart::getChildComponents()
|
const std::vector <shared_ptr <component> > bodyPart::getChildComponents() {
|
||||||
{
|
|
||||||
std::vector <shared_ptr <component> > list;
|
std::vector <shared_ptr <component> > list;
|
||||||
|
|
||||||
list.push_back(m_header);
|
list.push_back(m_header);
|
||||||
list.push_back(m_body);
|
list.push_back(m_body);
|
||||||
|
|
||||||
return (list);
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -32,15 +32,13 @@
|
|||||||
#include "vmime/body.hpp"
|
#include "vmime/body.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** A MIME part.
|
/** A MIME part.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT bodyPart : public component {
|
||||||
|
|
||||||
class VMIME_EXPORT bodyPart : public component
|
|
||||||
{
|
|
||||||
friend class body;
|
friend class body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -63,7 +61,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param header the new header of this part
|
* @param header the new header of this part
|
||||||
*/
|
*/
|
||||||
void setHeader(shared_ptr <header> header);
|
void setHeader(const shared_ptr <header>& header);
|
||||||
|
|
||||||
/** Return the body section of this part.
|
/** Return the body section of this part.
|
||||||
*
|
*
|
||||||
@ -81,7 +79,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param body new body section
|
* @param body new body section
|
||||||
*/
|
*/
|
||||||
void setBody(shared_ptr <body> body);
|
void setBody(const shared_ptr <body>& body);
|
||||||
|
|
||||||
/** Return the parent part of this part.
|
/** Return the parent part of this part.
|
||||||
*
|
*
|
||||||
@ -131,21 +129,23 @@ protected:
|
|||||||
*
|
*
|
||||||
* @param part child part to attach
|
* @param part child part to attach
|
||||||
*/
|
*/
|
||||||
void importChildPart(shared_ptr <bodyPart> part);
|
void importChildPart(const shared_ptr <bodyPart>& part);
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parseImpl
|
void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
shared_ptr <utility::parserInputStreamAdapter> parser,
|
const shared_ptr <utility::parserInputStreamAdapter>& parser,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -24,75 +24,77 @@
|
|||||||
#include "vmime/bodyPartAttachment.hpp"
|
#include "vmime/bodyPartAttachment.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
bodyPartAttachment::bodyPartAttachment(shared_ptr <const bodyPart> part)
|
bodyPartAttachment::bodyPartAttachment(const shared_ptr <const bodyPart>& part)
|
||||||
: m_part(part)
|
: m_part(part) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const mediaType bodyPartAttachment::getType() const
|
const mediaType bodyPartAttachment::getType() const {
|
||||||
{
|
|
||||||
shared_ptr <const contentTypeField> ctf = getContentType();
|
shared_ptr <const contentTypeField> ctf = getContentType();
|
||||||
|
|
||||||
if (ctf)
|
if (ctf) {
|
||||||
{
|
|
||||||
return *ctf->getValue <mediaType>();
|
return *ctf->getValue <mediaType>();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// No "Content-type" field: assume "application/octet-stream".
|
// No "Content-type" field: assume "application/octet-stream".
|
||||||
return mediaType(mediaTypes::APPLICATION,
|
return mediaType(
|
||||||
mediaTypes::APPLICATION_OCTET_STREAM);
|
mediaTypes::APPLICATION,
|
||||||
|
mediaTypes::APPLICATION_OCTET_STREAM
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const word bodyPartAttachment::getName() const
|
const word bodyPartAttachment::getName() const {
|
||||||
{
|
|
||||||
word name;
|
word name;
|
||||||
|
|
||||||
// Try the 'filename' parameter of 'Content-Disposition' field
|
// Try the 'filename' parameter of 'Content-Disposition' field
|
||||||
shared_ptr <const contentDispositionField> cdf = getContentDisposition();
|
shared_ptr <const contentDispositionField> cdf = getContentDisposition();
|
||||||
|
|
||||||
if (cdf && cdf->hasFilename())
|
if (cdf && cdf->hasFilename()) {
|
||||||
{
|
|
||||||
name = cdf->getFilename();
|
name = cdf->getFilename();
|
||||||
}
|
|
||||||
// Try the 'name' parameter of 'Content-Type' field
|
// Try the 'name' parameter of 'Content-Type' field
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
shared_ptr <const contentTypeField> ctf = getContentType();
|
shared_ptr <const contentTypeField> ctf = getContentType();
|
||||||
|
|
||||||
if (ctf)
|
if (ctf) {
|
||||||
{
|
|
||||||
shared_ptr <const parameter> prm = ctf->findParameter("name");
|
shared_ptr <const parameter> prm = ctf->findParameter("name");
|
||||||
|
|
||||||
if (prm != NULL)
|
if (prm) {
|
||||||
name = prm->getValue();
|
name = prm->getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const text bodyPartAttachment::getDescription() const
|
const text bodyPartAttachment::getDescription() const {
|
||||||
{
|
|
||||||
text description;
|
text description;
|
||||||
|
|
||||||
shared_ptr <const headerField> cd =
|
shared_ptr <const headerField> cd =
|
||||||
getHeader()->findField(fields::CONTENT_DESCRIPTION);
|
getHeader()->findField(fields::CONTENT_DESCRIPTION);
|
||||||
|
|
||||||
if (cd)
|
if (cd) {
|
||||||
{
|
|
||||||
description = *cd->getValue <text>();
|
description = *cd->getValue <text>();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// No description available.
|
// No description available.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,47 +102,46 @@ const text bodyPartAttachment::getDescription() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const encoding bodyPartAttachment::getEncoding() const
|
const encoding bodyPartAttachment::getEncoding() const {
|
||||||
{
|
|
||||||
return m_part->getBody()->getEncoding();
|
return m_part->getBody()->getEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const shared_ptr <const contentHandler> bodyPartAttachment::getData() const
|
const shared_ptr <const contentHandler> bodyPartAttachment::getData() const {
|
||||||
{
|
|
||||||
return m_part->getBody()->getContents();
|
return m_part->getBody()->getContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <const object> bodyPartAttachment::getPart() const
|
shared_ptr <const object> bodyPartAttachment::getPart() const {
|
||||||
{
|
|
||||||
return m_part;
|
return m_part;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <const header> bodyPartAttachment::getHeader() const
|
shared_ptr <const header> bodyPartAttachment::getHeader() const {
|
||||||
{
|
|
||||||
return m_part->getHeader();
|
return m_part->getHeader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <const contentDispositionField> bodyPartAttachment::getContentDisposition() const
|
shared_ptr <const contentDispositionField> bodyPartAttachment::getContentDisposition() const {
|
||||||
{
|
|
||||||
return getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
|
return getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <const contentTypeField> bodyPartAttachment::getContentType() const
|
shared_ptr <const contentTypeField> bodyPartAttachment::getContentType() const {
|
||||||
{
|
|
||||||
return getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
return getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bodyPartAttachment::generateIn(shared_ptr <bodyPart> /* parent */) const
|
void bodyPartAttachment::generateIn(const shared_ptr <bodyPart>& /* parent */) const {
|
||||||
{
|
|
||||||
// Not used
|
// Not used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,17 +34,16 @@
|
|||||||
#include "vmime/contentTypeField.hpp"
|
#include "vmime/contentTypeField.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** An attachment related to a local body part.
|
/** An attachment related to a local body part.
|
||||||
*/
|
*/
|
||||||
class VMIME_EXPORT bodyPartAttachment : public attachment
|
class VMIME_EXPORT bodyPartAttachment : public attachment {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bodyPartAttachment(shared_ptr <const bodyPart> part);
|
bodyPartAttachment(const shared_ptr <const bodyPart>& part);
|
||||||
|
|
||||||
const mediaType getType() const;
|
const mediaType getType() const;
|
||||||
const word getName() const;
|
const word getName() const;
|
||||||
@ -58,7 +57,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void generateIn(shared_ptr <bodyPart> parent) const;
|
void generateIn(const shared_ptr <bodyPart>& parent) const;
|
||||||
|
|
||||||
shared_ptr <const contentDispositionField> getContentDisposition() const;
|
shared_ptr <const contentDispositionField> getContentDisposition() const;
|
||||||
shared_ptr <const contentTypeField> getContentType() const;
|
shared_ptr <const contentTypeField> getContentType() const;
|
||||||
@ -75,4 +74,3 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
#endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED
|
#endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -32,74 +32,93 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
charset::charset()
|
charset::charset()
|
||||||
: m_name(charsets::US_ASCII)
|
: m_name(charsets::US_ASCII) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charset::charset(const string& name)
|
charset::charset(const string& name)
|
||||||
: m_name(name)
|
: m_name(name) {
|
||||||
{
|
|
||||||
// If we receive this rfc-1642 valid MIME charset, convert it to something usefull for iconv
|
// If we receive this rfc-1642 valid MIME charset, convert it to something usefull for iconv
|
||||||
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
|
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) {
|
||||||
m_name = "utf-7";
|
m_name = "utf-7";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charset::charset(const char* name)
|
charset::charset(const char* name)
|
||||||
: m_name(name)
|
: m_name(name) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charset::parseImpl
|
void charset::parseImpl(
|
||||||
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
|
const parsingContext& /* ctx */,
|
||||||
const size_t end, size_t* newPosition)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
m_name = utility::stringUtils::trim
|
const size_t end,
|
||||||
(string(buffer.begin() + position, buffer.begin() + end));
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
|
m_name = utility::stringUtils::trim(
|
||||||
|
string(buffer.begin() + position, buffer.begin() + end)
|
||||||
|
);
|
||||||
|
|
||||||
// If we parsed this rfc-1642 valid MIME charset, convert it to something usefull for iconv
|
// If we parsed this rfc-1642 valid MIME charset, convert it to something usefull for iconv
|
||||||
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
|
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) {
|
||||||
m_name = "utf-7";
|
m_name = "utf-7";
|
||||||
|
}
|
||||||
|
|
||||||
setParsedBounds(position, end);
|
setParsedBounds(position, end);
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charset::generateImpl
|
void charset::generateImpl(
|
||||||
(const generationContext& /* ctx */, utility::outputStream& os,
|
const generationContext& /* ctx */,
|
||||||
const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t curLinePos,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
os << m_name;
|
os << m_name;
|
||||||
|
|
||||||
if (newLinePos)
|
if (newLinePos) {
|
||||||
*newLinePos = curLinePos + m_name.length();
|
*newLinePos = curLinePos + m_name.length();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charset::convert(utility::inputStream& in, utility::outputStream& out,
|
void charset::convert(
|
||||||
const charset& source, const charset& dest,
|
utility::inputStream& in,
|
||||||
const charsetConverterOptions& opts)
|
utility::outputStream& out,
|
||||||
{
|
const charset& source,
|
||||||
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts
|
||||||
|
) {
|
||||||
|
|
||||||
shared_ptr <charsetConverter> conv = charsetConverter::create(source, dest, opts);
|
shared_ptr <charsetConverter> conv = charsetConverter::create(source, dest, opts);
|
||||||
conv->convert(in, out);
|
conv->convert(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charset::convert(const string& in, string& out, const charset& source, const charset& dest,
|
void charset::convert(
|
||||||
const charsetConverterOptions& opts)
|
const string& in,
|
||||||
{
|
string& out,
|
||||||
if (source == dest)
|
const charset& source,
|
||||||
{
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (source == dest) {
|
||||||
out = in;
|
out = in;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -109,27 +128,26 @@ void charset::convert(const string& in, string& out, const charset& source, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool charset::isValidText
|
bool charset::isValidText(const string& text, string::size_type* firstInvalidByte) const {
|
||||||
(const string& text, string::size_type* firstInvalidByte) const
|
|
||||||
{
|
|
||||||
charsetConverterOptions opts;
|
charsetConverterOptions opts;
|
||||||
opts.silentlyReplaceInvalidSequences = false;
|
opts.silentlyReplaceInvalidSequences = false;
|
||||||
|
|
||||||
charsetConverter::status st;
|
charsetConverter::status st;
|
||||||
|
|
||||||
try
|
try {
|
||||||
{
|
|
||||||
std::string out;
|
std::string out;
|
||||||
|
|
||||||
// Try converting to UTF-8
|
// Try converting to UTF-8
|
||||||
shared_ptr <charsetConverter> conv = charsetConverter::create(*this, vmime::charset("utf-8"), opts);
|
shared_ptr <charsetConverter> conv = charsetConverter::create(*this, vmime::charset("utf-8"), opts);
|
||||||
conv->convert(text, out, &st);
|
conv->convert(text, out, &st);
|
||||||
}
|
|
||||||
catch (exceptions::illegal_byte_sequence_for_charset& e)
|
} catch (exceptions::illegal_byte_sequence_for_charset& e) {
|
||||||
{
|
|
||||||
// An illegal byte sequence was found in the input buffer
|
// An illegal byte sequence was found in the input buffer
|
||||||
if (firstInvalidByte)
|
if (firstInvalidByte) {
|
||||||
{
|
|
||||||
if (st.inputBytesRead < text.length())
|
if (st.inputBytesRead < text.length())
|
||||||
*firstInvalidByte = st.inputBytesRead;
|
*firstInvalidByte = st.inputBytesRead;
|
||||||
else
|
else
|
||||||
@ -139,77 +157,79 @@ bool charset::isValidText
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstInvalidByte)
|
if (firstInvalidByte) {
|
||||||
*firstInvalidByte = text.length();
|
*firstInvalidByte = text.length();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const charset charset::getLocalCharset()
|
const charset charset::getLocalCharset() {
|
||||||
{
|
|
||||||
return (platform::getHandler()->getLocalCharset());
|
return platform::getHandler()->getLocalCharset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charset& charset::operator=(const charset& other)
|
charset& charset::operator=(const charset& other) {
|
||||||
{
|
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool charset::operator==(const charset& value) const
|
bool charset::operator==(const charset& value) const {
|
||||||
{
|
|
||||||
return (utility::stringUtils::isStringEqualNoCase(m_name, value.m_name));
|
return utility::stringUtils::isStringEqualNoCase(m_name, value.m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool charset::operator!=(const charset& value) const
|
bool charset::operator!=(const charset& value) const {
|
||||||
{
|
|
||||||
return !(*this == value);
|
return !(*this == value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component> charset::clone() const
|
shared_ptr <component> charset::clone() const {
|
||||||
{
|
|
||||||
return make_shared <charset>(m_name);
|
return make_shared <charset>(m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string& charset::getName() const
|
const string& charset::getName() const {
|
||||||
{
|
|
||||||
return (m_name);
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charset::copyFrom(const component& other)
|
void charset::copyFrom(const component& other) {
|
||||||
{
|
|
||||||
m_name = dynamic_cast <const charset&>(other).m_name;
|
m_name = dynamic_cast <const charset&>(other).m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <component> > charset::getChildComponents()
|
const std::vector <shared_ptr <component> > charset::getChildComponents() {
|
||||||
{
|
|
||||||
return std::vector <shared_ptr <component> >();
|
return std::vector <shared_ptr <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Explicitly force encoding for some charsets
|
// Explicitly force encoding for some charsets
|
||||||
struct CharsetEncodingEntry
|
struct CharsetEncodingEntry {
|
||||||
{
|
|
||||||
CharsetEncodingEntry(const string& charset_, const string& encoding_)
|
CharsetEncodingEntry(const string& charset_, const string& encoding_)
|
||||||
: charset(charset_), encoding(encoding_)
|
: charset(charset_), encoding(encoding_) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const string charset;
|
const string charset;
|
||||||
const string encoding;
|
const string encoding;
|
||||||
};
|
};
|
||||||
|
|
||||||
CharsetEncodingEntry g_charsetEncodingMap[] =
|
|
||||||
{
|
CharsetEncodingEntry g_charsetEncodingMap[] = {
|
||||||
|
|
||||||
// Use QP encoding for ISO-8859-x charsets
|
// Use QP encoding for ISO-8859-x charsets
|
||||||
CharsetEncodingEntry("iso-8859", encodingTypes::QUOTED_PRINTABLE),
|
CharsetEncodingEntry("iso-8859", encodingTypes::QUOTED_PRINTABLE),
|
||||||
CharsetEncodingEntry("iso8859", encodingTypes::QUOTED_PRINTABLE),
|
CharsetEncodingEntry("iso8859", encodingTypes::QUOTED_PRINTABLE),
|
||||||
@ -226,15 +246,16 @@ CharsetEncodingEntry g_charsetEncodingMap[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
bool charset::getRecommendedEncoding(encoding& enc) const
|
bool charset::getRecommendedEncoding(encoding& enc) const {
|
||||||
{
|
|
||||||
// Special treatment for some charsets
|
// Special treatment for some charsets
|
||||||
const string cset = utility::stringUtils::toLower(getName());
|
const string cset = utility::stringUtils::toLower(getName());
|
||||||
|
|
||||||
for (unsigned int i = 0 ; i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ; ++i)
|
for (unsigned int i = 0 ;
|
||||||
{
|
i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ;
|
||||||
if (cset.find(g_charsetEncodingMap[i].charset) != string::npos)
|
++i) {
|
||||||
{
|
|
||||||
|
if (cset.find(g_charsetEncodingMap[i].charset) != string::npos) {
|
||||||
enc = g_charsetEncodingMap[i].encoding;
|
enc = g_charsetEncodingMap[i].encoding;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -32,8 +32,7 @@
|
|||||||
#include "vmime/component.hpp"
|
#include "vmime/component.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class encoding; // forward reference
|
class encoding; // forward reference
|
||||||
@ -41,9 +40,8 @@ class encoding; // forward reference
|
|||||||
|
|
||||||
/** Charset description (basic type).
|
/** Charset description (basic type).
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT charset : public component {
|
||||||
|
|
||||||
class VMIME_EXPORT charset : public component
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
charset();
|
charset();
|
||||||
@ -102,9 +100,13 @@ public:
|
|||||||
* @throws exceptions::charset_conv_error if an unexpected error occurred
|
* @throws exceptions::charset_conv_error if an unexpected error occurred
|
||||||
* during the conversion
|
* during the conversion
|
||||||
*/
|
*/
|
||||||
static void convert(const string& in, string& out,
|
static void convert(
|
||||||
const charset& source, const charset& dest,
|
const string& in,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
string& out,
|
||||||
|
const charset& source,
|
||||||
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
/** Convert the contents of an input stream in a specified charset
|
/** Convert the contents of an input stream in a specified charset
|
||||||
* to another charset and write the result to an output stream.
|
* to another charset and write the result to an output stream.
|
||||||
@ -121,9 +123,13 @@ public:
|
|||||||
* @throws exceptions::charset_conv_error if an unexpected error occurred
|
* @throws exceptions::charset_conv_error if an unexpected error occurred
|
||||||
* during the conversion
|
* during the conversion
|
||||||
*/
|
*/
|
||||||
static void convert(utility::inputStream& in, utility::outputStream& out,
|
static void convert(
|
||||||
const charset& source, const charset& dest,
|
utility::inputStream& in,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
utility::outputStream& out,
|
||||||
|
const charset& source,
|
||||||
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
/** Checks whether the specified text is valid in this charset.
|
/** Checks whether the specified text is valid in this charset.
|
||||||
*
|
*
|
||||||
@ -147,18 +153,20 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parseImpl
|
void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -26,25 +26,26 @@
|
|||||||
#include "vmime/charsetConverter_idna.hpp"
|
#include "vmime/charsetConverter_idna.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
shared_ptr <charsetConverter> charsetConverter::create
|
shared_ptr <charsetConverter> charsetConverter::create(
|
||||||
(const charset& source, const charset& dest,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts)
|
const charset& dest,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
if (source == "idna" || dest == "idna")
|
) {
|
||||||
|
|
||||||
|
if (source == "idna" || dest == "idna") {
|
||||||
return make_shared <charsetConverter_idna>(source, dest, opts);
|
return make_shared <charsetConverter_idna>(source, dest, opts);
|
||||||
else
|
} else {
|
||||||
return createGenericConverter(source, dest, opts);
|
return createGenericConverter(source, dest, opts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetConverter::status::status()
|
charsetConverter::status::status()
|
||||||
: inputBytesRead(0), outputBytesWritten(0)
|
: inputBytesRead(0), outputBytesWritten(0) {
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -33,12 +33,10 @@
|
|||||||
#include "vmime/utility/filteredStream.hpp"
|
#include "vmime/utility/filteredStream.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
namespace utility
|
namespace utility {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** A filtered output stream which applies a charset conversion
|
/** A filtered output stream which applies a charset conversion
|
||||||
@ -52,9 +50,8 @@ namespace utility
|
|||||||
* 'silentlyReplaceInvalidSequences' flag is set to false in
|
* 'silentlyReplaceInvalidSequences' flag is set to false in
|
||||||
* the charsetConverterOptions.
|
* the charsetConverterOptions.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream {
|
||||||
|
|
||||||
class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream
|
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -63,15 +60,14 @@ class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream
|
|||||||
|
|
||||||
/** Convert between charsets.
|
/** Convert between charsets.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT charsetConverter : public object {
|
||||||
|
|
||||||
class VMIME_EXPORT charsetConverter : public object
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Holds information about a conversion.
|
/** Holds information about a conversion.
|
||||||
*/
|
*/
|
||||||
struct status
|
struct status {
|
||||||
{
|
|
||||||
status();
|
status();
|
||||||
|
|
||||||
|
|
||||||
@ -91,9 +87,11 @@ public:
|
|||||||
* @param dest output charset
|
* @param dest output charset
|
||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
*/
|
*/
|
||||||
static shared_ptr <charsetConverter> create
|
static shared_ptr <charsetConverter> create(
|
||||||
(const charset& source, const charset& dest,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
/** Convert a string buffer from one charset to another
|
/** Convert a string buffer from one charset to another
|
||||||
* charset (in-memory conversion)
|
* charset (in-memory conversion)
|
||||||
@ -128,7 +126,11 @@ public:
|
|||||||
* @throws exceptions::charset_conv_error if an unexpected error occurred
|
* @throws exceptions::charset_conv_error if an unexpected error occurred
|
||||||
* during the conversion
|
* during the conversion
|
||||||
*/
|
*/
|
||||||
virtual void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL) = 0;
|
virtual void convert(
|
||||||
|
utility::inputStream& in,
|
||||||
|
utility::outputStream& out,
|
||||||
|
status* st = NULL
|
||||||
|
) = 0;
|
||||||
|
|
||||||
/** Returns a filtered output stream which applies a charset
|
/** Returns a filtered output stream which applies a charset
|
||||||
* conversion to input bytes. Please note that it may not be
|
* conversion to input bytes. Please note that it may not be
|
||||||
@ -138,15 +140,19 @@ public:
|
|||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
* @return a filtered output stream, or NULL if not supported
|
* @return a filtered output stream, or NULL if not supported
|
||||||
*/
|
*/
|
||||||
virtual shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
|
virtual shared_ptr <utility::charsetFilteredOutputStream>
|
||||||
(utility::outputStream& os,
|
getFilteredOutputStream(
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions()) = 0;
|
utility::outputStream& os,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static shared_ptr <charsetConverter> createGenericConverter
|
static shared_ptr <charsetConverter> createGenericConverter(
|
||||||
(const charset& source, const charset& dest,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts);
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -24,14 +24,13 @@
|
|||||||
#include "vmime/charsetConverterOptions.hpp"
|
#include "vmime/charsetConverterOptions.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
charsetConverterOptions::charsetConverterOptions()
|
charsetConverterOptions::charsetConverterOptions()
|
||||||
: silentlyReplaceInvalidSequences(true),
|
: silentlyReplaceInvalidSequences(true),
|
||||||
invalidSequence("?")
|
invalidSequence("?") {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -28,15 +28,13 @@
|
|||||||
#include "vmime/base.hpp"
|
#include "vmime/base.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Options for charset conversion.
|
/** Options for charset conversion.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT charsetConverterOptions : public object {
|
||||||
|
|
||||||
class VMIME_EXPORT charsetConverterOptions : public object
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
charsetConverterOptions();
|
charsetConverterOptions();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,8 +34,8 @@
|
|||||||
#include "vmime/utility/outputStreamStringAdapter.hpp"
|
#include "vmime/utility/outputStreamStringAdapter.hpp"
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#ifndef VMIME_BUILDING_DOC
|
#ifndef VMIME_BUILDING_DOC
|
||||||
|
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
@ -45,8 +45,8 @@ extern "C"
|
|||||||
// second parameter may or may not be 'const'). This relies on the compiler
|
// second parameter may or may not be 'const'). This relies on the compiler
|
||||||
// for choosing the right type.
|
// for choosing the right type.
|
||||||
|
|
||||||
class ICONV_IN_TYPE
|
class ICONV_IN_TYPE {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ICONV_IN_TYPE(const char** ptr) : m_ptr(ptr) { }
|
ICONV_IN_TYPE(const char** ptr) : m_ptr(ptr) { }
|
||||||
@ -62,8 +62,8 @@ extern "C"
|
|||||||
const char** m_ptr;
|
const char** m_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ICONV_OUT_TYPE
|
class ICONV_OUT_TYPE {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ICONV_OUT_TYPE(char** ptr) : m_ptr(ptr) { }
|
ICONV_OUT_TYPE(char** ptr) : m_ptr(ptr) { }
|
||||||
@ -85,9 +85,12 @@ extern "C"
|
|||||||
|
|
||||||
// Output replacement char when an invalid sequence is encountered
|
// Output replacement char when an invalid sequence is encountered
|
||||||
template <typename OUTPUT_CLASS, typename ICONV_DESC>
|
template <typename OUTPUT_CLASS, typename ICONV_DESC>
|
||||||
void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd,
|
void outputInvalidChar(
|
||||||
const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions())
|
OUTPUT_CLASS& out,
|
||||||
{
|
ICONV_DESC cd,
|
||||||
|
const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions()
|
||||||
|
) {
|
||||||
|
|
||||||
const char* invalidCharIn = opts.invalidSequence.c_str();
|
const char* invalidCharIn = opts.invalidSequence.c_str();
|
||||||
vmime::size_t invalidCharInLen = opts.invalidSequence.length();
|
vmime::size_t invalidCharInLen = opts.invalidSequence.length();
|
||||||
|
|
||||||
@ -96,36 +99,43 @@ void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd,
|
|||||||
vmime::size_t invalidCharOutLen = 16;
|
vmime::size_t invalidCharOutLen = 16;
|
||||||
|
|
||||||
if (iconv(cd, ICONV_IN_TYPE(&invalidCharIn), &invalidCharInLen,
|
if (iconv(cd, ICONV_IN_TYPE(&invalidCharIn), &invalidCharInLen,
|
||||||
ICONV_OUT_TYPE(&invalidCharOutPtr), &invalidCharOutLen) != static_cast <size_t>(-1))
|
ICONV_OUT_TYPE(&invalidCharOutPtr), &invalidCharOutLen) != static_cast <size_t>(-1)) {
|
||||||
{
|
|
||||||
out.write(invalidCharOutBuffer, 16 - invalidCharOutLen);
|
out.write(invalidCharOutBuffer, 16 - invalidCharOutLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
|
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
|
||||||
(const charset& source, const charset& dest,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts)
|
const charset& dest,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
) {
|
||||||
|
|
||||||
return make_shared <charsetConverter_iconv>(source, dest, opts);
|
return make_shared <charsetConverter_iconv>(source, dest, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetConverter_iconv::charsetConverter_iconv
|
charsetConverter_iconv::charsetConverter_iconv(
|
||||||
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
|
const charset& source,
|
||||||
: m_desc(NULL), m_source(source), m_dest(dest), m_options(opts)
|
const charset& dest,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
)
|
||||||
|
: m_desc(NULL),
|
||||||
|
m_source(source),
|
||||||
|
m_dest(dest),
|
||||||
|
m_options(opts) {
|
||||||
|
|
||||||
// Get an iconv descriptor
|
// Get an iconv descriptor
|
||||||
const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str());
|
const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str());
|
||||||
|
|
||||||
if (cd != reinterpret_cast <iconv_t>(-1))
|
if (cd != reinterpret_cast <iconv_t>(-1)) {
|
||||||
{
|
|
||||||
iconv_t* p = new iconv_t;
|
iconv_t* p = new iconv_t;
|
||||||
*p= cd;
|
*p= cd;
|
||||||
|
|
||||||
@ -134,10 +144,10 @@ charsetConverter_iconv::charsetConverter_iconv
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetConverter_iconv::~charsetConverter_iconv()
|
charsetConverter_iconv::~charsetConverter_iconv() {
|
||||||
{
|
|
||||||
if (m_desc != NULL)
|
if (m_desc) {
|
||||||
{
|
|
||||||
// Close iconv handle
|
// Close iconv handle
|
||||||
iconv_close(*static_cast <iconv_t*>(m_desc));
|
iconv_close(*static_cast <iconv_t*>(m_desc));
|
||||||
|
|
||||||
@ -147,14 +157,19 @@ charsetConverter_iconv::~charsetConverter_iconv()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_iconv::convert
|
void charsetConverter_iconv::convert(
|
||||||
(utility::inputStream& in, utility::outputStream& out, status* st)
|
utility::inputStream& in,
|
||||||
{
|
utility::outputStream& out,
|
||||||
if (st)
|
status* st
|
||||||
new (st) status();
|
) {
|
||||||
|
|
||||||
if (m_desc == NULL)
|
if (st) {
|
||||||
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_desc) {
|
||||||
throw exceptions::charset_conv_error("Cannot initialize converter.");
|
throw exceptions::charset_conv_error("Cannot initialize converter.");
|
||||||
|
}
|
||||||
|
|
||||||
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
|
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
|
||||||
|
|
||||||
@ -165,8 +180,8 @@ void charsetConverter_iconv::convert
|
|||||||
bool prevIsInvalid = false;
|
bool prevIsInvalid = false;
|
||||||
bool breakAfterNext = false;
|
bool breakAfterNext = false;
|
||||||
|
|
||||||
while (true)
|
while (true) {
|
||||||
{
|
|
||||||
// Fullfill the buffer
|
// Fullfill the buffer
|
||||||
size_t inLength = static_cast <size_t>(in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos);
|
size_t inLength = static_cast <size_t>(in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos);
|
||||||
size_t outLength = sizeof(outBuffer);
|
size_t outLength = sizeof(outBuffer);
|
||||||
@ -177,23 +192,23 @@ void charsetConverter_iconv::convert
|
|||||||
|
|
||||||
// Convert input bytes
|
// Convert input bytes
|
||||||
if (iconv(cd, ICONV_IN_TYPE(&inPtr), ptrLength,
|
if (iconv(cd, ICONV_IN_TYPE(&inPtr), ptrLength,
|
||||||
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
|
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
|
||||||
{
|
|
||||||
if (st && inPtr)
|
if (st && inPtr) {
|
||||||
{
|
|
||||||
st->inputBytesRead += (inPtr - inBuffer);
|
st->inputBytesRead += (inPtr - inBuffer);
|
||||||
st->outputBytesWritten += (outPtr - outBuffer);
|
st->outputBytesWritten += (outPtr - outBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Illegal input sequence or input sequence has no equivalent
|
// Illegal input sequence or input sequence has no equivalent
|
||||||
// sequence in the destination charset.
|
// sequence in the destination charset.
|
||||||
if (prevIsInvalid)
|
if (prevIsInvalid) {
|
||||||
{
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
out.write(outBuffer, sizeof(outBuffer) - outLength);
|
out.write(outBuffer, sizeof(outBuffer) - outLength);
|
||||||
|
|
||||||
if (!m_options.silentlyReplaceInvalidSequences)
|
if (!m_options.silentlyReplaceInvalidSequences) {
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
|
}
|
||||||
|
|
||||||
// Output a special character to indicate we don't known how to
|
// Output a special character to indicate we don't known how to
|
||||||
// convert the sequence at this position
|
// convert the sequence at this position
|
||||||
@ -202,9 +217,9 @@ void charsetConverter_iconv::convert
|
|||||||
// Skip a byte and leave unconverted bytes in the input buffer
|
// Skip a byte and leave unconverted bytes in the input buffer
|
||||||
std::copy(const_cast <byte_t*>(inPtr + 1), inBuffer + sizeof(inBuffer), inBuffer);
|
std::copy(const_cast <byte_t*>(inPtr + 1), inBuffer + sizeof(inBuffer), inBuffer);
|
||||||
inPos = inLength - 1;
|
inPos = inLength - 1;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
out.write(outBuffer, sizeof(outBuffer) - outLength);
|
out.write(outBuffer, sizeof(outBuffer) - outLength);
|
||||||
|
|
||||||
@ -212,17 +227,17 @@ void charsetConverter_iconv::convert
|
|||||||
std::copy(const_cast <byte_t*>(inPtr), inBuffer + sizeof(inBuffer), inBuffer);
|
std::copy(const_cast <byte_t*>(inPtr), inBuffer + sizeof(inBuffer), inBuffer);
|
||||||
inPos = inLength;
|
inPos = inLength;
|
||||||
|
|
||||||
if (errno != E2BIG)
|
if (errno != E2BIG) {
|
||||||
prevIsInvalid = true;
|
prevIsInvalid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
} else {
|
||||||
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
out.write(outBuffer, sizeof(outBuffer) - outLength);
|
out.write(outBuffer, sizeof(outBuffer) - outLength);
|
||||||
|
|
||||||
if (st && inPtr)
|
if (st && inPtr) {
|
||||||
{
|
|
||||||
st->inputBytesRead += (inPtr - inBuffer);
|
st->inputBytesRead += (inPtr - inBuffer);
|
||||||
st->outputBytesWritten += (outPtr - outBuffer);
|
st->outputBytesWritten += (outPtr - outBuffer);
|
||||||
}
|
}
|
||||||
@ -231,20 +246,23 @@ void charsetConverter_iconv::convert
|
|||||||
prevIsInvalid = false;
|
prevIsInvalid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (breakAfterNext)
|
if (breakAfterNext) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for end of data, loop again to flush stateful data from iconv
|
// Check for end of data, loop again to flush stateful data from iconv
|
||||||
if (in.eof() && inPos == 0)
|
if (in.eof() && inPos == 0) {
|
||||||
breakAfterNext = true;
|
breakAfterNext = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_iconv::convert(const string& in, string& out, status* st)
|
void charsetConverter_iconv::convert(const string& in, string& out, status* st) {
|
||||||
{
|
|
||||||
if (st)
|
if (st) {
|
||||||
new (st) status();
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
out.clear();
|
out.clear();
|
||||||
|
|
||||||
@ -258,9 +276,11 @@ void charsetConverter_iconv::convert(const string& in, string& out, status* st)
|
|||||||
|
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream>
|
shared_ptr <utility::charsetFilteredOutputStream>
|
||||||
charsetConverter_iconv::getFilteredOutputStream
|
charsetConverter_iconv::getFilteredOutputStream(
|
||||||
(utility::outputStream& os, const charsetConverterOptions& opts)
|
utility::outputStream& os,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
) {
|
||||||
|
|
||||||
return make_shared <utility::charsetFilteredOutputStream_iconv>(m_source, m_dest, &os, opts);
|
return make_shared <utility::charsetFilteredOutputStream_iconv>(m_source, m_dest, &os, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,17 +291,23 @@ shared_ptr <utility::charsetFilteredOutputStream>
|
|||||||
namespace utility {
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv
|
charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv(
|
||||||
(const charset& source, const charset& dest, outputStream* os,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts)
|
const charset& dest, outputStream* os,
|
||||||
: m_desc(NULL), m_sourceCharset(source), m_destCharset(dest),
|
const charsetConverterOptions& opts
|
||||||
m_stream(*os), m_unconvCount(0), m_options(opts)
|
)
|
||||||
{
|
: m_desc(NULL),
|
||||||
|
m_sourceCharset(source),
|
||||||
|
m_destCharset(dest),
|
||||||
|
m_stream(*os),
|
||||||
|
m_unconvCount(0),
|
||||||
|
m_options(opts) {
|
||||||
|
|
||||||
// Get an iconv descriptor
|
// Get an iconv descriptor
|
||||||
const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str());
|
const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str());
|
||||||
|
|
||||||
if (cd != reinterpret_cast <iconv_t>(-1))
|
if (cd != reinterpret_cast <iconv_t>(-1)) {
|
||||||
{
|
|
||||||
iconv_t* p = new iconv_t;
|
iconv_t* p = new iconv_t;
|
||||||
*p= cd;
|
*p= cd;
|
||||||
|
|
||||||
@ -290,10 +316,10 @@ charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv()
|
charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv() {
|
||||||
{
|
|
||||||
if (m_desc != NULL)
|
if (m_desc) {
|
||||||
{
|
|
||||||
// Close iconv handle
|
// Close iconv handle
|
||||||
iconv_close(*static_cast <iconv_t*>(m_desc));
|
iconv_close(*static_cast <iconv_t*>(m_desc));
|
||||||
|
|
||||||
@ -303,17 +329,20 @@ charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
outputStream& charsetFilteredOutputStream_iconv::getNextOutputStream()
|
outputStream& charsetFilteredOutputStream_iconv::getNextOutputStream() {
|
||||||
{
|
|
||||||
return m_stream;
|
return m_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetFilteredOutputStream_iconv::writeImpl
|
void charsetFilteredOutputStream_iconv::writeImpl(
|
||||||
(const byte_t* const data, const size_t count)
|
const byte_t* const data,
|
||||||
{
|
const size_t count
|
||||||
if (m_desc == NULL)
|
) {
|
||||||
|
|
||||||
|
if (!m_desc) {
|
||||||
throw exceptions::charset_conv_error("Cannot initialize converter.");
|
throw exceptions::charset_conv_error("Cannot initialize converter.");
|
||||||
|
}
|
||||||
|
|
||||||
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
|
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
|
||||||
|
|
||||||
@ -322,23 +351,26 @@ void charsetFilteredOutputStream_iconv::writeImpl
|
|||||||
|
|
||||||
// If there is some unconverted bytes left, add more data from this
|
// If there is some unconverted bytes left, add more data from this
|
||||||
// chunk to see if it can now be converted.
|
// chunk to see if it can now be converted.
|
||||||
while (m_unconvCount != 0 || curDataLen != 0)
|
while (m_unconvCount != 0 || curDataLen != 0) {
|
||||||
{
|
|
||||||
if (m_unconvCount != 0)
|
if (m_unconvCount != 0) {
|
||||||
{
|
|
||||||
// Check if an incomplete input sequence is larger than the
|
// Check if an incomplete input sequence is larger than the
|
||||||
// input buffer size: should not happen except if something
|
// input buffer size: should not happen except if something
|
||||||
// in the input sequence is invalid. If so, output a special
|
// in the input sequence is invalid. If so, output a special
|
||||||
// character and skip one byte in the invalid sequence.
|
// character and skip one byte in the invalid sequence.
|
||||||
if (m_unconvCount >= sizeof(m_unconvBuffer))
|
if (m_unconvCount >= sizeof(m_unconvBuffer)) {
|
||||||
{
|
|
||||||
if (!m_options.silentlyReplaceInvalidSequences)
|
if (!m_options.silentlyReplaceInvalidSequences) {
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
|
}
|
||||||
|
|
||||||
outputInvalidChar(m_stream, cd);
|
outputInvalidChar(m_stream, cd);
|
||||||
|
|
||||||
std::copy(m_unconvBuffer + 1,
|
std::copy(
|
||||||
m_unconvBuffer + m_unconvCount, m_unconvBuffer);
|
m_unconvBuffer + 1,
|
||||||
|
m_unconvBuffer + m_unconvCount, m_unconvBuffer
|
||||||
|
);
|
||||||
|
|
||||||
m_unconvCount--;
|
m_unconvCount--;
|
||||||
}
|
}
|
||||||
@ -365,16 +397,18 @@ void charsetFilteredOutputStream_iconv::writeImpl
|
|||||||
const size_t inLength0 = inLength;
|
const size_t inLength0 = inLength;
|
||||||
|
|
||||||
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
|
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
|
||||||
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
|
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
|
||||||
{
|
|
||||||
const size_t inputConverted = inLength0 - inLength;
|
const size_t inputConverted = inLength0 - inLength;
|
||||||
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
||||||
|
|
||||||
// Shift unconverted bytes
|
// Shift unconverted bytes
|
||||||
std::copy(m_unconvBuffer + inputConverted,
|
std::copy(
|
||||||
m_unconvBuffer + m_unconvCount, m_unconvBuffer);
|
m_unconvBuffer + inputConverted,
|
||||||
|
m_unconvBuffer + m_unconvCount, m_unconvBuffer
|
||||||
|
);
|
||||||
|
|
||||||
m_unconvCount -= inputConverted;
|
m_unconvCount -= inputConverted;
|
||||||
|
|
||||||
@ -388,8 +422,9 @@ void charsetFilteredOutputStream_iconv::writeImpl
|
|||||||
m_unconvCount = 0;
|
m_unconvCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curDataLen == 0)
|
if (curDataLen == 0) {
|
||||||
return; // no more data
|
return; // no more data
|
||||||
|
}
|
||||||
|
|
||||||
// Now, convert the current data buffer
|
// Now, convert the current data buffer
|
||||||
const byte_t* inPtr = curData;
|
const byte_t* inPtr = curData;
|
||||||
@ -400,8 +435,8 @@ void charsetFilteredOutputStream_iconv::writeImpl
|
|||||||
const size_t inLength0 = inLength;
|
const size_t inLength0 = inLength;
|
||||||
|
|
||||||
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
|
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
|
||||||
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
|
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
|
||||||
{
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
||||||
|
|
||||||
@ -412,17 +447,17 @@ void charsetFilteredOutputStream_iconv::writeImpl
|
|||||||
|
|
||||||
// Put one byte byte into the unconverted buffer so
|
// Put one byte byte into the unconverted buffer so
|
||||||
// that the next iteration fill it
|
// that the next iteration fill it
|
||||||
if (curDataLen != 0)
|
if (curDataLen != 0) {
|
||||||
{
|
|
||||||
m_unconvCount = 1;
|
m_unconvCount = 1;
|
||||||
m_unconvBuffer[0] = *curData;
|
m_unconvBuffer[0] = *curData;
|
||||||
|
|
||||||
curData++;
|
curData++;
|
||||||
curDataLen--;
|
curDataLen--;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
||||||
|
|
||||||
@ -433,18 +468,19 @@ void charsetFilteredOutputStream_iconv::writeImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetFilteredOutputStream_iconv::flush()
|
void charsetFilteredOutputStream_iconv::flush() {
|
||||||
{
|
|
||||||
if (m_desc == NULL)
|
if (!m_desc) {
|
||||||
throw exceptions::charset_conv_error("Cannot initialize converter.");
|
throw exceptions::charset_conv_error("Cannot initialize converter.");
|
||||||
|
}
|
||||||
|
|
||||||
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
|
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
|
|
||||||
// Process unconverted bytes
|
// Process unconverted bytes
|
||||||
while (m_unconvCount != 0)
|
while (m_unconvCount != 0) {
|
||||||
{
|
|
||||||
// Try a conversion
|
// Try a conversion
|
||||||
const byte_t* inPtr = m_unconvBuffer + offset;
|
const byte_t* inPtr = m_unconvBuffer + offset;
|
||||||
size_t inLength = m_unconvCount;
|
size_t inLength = m_unconvCount;
|
||||||
@ -453,32 +489,34 @@ void charsetFilteredOutputStream_iconv::flush()
|
|||||||
|
|
||||||
const size_t inLength0 = inLength;
|
const size_t inLength0 = inLength;
|
||||||
|
|
||||||
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength, ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
|
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
|
||||||
{
|
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
|
||||||
|
|
||||||
const size_t inputConverted = inLength0 - inLength;
|
const size_t inputConverted = inLength0 - inLength;
|
||||||
|
|
||||||
// Skip a "blocking" character
|
// Skip a "blocking" character
|
||||||
if (inputConverted == 0)
|
if (inputConverted == 0) {
|
||||||
{
|
|
||||||
if (!m_options.silentlyReplaceInvalidSequences)
|
if (!m_options.silentlyReplaceInvalidSequences) {
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
|
}
|
||||||
|
|
||||||
outputInvalidChar(m_stream, cd);
|
outputInvalidChar(m_stream, cd);
|
||||||
|
|
||||||
offset++;
|
offset++;
|
||||||
m_unconvCount--;
|
m_unconvCount--;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
||||||
|
|
||||||
offset += inputConverted;
|
offset += inputConverted;
|
||||||
m_unconvCount -= inputConverted;
|
m_unconvCount -= inputConverted;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Write successfully converted bytes
|
// Write successfully converted bytes
|
||||||
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,15 +34,13 @@
|
|||||||
#include "vmime/charsetConverter.hpp"
|
#include "vmime/charsetConverter.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** A generic charset converter which uses iconv library.
|
/** A generic charset converter which uses iconv library.
|
||||||
*/
|
*/
|
||||||
|
class charsetConverter_iconv : public charsetConverter {
|
||||||
|
|
||||||
class charsetConverter_iconv : public charsetConverter
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Construct and initialize an iconv charset converter.
|
/** Construct and initialize an iconv charset converter.
|
||||||
@ -51,17 +49,21 @@ public:
|
|||||||
* @param dest output charset
|
* @param dest output charset
|
||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
*/
|
*/
|
||||||
charsetConverter_iconv(const charset& source, const charset& dest,
|
charsetConverter_iconv(
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charset& source,
|
||||||
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
~charsetConverter_iconv();
|
~charsetConverter_iconv();
|
||||||
|
|
||||||
void convert(const string& in, string& out, status* st = NULL);
|
void convert(const string& in, string& out, status* st = NULL);
|
||||||
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
|
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
|
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
|
||||||
(utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -77,8 +79,8 @@ private:
|
|||||||
namespace utility {
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream
|
class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Construct a new filter for the specified output stream.
|
/** Construct a new filter for the specified output stream.
|
||||||
@ -88,9 +90,11 @@ public:
|
|||||||
* @param os stream into which write filtered data
|
* @param os stream into which write filtered data
|
||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
*/
|
*/
|
||||||
charsetFilteredOutputStream_iconv
|
charsetFilteredOutputStream_iconv(
|
||||||
(const charset& source, const charset& dest, outputStream* os,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charset& dest, outputStream* os,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
~charsetFilteredOutputStream_iconv();
|
~charsetFilteredOutputStream_iconv();
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,8 +34,8 @@
|
|||||||
#include "vmime/utility/outputStreamStringAdapter.hpp"
|
#include "vmime/utility/outputStreamStringAdapter.hpp"
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
#ifndef VMIME_BUILDING_DOC
|
#ifndef VMIME_BUILDING_DOC
|
||||||
|
|
||||||
#include <unicode/ucnv.h>
|
#include <unicode/ucnv.h>
|
||||||
@ -48,59 +48,75 @@ extern "C"
|
|||||||
#include <unicode/unistr.h>
|
#include <unicode/unistr.h>
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
|
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
|
||||||
(const charset& source, const charset& dest,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts)
|
const charset& dest,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
) {
|
||||||
|
|
||||||
return make_shared <charsetConverter_icu>(source, dest, opts);
|
return make_shared <charsetConverter_icu>(source, dest, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetConverter_icu::charsetConverter_icu
|
charsetConverter_icu::charsetConverter_icu(
|
||||||
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
|
const charset& source,
|
||||||
: m_from(NULL), m_to(NULL), m_source(source), m_dest(dest), m_options(opts)
|
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;
|
UErrorCode err = U_ZERO_ERROR;
|
||||||
m_from = ucnv_open(source.getName().c_str(), &err);
|
m_from = ucnv_open(source.getName().c_str(), &err);
|
||||||
|
|
||||||
if (!U_SUCCESS(err))
|
if (!U_SUCCESS(err)) {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + ".");
|
"Cannot initialize ICU converter for source charset '" + source.getName()
|
||||||
|
+ "' (error code: " + u_errorName(err) + "."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_to = ucnv_open(dest.getName().c_str(), &err);
|
m_to = ucnv_open(dest.getName().c_str(), &err);
|
||||||
|
|
||||||
if (!U_SUCCESS(err))
|
if (!U_SUCCESS(err)) {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + ".");
|
"Cannot initialize ICU converter for destination charset '" + dest.getName()
|
||||||
|
+ "' (error code: " + u_errorName(err) + "."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetConverter_icu::~charsetConverter_icu()
|
charsetConverter_icu::~charsetConverter_icu() {
|
||||||
{
|
|
||||||
if (m_from) ucnv_close(m_from);
|
if (m_from) ucnv_close(m_from);
|
||||||
if (m_to) ucnv_close(m_to);
|
if (m_to) ucnv_close(m_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_icu::convert
|
void charsetConverter_icu::convert(
|
||||||
(utility::inputStream& in, utility::outputStream& out, status* st)
|
utility::inputStream& in,
|
||||||
{
|
utility::outputStream& out,
|
||||||
|
status* st
|
||||||
|
) {
|
||||||
|
|
||||||
UErrorCode err = U_ZERO_ERROR;
|
UErrorCode err = U_ZERO_ERROR;
|
||||||
|
|
||||||
ucnv_reset(m_from);
|
ucnv_reset(m_from);
|
||||||
ucnv_reset(m_to);
|
ucnv_reset(m_to);
|
||||||
|
|
||||||
if (st)
|
if (st) {
|
||||||
new (st) status();
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
// From buffers
|
// From buffers
|
||||||
byte_t cpInBuffer[16]; // stream data put here
|
byte_t cpInBuffer[16]; // stream data put here
|
||||||
@ -113,34 +129,39 @@ void charsetConverter_icu::convert
|
|||||||
std::vector <char> cpOutBuffer(cpOutBufferSz);
|
std::vector <char> cpOutBuffer(cpOutBufferSz);
|
||||||
|
|
||||||
// Tell ICU what to do when encountering an illegal byte sequence
|
// Tell ICU what to do when encountering an illegal byte sequence
|
||||||
if (m_options.silentlyReplaceInvalidSequences)
|
if (m_options.silentlyReplaceInvalidSequences) {
|
||||||
{
|
|
||||||
// Set replacement chars for when converting from Unicode to codepage
|
// Set replacement chars for when converting from Unicode to codepage
|
||||||
icu::UnicodeString substString(m_options.invalidSequence.c_str());
|
icu::UnicodeString substString(m_options.invalidSequence.c_str());
|
||||||
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
|
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
|
||||||
|
|
||||||
if (U_FAILURE(err))
|
if (U_FAILURE(err)) {
|
||||||
throw exceptions::charset_conv_error("[ICU] Error when setting substitution string.");
|
throw exceptions::charset_conv_error("[ICU] Error when setting substitution string.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
} else {
|
||||||
|
|
||||||
// Tell ICU top stop (and return an error) on illegal byte sequences
|
// Tell ICU top stop (and return an error) on illegal byte sequences
|
||||||
ucnv_setToUCallBack
|
ucnv_setToUCallBack(
|
||||||
(m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
|
m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
|
||||||
|
);
|
||||||
|
|
||||||
if (U_FAILURE(err))
|
if (U_FAILURE(err)) {
|
||||||
throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback.");
|
throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback.");
|
||||||
|
}
|
||||||
|
|
||||||
ucnv_setFromUCallBack
|
ucnv_setFromUCallBack(
|
||||||
(m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
|
m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
|
||||||
|
);
|
||||||
|
|
||||||
if (U_FAILURE(err))
|
if (U_FAILURE(err)) {
|
||||||
throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback.");
|
throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Input data available
|
// Input data available
|
||||||
while (!in.eof())
|
while (!in.eof()) {
|
||||||
{
|
|
||||||
// Read input data into buffer
|
// Read input data into buffer
|
||||||
size_t inLength = in.read(cpInBuffer, sizeof(cpInBuffer));
|
size_t inLength = in.read(cpInBuffer, sizeof(cpInBuffer));
|
||||||
|
|
||||||
@ -153,30 +174,36 @@ void charsetConverter_icu::convert
|
|||||||
UErrorCode toErr;
|
UErrorCode toErr;
|
||||||
|
|
||||||
// Loop until all source has been processed
|
// Loop until all source has been processed
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
// Set up target pointers
|
// Set up target pointers
|
||||||
UChar* target = &uOutBuffer[0];
|
UChar* target = &uOutBuffer[0];
|
||||||
UChar* targetLimit = &target[0] + outSize;
|
UChar* targetLimit = &target[0] + outSize;
|
||||||
|
|
||||||
toErr = U_ZERO_ERROR;
|
toErr = U_ZERO_ERROR;
|
||||||
ucnv_toUnicode(m_from, &target, targetLimit,
|
|
||||||
&source, sourceLimit, NULL, flush, &toErr);
|
|
||||||
|
|
||||||
if (st)
|
ucnv_toUnicode(
|
||||||
|
m_from, &target, targetLimit,
|
||||||
|
&source, sourceLimit, NULL, flush, &toErr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (st) {
|
||||||
st->inputBytesRead += (source - reinterpret_cast <const char*>(&cpInBuffer[0]));
|
st->inputBytesRead += (source - reinterpret_cast <const char*>(&cpInBuffer[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr)) {
|
||||||
|
|
||||||
if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr))
|
|
||||||
{
|
|
||||||
if (toErr == U_INVALID_CHAR_FOUND ||
|
if (toErr == U_INVALID_CHAR_FOUND ||
|
||||||
toErr == U_TRUNCATED_CHAR_FOUND ||
|
toErr == U_TRUNCATED_CHAR_FOUND ||
|
||||||
toErr == U_ILLEGAL_CHAR_FOUND)
|
toErr == U_ILLEGAL_CHAR_FOUND) {
|
||||||
{
|
|
||||||
// Error will be thrown later (*)
|
// Error will be thrown later (*)
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error("[ICU] Error converting to Unicode from " + m_source.getName());
|
throw exceptions::charset_conv_error(
|
||||||
|
"[ICU] Error converting to Unicode from " + m_source.getName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,19 +214,21 @@ void charsetConverter_icu::convert
|
|||||||
UErrorCode fromErr;
|
UErrorCode fromErr;
|
||||||
|
|
||||||
// Loop until converted chars are fully written
|
// Loop until converted chars are fully written
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
char* cpTarget = &cpOutBuffer[0];
|
char* cpTarget = &cpOutBuffer[0];
|
||||||
const char* cpTargetLimit = &cpOutBuffer[0] + cpOutBufferSz;
|
const char* cpTargetLimit = &cpOutBuffer[0] + cpOutBufferSz;
|
||||||
|
|
||||||
fromErr = U_ZERO_ERROR;
|
fromErr = U_ZERO_ERROR;
|
||||||
|
|
||||||
// Write converted bytes (Unicode) to destination codepage
|
// Write converted bytes (Unicode) to destination codepage
|
||||||
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
|
ucnv_fromUnicode(
|
||||||
&uSource, uSourceLimit, NULL, flush, &fromErr);
|
m_to, &cpTarget, cpTargetLimit,
|
||||||
|
&uSource, uSourceLimit, NULL, flush, &fromErr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (st) {
|
||||||
|
|
||||||
if (st)
|
|
||||||
{
|
|
||||||
// Decrement input bytes count by the number of input bytes in error
|
// Decrement input bytes count by the number of input bytes in error
|
||||||
char errBytes[16];
|
char errBytes[16];
|
||||||
int8_t errBytesLen = sizeof(errBytes);
|
int8_t errBytesLen = sizeof(errBytes);
|
||||||
@ -214,22 +243,24 @@ void charsetConverter_icu::convert
|
|||||||
// (*) If an error occurred while converting from input charset, throw it now
|
// (*) If an error occurred while converting from input charset, throw it now
|
||||||
if (toErr == U_INVALID_CHAR_FOUND ||
|
if (toErr == U_INVALID_CHAR_FOUND ||
|
||||||
toErr == U_TRUNCATED_CHAR_FOUND ||
|
toErr == U_TRUNCATED_CHAR_FOUND ||
|
||||||
toErr == U_ILLEGAL_CHAR_FOUND)
|
toErr == U_ILLEGAL_CHAR_FOUND) {
|
||||||
{
|
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
|
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) {
|
||||||
{
|
|
||||||
if (fromErr == U_INVALID_CHAR_FOUND ||
|
if (fromErr == U_INVALID_CHAR_FOUND ||
|
||||||
fromErr == U_TRUNCATED_CHAR_FOUND ||
|
fromErr == U_TRUNCATED_CHAR_FOUND ||
|
||||||
fromErr == U_ILLEGAL_CHAR_FOUND)
|
fromErr == U_ILLEGAL_CHAR_FOUND) {
|
||||||
{
|
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error("[ICU] Error converting from Unicode to " + m_dest.getName());
|
throw exceptions::charset_conv_error(
|
||||||
|
"[ICU] Error converting from Unicode to " + m_dest.getName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,10 +274,11 @@ void charsetConverter_icu::convert
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_icu::convert(const string& in, string& out, status* st)
|
void charsetConverter_icu::convert(const string& in, string& out, status* st) {
|
||||||
{
|
|
||||||
if (st)
|
if (st) {
|
||||||
new (st) status();
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
out.clear();
|
out.clear();
|
||||||
|
|
||||||
@ -260,9 +292,11 @@ void charsetConverter_icu::convert(const string& in, string& out, status* st)
|
|||||||
|
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream>
|
shared_ptr <utility::charsetFilteredOutputStream>
|
||||||
charsetConverter_icu::getFilteredOutputStream
|
charsetConverter_icu::getFilteredOutputStream(
|
||||||
(utility::outputStream& os, const charsetConverterOptions& opts)
|
utility::outputStream& os,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
) {
|
||||||
|
|
||||||
return make_shared <utility::charsetFilteredOutputStream_icu>(m_source, m_dest, &os, opts);
|
return make_shared <utility::charsetFilteredOutputStream_icu>(m_source, m_dest, &os, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,75 +307,94 @@ shared_ptr <utility::charsetFilteredOutputStream>
|
|||||||
namespace utility {
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu
|
charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu(
|
||||||
(const charset& source, const charset& dest, outputStream* os,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts)
|
const charset& dest,
|
||||||
: m_from(NULL), m_to(NULL), m_sourceCharset(source),
|
outputStream* os,
|
||||||
m_destCharset(dest), m_stream(*os), m_options(opts)
|
const charsetConverterOptions& opts
|
||||||
{
|
)
|
||||||
|
: m_from(NULL),
|
||||||
|
m_to(NULL),
|
||||||
|
m_sourceCharset(source),
|
||||||
|
m_destCharset(dest),
|
||||||
|
m_stream(*os),
|
||||||
|
m_options(opts) {
|
||||||
|
|
||||||
UErrorCode err = U_ZERO_ERROR;
|
UErrorCode err = U_ZERO_ERROR;
|
||||||
m_from = ucnv_open(source.getName().c_str(), &err);
|
m_from = ucnv_open(source.getName().c_str(), &err);
|
||||||
|
|
||||||
if (!U_SUCCESS(err))
|
if (!U_SUCCESS(err)) {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + ".");
|
"Cannot initialize ICU converter for source charset '" + source.getName()
|
||||||
|
+ "' (error code: " + u_errorName(err) + "."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_to = ucnv_open(dest.getName().c_str(), &err);
|
m_to = ucnv_open(dest.getName().c_str(), &err);
|
||||||
|
|
||||||
if (!U_SUCCESS(err))
|
if (!U_SUCCESS(err)) {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + ".");
|
"Cannot initialize ICU converter for destination charset '" + dest.getName()
|
||||||
|
+ "' (error code: " + u_errorName(err) + "."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell ICU what to do when encountering an illegal byte sequence
|
// Tell ICU what to do when encountering an illegal byte sequence
|
||||||
if (m_options.silentlyReplaceInvalidSequences)
|
if (m_options.silentlyReplaceInvalidSequences) {
|
||||||
{
|
|
||||||
// Set replacement chars for when converting from Unicode to codepage
|
// Set replacement chars for when converting from Unicode to codepage
|
||||||
icu::UnicodeString substString(m_options.invalidSequence.c_str());
|
icu::UnicodeString substString(m_options.invalidSequence.c_str());
|
||||||
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
|
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
|
||||||
|
|
||||||
if (U_FAILURE(err))
|
if (U_FAILURE(err)) {
|
||||||
throw exceptions::charset_conv_error("[ICU] Error when setting substitution string.");
|
throw exceptions::charset_conv_error("[ICU] Error when setting substitution string.");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
} else {
|
||||||
|
|
||||||
// Tell ICU top stop (and return an error) on illegal byte sequences
|
// Tell ICU top stop (and return an error) on illegal byte sequences
|
||||||
ucnv_setToUCallBack
|
ucnv_setToUCallBack(
|
||||||
(m_to, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
|
m_to, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
|
||||||
|
);
|
||||||
|
|
||||||
if (U_FAILURE(err))
|
if (U_FAILURE(err)) {
|
||||||
throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback.");
|
throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback.");
|
||||||
|
}
|
||||||
|
|
||||||
ucnv_setFromUCallBack
|
ucnv_setFromUCallBack(
|
||||||
(m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
|
m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
|
||||||
|
);
|
||||||
|
|
||||||
if (U_FAILURE(err))
|
if (U_FAILURE(err)) {
|
||||||
throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback.");
|
throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu()
|
charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu() {
|
||||||
{
|
|
||||||
if (m_from) ucnv_close(m_from);
|
if (m_from) ucnv_close(m_from);
|
||||||
if (m_to) ucnv_close(m_to);
|
if (m_to) ucnv_close(m_to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
outputStream& charsetFilteredOutputStream_icu::getNextOutputStream()
|
outputStream& charsetFilteredOutputStream_icu::getNextOutputStream() {
|
||||||
{
|
|
||||||
return m_stream;
|
return m_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetFilteredOutputStream_icu::writeImpl
|
void charsetFilteredOutputStream_icu::writeImpl(
|
||||||
(const byte_t* const data, const size_t count)
|
const byte_t* const data,
|
||||||
{
|
const size_t count
|
||||||
if (m_from == NULL || m_to == NULL)
|
) {
|
||||||
|
|
||||||
|
if (!m_from || !m_to) {
|
||||||
throw exceptions::charset_conv_error("Cannot initialize converters.");
|
throw exceptions::charset_conv_error("Cannot initialize converters.");
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate buffer for Unicode chars
|
// Allocate buffer for Unicode chars
|
||||||
const size_t uniSize = ucnv_getMinCharSize(m_from) * count * sizeof(UChar);
|
const size_t uniSize = ucnv_getMinCharSize(m_from) * count * sizeof(UChar);
|
||||||
@ -353,29 +406,32 @@ void charsetFilteredOutputStream_icu::writeImpl
|
|||||||
const char* uniSource = reinterpret_cast <const char*>(data);
|
const char* uniSource = reinterpret_cast <const char*>(data);
|
||||||
const char* uniSourceLimit = uniSource + count;
|
const char* uniSourceLimit = uniSource + count;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
// Convert from source charset to Unicode
|
// Convert from source charset to Unicode
|
||||||
UChar* uniTarget = &uniBuffer[0];
|
UChar* uniTarget = &uniBuffer[0];
|
||||||
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
|
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
|
||||||
|
|
||||||
toErr = U_ZERO_ERROR;
|
toErr = U_ZERO_ERROR;
|
||||||
|
|
||||||
ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit,
|
ucnv_toUnicode(
|
||||||
&uniSource, uniSourceLimit, NULL, /* flush */ FALSE, &toErr);
|
m_from, &uniTarget, uniTargetLimit,
|
||||||
|
&uniSource, uniSourceLimit, NULL, /* flush */ FALSE, &toErr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) {
|
||||||
|
|
||||||
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR)
|
|
||||||
{
|
|
||||||
if (toErr == U_INVALID_CHAR_FOUND ||
|
if (toErr == U_INVALID_CHAR_FOUND ||
|
||||||
toErr == U_TRUNCATED_CHAR_FOUND ||
|
toErr == U_TRUNCATED_CHAR_FOUND ||
|
||||||
toErr == U_ILLEGAL_CHAR_FOUND)
|
toErr == U_ILLEGAL_CHAR_FOUND) {
|
||||||
{
|
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'.");
|
"[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,28 +447,31 @@ void charsetFilteredOutputStream_icu::writeImpl
|
|||||||
const UChar* cpSource = &uniBuffer[0];
|
const UChar* cpSource = &uniBuffer[0];
|
||||||
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
|
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
char* cpTarget = &cpBuffer[0];
|
char* cpTarget = &cpBuffer[0];
|
||||||
char* cpTargetLimit = &cpBuffer[0] + cpSize;
|
char* cpTargetLimit = &cpBuffer[0] + cpSize;
|
||||||
|
|
||||||
fromErr = U_ZERO_ERROR;
|
fromErr = U_ZERO_ERROR;
|
||||||
|
|
||||||
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
|
ucnv_fromUnicode(
|
||||||
&cpSource, cpSourceLimit, NULL, /* flush */ FALSE, &fromErr);
|
m_to, &cpTarget, cpTargetLimit,
|
||||||
|
&cpSource, cpSourceLimit, NULL, /* flush */ FALSE, &fromErr
|
||||||
|
);
|
||||||
|
|
||||||
|
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) {
|
||||||
|
|
||||||
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
|
|
||||||
{
|
|
||||||
if (fromErr == U_INVALID_CHAR_FOUND ||
|
if (fromErr == U_INVALID_CHAR_FOUND ||
|
||||||
fromErr == U_TRUNCATED_CHAR_FOUND ||
|
fromErr == U_TRUNCATED_CHAR_FOUND ||
|
||||||
fromErr == U_ILLEGAL_CHAR_FOUND)
|
fromErr == U_ILLEGAL_CHAR_FOUND) {
|
||||||
{
|
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'.");
|
"[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,10 +486,11 @@ void charsetFilteredOutputStream_icu::writeImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetFilteredOutputStream_icu::flush()
|
void charsetFilteredOutputStream_icu::flush() {
|
||||||
{
|
|
||||||
if (m_from == NULL || m_to == NULL)
|
if (!m_from || !m_to) {
|
||||||
throw exceptions::charset_conv_error("Cannot initialize converters.");
|
throw exceptions::charset_conv_error("Cannot initialize converters.");
|
||||||
|
}
|
||||||
|
|
||||||
// Allocate buffer for Unicode chars
|
// Allocate buffer for Unicode chars
|
||||||
const size_t uniSize = ucnv_getMinCharSize(m_from) * 1024 * sizeof(UChar);
|
const size_t uniSize = ucnv_getMinCharSize(m_from) * 1024 * sizeof(UChar);
|
||||||
@ -442,21 +502,24 @@ void charsetFilteredOutputStream_icu::flush()
|
|||||||
const char* uniSource = 0;
|
const char* uniSource = 0;
|
||||||
const char* uniSourceLimit = 0;
|
const char* uniSourceLimit = 0;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
// Convert from source charset to Unicode
|
// Convert from source charset to Unicode
|
||||||
UChar* uniTarget = &uniBuffer[0];
|
UChar* uniTarget = &uniBuffer[0];
|
||||||
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
|
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
|
||||||
|
|
||||||
toErr = U_ZERO_ERROR;
|
toErr = U_ZERO_ERROR;
|
||||||
|
|
||||||
ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit,
|
ucnv_toUnicode(
|
||||||
&uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr);
|
m_from, &uniTarget, uniTargetLimit,
|
||||||
|
&uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr
|
||||||
|
);
|
||||||
|
|
||||||
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR)
|
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'.");
|
"[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t uniLength = uniTarget - &uniBuffer[0];
|
const size_t uniLength = uniTarget - &uniBuffer[0];
|
||||||
@ -471,20 +534,23 @@ void charsetFilteredOutputStream_icu::flush()
|
|||||||
const UChar* cpSource = &uniBuffer[0];
|
const UChar* cpSource = &uniBuffer[0];
|
||||||
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
|
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
|
||||||
|
|
||||||
do
|
do {
|
||||||
{
|
|
||||||
char* cpTarget = &cpBuffer[0];
|
char* cpTarget = &cpBuffer[0];
|
||||||
char* cpTargetLimit = &cpBuffer[0] + cpSize;
|
char* cpTargetLimit = &cpBuffer[0] + cpSize;
|
||||||
|
|
||||||
fromErr = U_ZERO_ERROR;
|
fromErr = U_ZERO_ERROR;
|
||||||
|
|
||||||
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
|
ucnv_fromUnicode(
|
||||||
&cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr);
|
m_to, &cpTarget, cpTargetLimit,
|
||||||
|
&cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr
|
||||||
|
);
|
||||||
|
|
||||||
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
|
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error
|
throw exceptions::charset_conv_error(
|
||||||
("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'.");
|
"[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t cpLength = cpTarget - &cpBuffer[0];
|
const size_t cpLength = cpTarget - &cpBuffer[0];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -37,15 +37,13 @@
|
|||||||
struct UConverter;
|
struct UConverter;
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** A generic charset converter which uses ICU library.
|
/** A generic charset converter which uses ICU library.
|
||||||
*/
|
*/
|
||||||
|
class charsetConverter_icu : public charsetConverter {
|
||||||
|
|
||||||
class charsetConverter_icu : public charsetConverter
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Construct and initialize an ICU charset converter.
|
/** Construct and initialize an ICU charset converter.
|
||||||
@ -54,17 +52,21 @@ public:
|
|||||||
* @param dest output charset
|
* @param dest output charset
|
||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
*/
|
*/
|
||||||
charsetConverter_icu(const charset& source, const charset& dest,
|
charsetConverter_icu(
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charset& source,
|
||||||
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
~charsetConverter_icu();
|
~charsetConverter_icu();
|
||||||
|
|
||||||
void convert(const string& in, string& out, status* st = NULL);
|
void convert(const string& in, string& out, status* st = NULL);
|
||||||
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
|
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
|
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
|
||||||
(utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -81,8 +83,8 @@ private:
|
|||||||
namespace utility {
|
namespace utility {
|
||||||
|
|
||||||
|
|
||||||
class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream
|
class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Construct a new filter for the specified output stream.
|
/** Construct a new filter for the specified output stream.
|
||||||
@ -92,9 +94,12 @@ public:
|
|||||||
* @param os stream into which write filtered data
|
* @param os stream into which write filtered data
|
||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
*/
|
*/
|
||||||
charsetFilteredOutputStream_icu
|
charsetFilteredOutputStream_icu(
|
||||||
(const charset& source, const charset& dest, outputStream* os,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charset& dest,
|
||||||
|
outputStream* os,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
~charsetFilteredOutputStream_icu();
|
~charsetFilteredOutputStream_icu();
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -30,8 +30,7 @@
|
|||||||
#include "vmime/utility/outputStreamStringAdapter.hpp"
|
#include "vmime/utility/outputStreamStringAdapter.hpp"
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C" {
|
||||||
{
|
|
||||||
|
|
||||||
#include "contrib/punycode/punycode.h"
|
#include "contrib/punycode/punycode.h"
|
||||||
#include "contrib/punycode/punycode.c"
|
#include "contrib/punycode/punycode.c"
|
||||||
@ -41,26 +40,31 @@ extern "C"
|
|||||||
#include "contrib/utf8/utf8.h"
|
#include "contrib/utf8/utf8.h"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
charsetConverter_idna::charsetConverter_idna
|
charsetConverter_idna::charsetConverter_idna(
|
||||||
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
|
const charset& source,
|
||||||
: m_source(source), m_dest(dest), m_options(opts)
|
const charset& dest,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
)
|
||||||
|
: m_source(source),
|
||||||
|
m_dest(dest),
|
||||||
|
m_options(opts) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetConverter_idna::~charsetConverter_idna()
|
charsetConverter_idna::~charsetConverter_idna() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStream& out, status* st)
|
void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStream& out, status* st) {
|
||||||
{
|
|
||||||
if (st)
|
if (st) {
|
||||||
new (st) status();
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
// IDNA should be used for short strings, so it does not matter if we
|
// IDNA should be used for short strings, so it does not matter if we
|
||||||
// do not work directly on the stream
|
// do not work directly on the stream
|
||||||
@ -75,19 +79,19 @@ void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStr
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_idna::convert(const string& in, string& out, status* st)
|
void charsetConverter_idna::convert(const string& in, string& out, status* st) {
|
||||||
{
|
|
||||||
if (st)
|
if (st) {
|
||||||
new (st) status();
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
out.clear();
|
out.clear();
|
||||||
|
|
||||||
if (m_dest == "idna")
|
if (m_dest == "idna") {
|
||||||
{
|
|
||||||
if (utility::stringUtils::is7bit(in))
|
if (utility::stringUtils::is7bit(in)) {
|
||||||
{
|
|
||||||
if (st)
|
if (st) {
|
||||||
{
|
|
||||||
st->inputBytesRead = in.length();
|
st->inputBytesRead = in.length();
|
||||||
st->outputBytesWritten = in.length();
|
st->outputBytesWritten = in.length();
|
||||||
}
|
}
|
||||||
@ -106,41 +110,42 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st)
|
|||||||
std::vector <punycode_uint> unichars;
|
std::vector <punycode_uint> unichars;
|
||||||
unichars.reserve(inUTF8.length());
|
unichars.reserve(inUTF8.length());
|
||||||
|
|
||||||
while (ch < end)
|
while (ch < end) {
|
||||||
{
|
|
||||||
const utf8::uint32_t uc = utf8::unchecked::next(ch);
|
const utf8::uint32_t uc = utf8::unchecked::next(ch);
|
||||||
unichars.push_back(uc);
|
unichars.push_back(uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st)
|
if (st) {
|
||||||
st->inputBytesRead = in.length();
|
st->inputBytesRead = in.length();
|
||||||
|
}
|
||||||
|
|
||||||
punycode_uint inputLen = static_cast <punycode_uint>(unichars.size());
|
punycode_uint inputLen = static_cast <punycode_uint>(unichars.size());
|
||||||
|
|
||||||
std::vector <char> output(inUTF8.length() * 2);
|
std::vector <char> output(inUTF8.length() * 2);
|
||||||
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
|
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
|
||||||
|
|
||||||
const punycode_status status = punycode_encode
|
const punycode_status status = punycode_encode(
|
||||||
(inputLen, &unichars[0], /* case_flags */ NULL, &outputLen, &output[0]);
|
inputLen, &unichars[0], /* case_flags */ NULL, &outputLen, &output[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (status == punycode_success) {
|
||||||
|
|
||||||
if (status == punycode_success)
|
|
||||||
{
|
|
||||||
out = string("xn--") + string(output.begin(), output.begin() + outputLen);
|
out = string("xn--") + string(output.begin(), output.begin() + outputLen);
|
||||||
|
|
||||||
if (st)
|
if (st) {
|
||||||
st->outputBytesWritten = out.length();
|
st->outputBytesWritten = out.length();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
} else {
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (m_source == "idna")
|
} else if (m_source == "idna") {
|
||||||
{
|
|
||||||
if (in.length() < 5 || in.substr(0, 4) != "xn--")
|
if (in.length() < 5 || in.substr(0, 4) != "xn--") {
|
||||||
{
|
|
||||||
if (st)
|
if (st) {
|
||||||
{
|
|
||||||
st->inputBytesRead = in.length();
|
st->inputBytesRead = in.length();
|
||||||
st->outputBytesWritten = in.length();
|
st->outputBytesWritten = in.length();
|
||||||
}
|
}
|
||||||
@ -155,31 +160,34 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st)
|
|||||||
std::vector <punycode_uint> output(in.length() - 4);
|
std::vector <punycode_uint> output(in.length() - 4);
|
||||||
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
|
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
|
||||||
|
|
||||||
const punycode_status status = punycode_decode
|
const punycode_status status = punycode_decode(
|
||||||
(inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL);
|
inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL
|
||||||
|
);
|
||||||
|
|
||||||
if (st)
|
if (st) {
|
||||||
st->inputBytesRead = in.length();
|
st->inputBytesRead = in.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == punycode_success) {
|
||||||
|
|
||||||
if (status == punycode_success)
|
|
||||||
{
|
|
||||||
std::vector <char> outUTF8Bytes(outputLen * 4);
|
std::vector <char> outUTF8Bytes(outputLen * 4);
|
||||||
char* p = &outUTF8Bytes[0];
|
char* p = &outUTF8Bytes[0];
|
||||||
|
|
||||||
for (std::vector <punycode_uint>::const_iterator it = output.begin() ;
|
for (std::vector <punycode_uint>::const_iterator it = output.begin() ;
|
||||||
it != output.begin() + outputLen ; ++it)
|
it != output.begin() + outputLen ; ++it) {
|
||||||
{
|
|
||||||
p = utf8::unchecked::append(*it, p);
|
p = utf8::unchecked::append(*it, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
string outUTF8(&outUTF8Bytes[0], p);
|
string outUTF8(&outUTF8Bytes[0], p);
|
||||||
charset::convert(outUTF8, out, vmime::charsets::UTF_8, m_dest);
|
charset::convert(outUTF8, out, vmime::charsets::UTF_8, m_dest);
|
||||||
|
|
||||||
if (st)
|
if (st) {
|
||||||
st->outputBytesWritten = out.length();
|
st->outputBytesWritten = out.length();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
} else {
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,9 +195,12 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st)
|
|||||||
|
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream>
|
shared_ptr <utility::charsetFilteredOutputStream>
|
||||||
charsetConverter_idna::getFilteredOutputStream
|
charsetConverter_idna::getFilteredOutputStream(
|
||||||
(utility::outputStream& /* os */, const charsetConverterOptions& /* opts */)
|
utility::outputStream& /* os */,
|
||||||
{
|
const charsetConverterOptions& /* opts */
|
||||||
|
) {
|
||||||
|
|
||||||
|
// Not supported
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -28,15 +28,13 @@
|
|||||||
#include "vmime/charsetConverter.hpp"
|
#include "vmime/charsetConverter.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** A charset converter which can convert to and from Punycode (for IDNA).
|
/** A charset converter which can convert to and from Punycode (for IDNA).
|
||||||
*/
|
*/
|
||||||
|
class charsetConverter_idna : public charsetConverter {
|
||||||
|
|
||||||
class charsetConverter_idna : public charsetConverter
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Construct and initialize an IDNA charset converter.
|
/** Construct and initialize an IDNA charset converter.
|
||||||
@ -45,17 +43,21 @@ public:
|
|||||||
* @param dest output charset
|
* @param dest output charset
|
||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
*/
|
*/
|
||||||
charsetConverter_idna(const charset& source, const charset& dest,
|
charsetConverter_idna(
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charset& source,
|
||||||
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
~charsetConverter_idna();
|
~charsetConverter_idna();
|
||||||
|
|
||||||
void convert(const string& in, string& out, status* st = NULL);
|
void convert(const string& in, string& out, status* st = NULL);
|
||||||
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
|
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
|
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
|
||||||
(utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -49,37 +49,46 @@
|
|||||||
#define CP_UNICODE 1200
|
#define CP_UNICODE 1200
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
|
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
|
||||||
(const charset& source, const charset& dest,
|
const charset& source,
|
||||||
const charsetConverterOptions& opts)
|
const charset& dest,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
) {
|
||||||
|
|
||||||
return make_shared <charsetConverter_win>(source, dest, opts);
|
return make_shared <charsetConverter_win>(source, dest, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charsetConverter_win::charsetConverter_win
|
charsetConverter_win::charsetConverter_win(
|
||||||
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
|
const charset& source,
|
||||||
: m_source(source), m_dest(dest), m_options(opts)
|
const charset& dest,
|
||||||
{
|
const charsetConverterOptions& opts
|
||||||
|
)
|
||||||
|
: m_source(source),
|
||||||
|
m_dest(dest),
|
||||||
|
m_options(opts) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_win::convert
|
void charsetConverter_win::convert(
|
||||||
(utility::inputStream& in, utility::outputStream& out, status* st)
|
utility::inputStream& in,
|
||||||
{
|
utility::outputStream& out,
|
||||||
if (st)
|
status* st
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (st) {
|
||||||
new (st) status();
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
byte_t buffer[32768];
|
byte_t buffer[32768];
|
||||||
string inStr, outStr;
|
string inStr, outStr;
|
||||||
|
|
||||||
while (!in.eof())
|
while (!in.eof()) {
|
||||||
{
|
|
||||||
const size_t len = in.read(buffer, sizeof(buffer));
|
const size_t len = in.read(buffer, sizeof(buffer));
|
||||||
utility::stringUtils::appendBytesToString(inStr, buffer, len);
|
utility::stringUtils::appendBytesToString(inStr, buffer, len);
|
||||||
}
|
}
|
||||||
@ -90,10 +99,11 @@ void charsetConverter_win::convert
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void charsetConverter_win::convert(const string& in, string& out, status* st)
|
void charsetConverter_win::convert(const string& in, string& out, status* st) {
|
||||||
{
|
|
||||||
if (st)
|
if (st) {
|
||||||
new (st) status();
|
new (st) status();
|
||||||
|
}
|
||||||
|
|
||||||
const int sourceCodePage = getCodePage(m_source.getName().c_str());
|
const int sourceCodePage = getCodePage(m_source.getName().c_str());
|
||||||
const int destCodePage = getCodePage(m_dest.getName().c_str());
|
const int destCodePage = getCodePage(m_dest.getName().c_str());
|
||||||
@ -103,69 +113,77 @@ void charsetConverter_win::convert(const string& in, string& out, status* st)
|
|||||||
const WCHAR* unicodePtr = NULL;
|
const WCHAR* unicodePtr = NULL;
|
||||||
size_t unicodeLen = 0;
|
size_t unicodeLen = 0;
|
||||||
|
|
||||||
if (sourceCodePage == CP_UNICODE)
|
if (sourceCodePage == CP_UNICODE) {
|
||||||
{
|
|
||||||
unicodePtr = reinterpret_cast <const WCHAR*>(in.c_str());
|
unicodePtr = reinterpret_cast <const WCHAR*>(in.c_str());
|
||||||
unicodeLen = in.length() / 2;
|
unicodeLen = in.length() / 2;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const size_t bufferSize = MultiByteToWideChar
|
const size_t bufferSize = MultiByteToWideChar(
|
||||||
(sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
|
sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()), NULL, 0
|
||||||
NULL, 0) * sizeof(WCHAR); // in wide characters
|
) * sizeof(WCHAR); // in wide characters
|
||||||
|
|
||||||
unicodeBuffer.resize(bufferSize);
|
unicodeBuffer.resize(bufferSize);
|
||||||
|
|
||||||
DWORD flags = 0;
|
DWORD flags = 0;
|
||||||
|
|
||||||
if (!m_options.silentlyReplaceInvalidSequences)
|
if (!m_options.silentlyReplaceInvalidSequences) {
|
||||||
flags |= MB_ERR_INVALID_CHARS;
|
flags |= MB_ERR_INVALID_CHARS;
|
||||||
|
}
|
||||||
|
|
||||||
unicodePtr = reinterpret_cast <const WCHAR*>(&unicodeBuffer[0]);
|
unicodePtr = reinterpret_cast <const WCHAR*>(&unicodeBuffer[0]);
|
||||||
unicodeLen = MultiByteToWideChar
|
unicodeLen = MultiByteToWideChar(
|
||||||
(sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
|
sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
|
||||||
reinterpret_cast <WCHAR*>(&unicodeBuffer[0]), static_cast <int>(bufferSize));
|
reinterpret_cast <WCHAR*>(&unicodeBuffer[0]), static_cast <int>(bufferSize)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (unicodeLen == 0) {
|
||||||
|
|
||||||
|
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
|
||||||
|
|
||||||
if (unicodeLen == 0)
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION)
|
|
||||||
{
|
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error("MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName());
|
throw exceptions::charset_conv_error(
|
||||||
|
"MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert from Unicode to destination charset
|
// Convert from Unicode to destination charset
|
||||||
if (destCodePage == CP_UNICODE)
|
if (destCodePage == CP_UNICODE) {
|
||||||
{
|
|
||||||
out.assign(reinterpret_cast <const char*>(unicodePtr), unicodeLen * 2);
|
out.assign(reinterpret_cast <const char*>(unicodePtr), unicodeLen * 2);
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
const size_t bufferSize = WideCharToMultiByte
|
const size_t bufferSize = WideCharToMultiByte(
|
||||||
(destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
|
destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
|
||||||
NULL, 0, 0, NULL); // in multibyte characters
|
NULL, 0, 0, NULL
|
||||||
|
); // in multibyte characters
|
||||||
|
|
||||||
std::vector <char> buffer;
|
std::vector <char> buffer;
|
||||||
buffer.resize(bufferSize);
|
buffer.resize(bufferSize);
|
||||||
|
|
||||||
const size_t len = WideCharToMultiByte
|
const size_t len = WideCharToMultiByte(
|
||||||
(destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
|
destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
|
||||||
&buffer[0], static_cast <int>(bufferSize), 0, NULL);
|
&buffer[0], static_cast <int>(bufferSize), 0, NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
|
||||||
|
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
|
||||||
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION)
|
|
||||||
{
|
|
||||||
throw exceptions::illegal_byte_sequence_for_charset();
|
throw exceptions::illegal_byte_sequence_for_charset();
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
throw exceptions::charset_conv_error("WideCharToMultiByte() failed when converting from Unicode to " + m_source.getName());
|
throw exceptions::charset_conv_error(
|
||||||
|
"WideCharToMultiByte() failed when converting from Unicode to " + m_source.getName()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,15 +193,16 @@ void charsetConverter_win::convert(const string& in, string& out, status* st)
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int charsetConverter_win::getCodePage(const char* name)
|
int charsetConverter_win::getCodePage(const char* name) {
|
||||||
{
|
|
||||||
if (_stricmp(name, charsets::UTF_16) == 0) // wchar_t is UTF-16 on Windows
|
if (_stricmp(name, charsets::UTF_16) == 0) { // wchar_t is UTF-16 on Windows
|
||||||
return CP_UNICODE;
|
return CP_UNICODE;
|
||||||
|
}
|
||||||
|
|
||||||
// "cp1252" --> return 1252
|
// "cp1252" --> return 1252
|
||||||
if ((name[0] == 'c' || name[0] == 'C') &&
|
if ((name[0] == 'c' || name[0] == 'C') &&
|
||||||
(name[1] == 'p' || name[1] == 'P'))
|
(name[1] == 'p' || name[1] == 'P')) {
|
||||||
{
|
|
||||||
return atoi(name + 2);
|
return atoi(name + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,9 +211,11 @@ int charsetConverter_win::getCodePage(const char* name)
|
|||||||
|
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream>
|
shared_ptr <utility::charsetFilteredOutputStream>
|
||||||
charsetConverter_win::getFilteredOutputStream
|
charsetConverter_win::getFilteredOutputStream(
|
||||||
(utility::outputStream& /* os */, const charsetConverterOptions& /* opts */)
|
utility::outputStream& /* os */,
|
||||||
{
|
const charsetConverterOptions& /* opts */
|
||||||
|
) {
|
||||||
|
|
||||||
// TODO: implement me!
|
// TODO: implement me!
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,8 +34,7 @@
|
|||||||
#include "vmime/charsetConverter.hpp"
|
#include "vmime/charsetConverter.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** A generic charset converter which uses Windows MultiByteToWideChar
|
/** A generic charset converter which uses Windows MultiByteToWideChar
|
||||||
@ -49,9 +48,8 @@ namespace vmime
|
|||||||
*
|
*
|
||||||
* Also, "status" is not supported by this converter for the same reason.
|
* Also, "status" is not supported by this converter for the same reason.
|
||||||
*/
|
*/
|
||||||
|
class charsetConverter_win : public charsetConverter {
|
||||||
|
|
||||||
class charsetConverter_win : public charsetConverter
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Construct and initialize a Windows charset converter.
|
/** Construct and initialize a Windows charset converter.
|
||||||
@ -60,14 +58,19 @@ public:
|
|||||||
* @param dest output charset
|
* @param dest output charset
|
||||||
* @param opts conversion options
|
* @param opts conversion options
|
||||||
*/
|
*/
|
||||||
charsetConverter_win(const charset& source, const charset& dest,
|
charsetConverter_win(
|
||||||
const charsetConverterOptions& opts = charsetConverterOptions());
|
const charset& source,
|
||||||
|
const charset& dest,
|
||||||
|
const charsetConverterOptions& opts = charsetConverterOptions()
|
||||||
|
);
|
||||||
|
|
||||||
void convert(const string& in, string& out, status* st);
|
void convert(const string& in, string& out, status* st);
|
||||||
void convert(utility::inputStream& in, utility::outputStream& out, status* st);
|
void convert(utility::inputStream& in, utility::outputStream& out, status* st);
|
||||||
|
|
||||||
shared_ptr <utility::charsetFilteredOutputStream>
|
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
|
||||||
getFilteredOutputStream(utility::outputStream& os, const charsetConverterOptions& opts);
|
utility::outputStream& os,
|
||||||
|
const charsetConverterOptions& opts
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -31,48 +31,54 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
component::component()
|
component::component()
|
||||||
: m_parsedOffset(0), m_parsedLength(0)
|
: m_parsedOffset(0), m_parsedLength(0) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
component::~component()
|
component::~component() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse
|
void component::parse(
|
||||||
(shared_ptr <utility::inputStream> inputStream, const size_t length)
|
const shared_ptr <utility::inputStream>& inputStream,
|
||||||
{
|
const size_t length
|
||||||
|
) {
|
||||||
|
|
||||||
parse(inputStream, 0, length, NULL);
|
parse(inputStream, 0, length, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse
|
void component::parse(
|
||||||
(shared_ptr <utility::inputStream> inputStream, const size_t position,
|
const shared_ptr <utility::inputStream>& inputStream,
|
||||||
const size_t end, size_t* newPosition)
|
const size_t position,
|
||||||
{
|
const size_t end,
|
||||||
|
size_t* newPosition) {
|
||||||
|
|
||||||
parse(parsingContext::getDefaultContext(), inputStream, position, end, newPosition);
|
parse(parsingContext::getDefaultContext(), inputStream, position, end, newPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse
|
void component::parse(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
shared_ptr <utility::inputStream> inputStream, const size_t position,
|
const shared_ptr <utility::inputStream>& inputStream,
|
||||||
const size_t end, size_t* newPosition)
|
const size_t position,
|
||||||
{
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
m_parsedOffset = m_parsedLength = 0;
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
shared_ptr <utility::seekableInputStream> seekableStream =
|
shared_ptr <utility::seekableInputStream> seekableStream =
|
||||||
dynamicCast <utility::seekableInputStream>(inputStream);
|
dynamicCast <utility::seekableInputStream>(inputStream);
|
||||||
|
|
||||||
if (seekableStream == NULL || end == 0)
|
if (!seekableStream || end == 0) {
|
||||||
{
|
|
||||||
// Read the whole stream into a buffer
|
// Read the whole stream into a buffer
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
utility::outputStreamAdapter ossAdapter(oss);
|
utility::outputStreamAdapter ossAdapter(oss);
|
||||||
@ -81,9 +87,9 @@ void component::parse
|
|||||||
|
|
||||||
const string buffer = oss.str();
|
const string buffer = oss.str();
|
||||||
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
|
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
shared_ptr <utility::parserInputStreamAdapter> parser =
|
shared_ptr <utility::parserInputStreamAdapter> parser =
|
||||||
make_shared <utility::parserInputStreamAdapter>(seekableStream);
|
make_shared <utility::parserInputStreamAdapter>(seekableStream);
|
||||||
|
|
||||||
@ -92,79 +98,95 @@ void component::parse
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse(const string& buffer)
|
void component::parse(const string& buffer) {
|
||||||
{
|
|
||||||
m_parsedOffset = m_parsedLength = 0;
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
parseImpl(parsingContext::getDefaultContext(), buffer, 0, buffer.length(), NULL);
|
parseImpl(parsingContext::getDefaultContext(), buffer, 0, buffer.length(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse(const parsingContext& ctx, const string& buffer)
|
void component::parse(const parsingContext& ctx, const string& buffer) {
|
||||||
{
|
|
||||||
m_parsedOffset = m_parsedLength = 0;
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
|
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse
|
void component::parse(
|
||||||
(const string& buffer, const size_t position,
|
const string& buffer,
|
||||||
const size_t end, size_t* newPosition)
|
const size_t position,
|
||||||
{
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
m_parsedOffset = m_parsedLength = 0;
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
parseImpl(parsingContext::getDefaultContext(), buffer, position, end, newPosition);
|
parseImpl(parsingContext::getDefaultContext(), buffer, position, end, newPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse
|
void component::parse(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer, const size_t position,
|
const string& buffer,
|
||||||
const size_t end, size_t* newPosition)
|
const size_t position,
|
||||||
{
|
const size_t end, size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
m_parsedOffset = m_parsedLength = 0;
|
m_parsedOffset = m_parsedLength = 0;
|
||||||
|
|
||||||
parseImpl(ctx, buffer, position, end, newPosition);
|
parseImpl(ctx, buffer, position, end, newPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::offsetParsedBounds(const size_t offset)
|
void component::offsetParsedBounds(const size_t offset) {
|
||||||
{
|
|
||||||
// Offset parsed bounds of this component
|
// Offset parsed bounds of this component
|
||||||
if (m_parsedLength != 0)
|
if (m_parsedLength != 0) {
|
||||||
m_parsedOffset += offset;
|
m_parsedOffset += offset;
|
||||||
|
}
|
||||||
|
|
||||||
// Offset parsed bounds of our children
|
// Offset parsed bounds of our children
|
||||||
std::vector <shared_ptr <component> > children = getChildComponents();
|
std::vector <shared_ptr <component> > children = getChildComponents();
|
||||||
|
|
||||||
for (size_t i = 0, n = children.size() ; i < n ; ++i)
|
for (size_t i = 0, n = children.size() ; i < n ; ++i) {
|
||||||
children[i]->offsetParsedBounds(offset);
|
children[i]->offsetParsedBounds(offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parseImpl
|
void component::parseImpl(
|
||||||
(const parsingContext& ctx, shared_ptr <utility::parserInputStreamAdapter> parser,
|
const parsingContext& ctx,
|
||||||
const size_t position, const size_t end, size_t* newPosition)
|
const shared_ptr <utility::parserInputStreamAdapter>& parser,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
// This is the default implementation for parsing from an input stream:
|
// This is the default implementation for parsing from an input stream:
|
||||||
// actually, we extract the substring and use the "parse from string" implementation
|
// actually, we extract the substring and use the "parse from string" implementation
|
||||||
const string buffer = parser->extract(position, end);
|
const string buffer = parser->extract(position, end);
|
||||||
parseImpl(ctx, buffer, 0, buffer.length(), newPosition);
|
parseImpl(ctx, buffer, 0, buffer.length(), newPosition);
|
||||||
|
|
||||||
// Recursivey offset parsed bounds on children
|
// Recursivey offset parsed bounds on children
|
||||||
if (position != 0)
|
if (position != 0) {
|
||||||
offsetParsedBounds(position);
|
offsetParsedBounds(position);
|
||||||
|
}
|
||||||
|
|
||||||
if (newPosition != NULL)
|
if (newPosition) {
|
||||||
*newPosition += position;
|
*newPosition += position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parseImpl
|
void component::parseImpl(
|
||||||
(const parsingContext& ctx, const string& buffer, const size_t position,
|
const parsingContext& ctx,
|
||||||
const size_t end, size_t* newPosition)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition) {
|
||||||
|
|
||||||
// This is the default implementation for parsing from a string:
|
// This is the default implementation for parsing from a string:
|
||||||
// actually, we encapsulate the string buffer in an input stream, then use
|
// actually, we encapsulate the string buffer in an input stream, then use
|
||||||
// the "parse from input stream" implementation
|
// the "parse from input stream" implementation
|
||||||
@ -178,9 +200,11 @@ void component::parseImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string component::generate
|
const string component::generate(
|
||||||
(const size_t maxLineLength, const size_t curLinePos) const
|
const size_t maxLineLength,
|
||||||
{
|
const size_t curLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
utility::outputStreamAdapter adapter(oss);
|
utility::outputStreamAdapter adapter(oss);
|
||||||
|
|
||||||
@ -189,56 +213,63 @@ const string component::generate
|
|||||||
|
|
||||||
generateImpl(ctx, adapter, curLinePos, NULL);
|
generateImpl(ctx, adapter, curLinePos, NULL);
|
||||||
|
|
||||||
return (oss.str());
|
return oss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::generate
|
void component::generate(
|
||||||
(utility::outputStream& os, const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t curLinePos,
|
||||||
generateImpl(generationContext::getDefaultContext(),
|
size_t* newLinePos
|
||||||
os, curLinePos, newLinePos);
|
) const {
|
||||||
|
|
||||||
|
generateImpl(generationContext::getDefaultContext(), os, curLinePos, newLinePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::generate
|
void component::generate(
|
||||||
(const generationContext& ctx, utility::outputStream& outputStream,
|
const generationContext& ctx,
|
||||||
const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& outputStream,
|
||||||
{
|
const size_t curLinePos,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
generateImpl(ctx, outputStream, curLinePos, newLinePos);
|
generateImpl(ctx, outputStream, curLinePos, newLinePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t component::getParsedOffset() const
|
size_t component::getParsedOffset() const {
|
||||||
{
|
|
||||||
return (m_parsedOffset);
|
return m_parsedOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t component::getParsedLength() const
|
size_t component::getParsedLength() const {
|
||||||
{
|
|
||||||
return (m_parsedLength);
|
return m_parsedLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::setParsedBounds(const size_t start, const size_t end)
|
void component::setParsedBounds(const size_t start, const size_t end) {
|
||||||
{
|
|
||||||
m_parsedOffset = start;
|
m_parsedOffset = start;
|
||||||
m_parsedLength = end - start;
|
m_parsedLength = end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t component::getGeneratedSize(const generationContext& ctx)
|
size_t component::getGeneratedSize(const generationContext& ctx) {
|
||||||
{
|
|
||||||
std::vector <shared_ptr <component> > children = getChildComponents();
|
std::vector <shared_ptr <component> > children = getChildComponents();
|
||||||
size_t totalSize = 0;
|
size_t totalSize = 0;
|
||||||
|
|
||||||
for (std::vector <shared_ptr <component> >::iterator it = children.begin() ; it != children.end() ; ++it)
|
for (std::vector <shared_ptr <component> >::iterator it = children.begin() ;
|
||||||
|
it != children.end() ; ++it) {
|
||||||
|
|
||||||
totalSize += (*it)->getGeneratedSize(ctx);
|
totalSize += (*it)->getGeneratedSize(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
return totalSize;
|
return totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,16 +34,14 @@
|
|||||||
#include "vmime/parsingContext.hpp"
|
#include "vmime/parsingContext.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** This abstract class is the base class for all the components of a message.
|
/** This abstract class is the base class for all the components of a message.
|
||||||
* It defines methods for parsing and generating a component.
|
* It defines methods for parsing and generating a component.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT component : public object {
|
||||||
|
|
||||||
class VMIME_EXPORT component : public object
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
component();
|
component();
|
||||||
@ -70,7 +68,7 @@ public:
|
|||||||
* @param inputStream stream from which to read data
|
* @param inputStream stream from which to read data
|
||||||
* @param length data length, in bytes (0 = unknown/not specified)
|
* @param length data length, in bytes (0 = unknown/not specified)
|
||||||
*/
|
*/
|
||||||
void parse(shared_ptr <utility::inputStream> inputStream, const size_t length);
|
void parse(const shared_ptr <utility::inputStream>& inputStream, const size_t length);
|
||||||
|
|
||||||
/** Parse RFC-822/MIME data for this component, using the default
|
/** Parse RFC-822/MIME data for this component, using the default
|
||||||
* parsing context.
|
* parsing context.
|
||||||
@ -80,11 +78,12 @@ public:
|
|||||||
* @param end end position in the input buffer
|
* @param end end position in the input buffer
|
||||||
* @param newPosition will receive the new position in the input buffer
|
* @param newPosition will receive the new position in the input buffer
|
||||||
*/
|
*/
|
||||||
void parse
|
void parse(
|
||||||
(const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
/** Parse RFC-822/MIME data for this component.
|
/** Parse RFC-822/MIME data for this component.
|
||||||
*
|
*
|
||||||
@ -94,12 +93,13 @@ public:
|
|||||||
* @param end end position in the input buffer
|
* @param end end position in the input buffer
|
||||||
* @param newPosition will receive the new position in the input buffer
|
* @param newPosition will receive the new position in the input buffer
|
||||||
*/
|
*/
|
||||||
void parse
|
void parse(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
||||||
* or if end position is not specified, entire contents of the stream will
|
* or if end position is not specified, entire contents of the stream will
|
||||||
@ -111,11 +111,12 @@ public:
|
|||||||
* @param end end position in the input stream
|
* @param end end position in the input stream
|
||||||
* @param newPosition will receive the new position in the input stream
|
* @param newPosition will receive the new position in the input stream
|
||||||
*/
|
*/
|
||||||
void parse
|
void parse(
|
||||||
(shared_ptr <utility::inputStream> inputStream,
|
const shared_ptr <utility::inputStream>& inputStream,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
|
||||||
* or if end position is not specified, entire contents of the stream will
|
* or if end position is not specified, entire contents of the stream will
|
||||||
@ -127,12 +128,13 @@ public:
|
|||||||
* @param end end position in the input stream
|
* @param end end position in the input stream
|
||||||
* @param newPosition will receive the new position in the input stream
|
* @param newPosition will receive the new position in the input stream
|
||||||
*/
|
*/
|
||||||
void parse
|
void parse(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
shared_ptr <utility::inputStream> inputStream,
|
const shared_ptr <utility::inputStream>& inputStream,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
/** Generate RFC-2822/MIME data for this component.
|
/** Generate RFC-2822/MIME data for this component.
|
||||||
*
|
*
|
||||||
@ -142,9 +144,10 @@ public:
|
|||||||
* @param curLinePos length of the current line in the output buffer
|
* @param curLinePos length of the current line in the output buffer
|
||||||
* @return generated data
|
* @return generated data
|
||||||
*/
|
*/
|
||||||
virtual const string generate
|
virtual const string generate(
|
||||||
(const size_t maxLineLength = lineLengthLimits::infinite,
|
const size_t maxLineLength = lineLengthLimits::infinite,
|
||||||
const size_t curLinePos = 0) const;
|
const size_t curLinePos = 0
|
||||||
|
) const;
|
||||||
|
|
||||||
/** Generate RFC-2822/MIME data for this component, using the default generation context.
|
/** Generate RFC-2822/MIME data for this component, using the default generation context.
|
||||||
*
|
*
|
||||||
@ -152,10 +155,11 @@ public:
|
|||||||
* @param curLinePos length of the current line in the output buffer
|
* @param curLinePos length of the current line in the output buffer
|
||||||
* @param newLinePos will receive the new line position (length of the last line written)
|
* @param newLinePos will receive the new line position (length of the last line written)
|
||||||
*/
|
*/
|
||||||
virtual void generate
|
virtual void generate(
|
||||||
(utility::outputStream& outputStream,
|
utility::outputStream& outputStream,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
|
|
||||||
/** Generate RFC-2822/MIME data for this component, using the default generation context.
|
/** Generate RFC-2822/MIME data for this component, using the default generation context.
|
||||||
*
|
*
|
||||||
@ -164,11 +168,12 @@ public:
|
|||||||
* @param curLinePos length of the current line in the output buffer
|
* @param curLinePos length of the current line in the output buffer
|
||||||
* @param newLinePos will receive the new line position (length of the last line written)
|
* @param newLinePos will receive the new line position (length of the last line written)
|
||||||
*/
|
*/
|
||||||
virtual void generate
|
virtual void generate(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& outputStream,
|
utility::outputStream& outputStream,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
|
|
||||||
/** Clone this component.
|
/** Clone this component.
|
||||||
*
|
*
|
||||||
@ -222,25 +227,28 @@ protected:
|
|||||||
void setParsedBounds(const size_t start, const size_t end);
|
void setParsedBounds(const size_t start, const size_t end);
|
||||||
|
|
||||||
// AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class
|
// AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class
|
||||||
virtual void parseImpl
|
virtual void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
shared_ptr <utility::parserInputStreamAdapter> parser,
|
const shared_ptr <utility::parserInputStreamAdapter>& parser,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
virtual void parseImpl
|
virtual void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
virtual void generateImpl
|
virtual void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const = 0;
|
size_t* newLinePos = NULL
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -24,13 +24,12 @@
|
|||||||
#include "vmime/constants.hpp"
|
#include "vmime/constants.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// Media Types
|
// Media Types
|
||||||
namespace mediaTypes
|
namespace mediaTypes {
|
||||||
{
|
|
||||||
// Types
|
// Types
|
||||||
const char* const TEXT = "text";
|
const char* const TEXT = "text";
|
||||||
const char* const MULTIPART = "multipart";
|
const char* const MULTIPART = "multipart";
|
||||||
@ -72,8 +71,8 @@ namespace mediaTypes
|
|||||||
|
|
||||||
|
|
||||||
// Encoding types
|
// Encoding types
|
||||||
namespace encodingTypes
|
namespace encodingTypes {
|
||||||
{
|
|
||||||
const char* const SEVEN_BIT = "7bit";
|
const char* const SEVEN_BIT = "7bit";
|
||||||
const char* const EIGHT_BIT = "8bit";
|
const char* const EIGHT_BIT = "8bit";
|
||||||
const char* const BASE64 = "base64";
|
const char* const BASE64 = "base64";
|
||||||
@ -84,16 +83,16 @@ namespace encodingTypes
|
|||||||
|
|
||||||
|
|
||||||
// Content disposition types
|
// Content disposition types
|
||||||
namespace contentDispositionTypes
|
namespace contentDispositionTypes {
|
||||||
{
|
|
||||||
const char* const INLINE = "inline";
|
const char* const INLINE = "inline";
|
||||||
const char* const ATTACHMENT = "attachment";
|
const char* const ATTACHMENT = "attachment";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Charsets
|
// Charsets
|
||||||
namespace charsets
|
namespace charsets {
|
||||||
{
|
|
||||||
const char* const ISO8859_1 = "iso-8859-1";
|
const char* const ISO8859_1 = "iso-8859-1";
|
||||||
const char* const ISO8859_2 = "iso-8859-2";
|
const char* const ISO8859_2 = "iso-8859-2";
|
||||||
const char* const ISO8859_3 = "iso-8859-3";
|
const char* const ISO8859_3 = "iso-8859-3";
|
||||||
@ -159,8 +158,8 @@ namespace charsets
|
|||||||
|
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
namespace fields
|
namespace fields {
|
||||||
{
|
|
||||||
const char* const RECEIVED = "Received";
|
const char* const RECEIVED = "Received";
|
||||||
const char* const FROM = "From";
|
const char* const FROM = "From";
|
||||||
const char* const SENDER = "Sender";
|
const char* const SENDER = "Sender";
|
||||||
@ -204,32 +203,32 @@ namespace fields
|
|||||||
|
|
||||||
|
|
||||||
// Constants for disposition action modes (RFC-3978).
|
// Constants for disposition action modes (RFC-3978).
|
||||||
namespace dispositionActionModes
|
namespace dispositionActionModes {
|
||||||
{
|
|
||||||
const char* const MANUAL = "manual";
|
const char* const MANUAL = "manual";
|
||||||
const char* const AUTOMATIC = "automatic";
|
const char* const AUTOMATIC = "automatic";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Constants for disposition sending modes (RFC-3798).
|
// Constants for disposition sending modes (RFC-3798).
|
||||||
namespace dispositionSendingModes
|
namespace dispositionSendingModes {
|
||||||
{
|
|
||||||
const char* const SENT_MANUALLY = "MDN-sent-manually";
|
const char* const SENT_MANUALLY = "MDN-sent-manually";
|
||||||
const char* const SENT_AUTOMATICALLY ="MDN-sent-automatically";
|
const char* const SENT_AUTOMATICALLY ="MDN-sent-automatically";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Constants for disposition types (RFC-3798).
|
// Constants for disposition types (RFC-3798).
|
||||||
namespace dispositionTypes
|
namespace dispositionTypes {
|
||||||
{
|
|
||||||
const char* const DISPLAYED = "displayed";
|
const char* const DISPLAYED = "displayed";
|
||||||
const char* const DELETED = "deleted";
|
const char* const DELETED = "deleted";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Constants for disposition modifiers (RFC-3798).
|
// Constants for disposition modifiers (RFC-3798).
|
||||||
namespace dispositionModifiers
|
namespace dispositionModifiers {
|
||||||
{
|
|
||||||
const char* const ERROR = "error";
|
const char* const ERROR = "error";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free SOFTWARE; you can redistribute it and/or
|
// This program is free SOFTWARE; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -37,11 +37,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
/** Constants for media types. */
|
/** Constants for media types. */
|
||||||
namespace mediaTypes
|
namespace mediaTypes {
|
||||||
{
|
|
||||||
// Types
|
// Types
|
||||||
extern VMIME_EXPORT const char* const TEXT;
|
extern VMIME_EXPORT const char* const TEXT;
|
||||||
extern VMIME_EXPORT const char* const MULTIPART;
|
extern VMIME_EXPORT const char* const MULTIPART;
|
||||||
@ -83,8 +83,8 @@ namespace vmime
|
|||||||
|
|
||||||
|
|
||||||
/** Constants for encoding types. */
|
/** Constants for encoding types. */
|
||||||
namespace encodingTypes
|
namespace encodingTypes {
|
||||||
{
|
|
||||||
extern VMIME_EXPORT const char* const SEVEN_BIT;
|
extern VMIME_EXPORT const char* const SEVEN_BIT;
|
||||||
extern VMIME_EXPORT const char* const EIGHT_BIT;
|
extern VMIME_EXPORT const char* const EIGHT_BIT;
|
||||||
extern VMIME_EXPORT const char* const BASE64;
|
extern VMIME_EXPORT const char* const BASE64;
|
||||||
@ -95,16 +95,16 @@ namespace vmime
|
|||||||
|
|
||||||
|
|
||||||
/** Constants for content disposition types (RFC-2183). */
|
/** Constants for content disposition types (RFC-2183). */
|
||||||
namespace contentDispositionTypes
|
namespace contentDispositionTypes {
|
||||||
{
|
|
||||||
extern VMIME_EXPORT const char* const INLINE;
|
extern VMIME_EXPORT const char* const INLINE;
|
||||||
extern VMIME_EXPORT const char* const ATTACHMENT;
|
extern VMIME_EXPORT const char* const ATTACHMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Constants for charsets. */
|
/** Constants for charsets. */
|
||||||
namespace charsets
|
namespace charsets {
|
||||||
{
|
|
||||||
extern VMIME_EXPORT const char* const ISO8859_1;
|
extern VMIME_EXPORT const char* const ISO8859_1;
|
||||||
extern VMIME_EXPORT const char* const ISO8859_2;
|
extern VMIME_EXPORT const char* const ISO8859_2;
|
||||||
extern VMIME_EXPORT const char* const ISO8859_3;
|
extern VMIME_EXPORT const char* const ISO8859_3;
|
||||||
@ -169,8 +169,8 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constants for standard field names. */
|
/** Constants for standard field names. */
|
||||||
namespace fields
|
namespace fields {
|
||||||
{
|
|
||||||
extern VMIME_EXPORT const char* const RECEIVED;
|
extern VMIME_EXPORT const char* const RECEIVED;
|
||||||
extern VMIME_EXPORT const char* const FROM;
|
extern VMIME_EXPORT const char* const FROM;
|
||||||
extern VMIME_EXPORT const char* const SENDER;
|
extern VMIME_EXPORT const char* const SENDER;
|
||||||
@ -213,8 +213,8 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constants for disposition action modes (RFC-3978). */
|
/** Constants for disposition action modes (RFC-3978). */
|
||||||
namespace dispositionActionModes
|
namespace dispositionActionModes {
|
||||||
{
|
|
||||||
/** User implicitely displayed or deleted the message (filter or
|
/** User implicitely displayed or deleted the message (filter or
|
||||||
* any other automatic action). */
|
* any other automatic action). */
|
||||||
extern VMIME_EXPORT const char* const AUTOMATIC;
|
extern VMIME_EXPORT const char* const AUTOMATIC;
|
||||||
@ -224,8 +224,8 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constants for disposition sending modes (RFC-3798). */
|
/** Constants for disposition sending modes (RFC-3798). */
|
||||||
namespace dispositionSendingModes
|
namespace dispositionSendingModes {
|
||||||
{
|
|
||||||
/** The MDN was sent because the MUA had previously been configured
|
/** The MDN was sent because the MUA had previously been configured
|
||||||
* to do so automatically. */
|
* to do so automatically. */
|
||||||
extern VMIME_EXPORT const char* const SENT_AUTOMATICALLY;
|
extern VMIME_EXPORT const char* const SENT_AUTOMATICALLY;
|
||||||
@ -235,8 +235,8 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constants for disposition types (RFC-3798). */
|
/** Constants for disposition types (RFC-3798). */
|
||||||
namespace dispositionTypes
|
namespace dispositionTypes {
|
||||||
{
|
|
||||||
/** Message has been displayed to the user. */
|
/** Message has been displayed to the user. */
|
||||||
extern VMIME_EXPORT const char* const DISPLAYED;
|
extern VMIME_EXPORT const char* const DISPLAYED;
|
||||||
/** Message has been deleted without being displayed. */
|
/** Message has been deleted without being displayed. */
|
||||||
@ -246,8 +246,8 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Constants for disposition modifiers (RFC-3798). */
|
/** Constants for disposition modifiers (RFC-3798). */
|
||||||
namespace dispositionModifiers
|
namespace dispositionModifiers {
|
||||||
{
|
|
||||||
extern VMIME_EXPORT const char* const ERROR;
|
extern VMIME_EXPORT const char* const ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -25,107 +25,118 @@
|
|||||||
#include "vmime/utility/stringUtils.hpp"
|
#include "vmime/utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
contentDisposition::contentDisposition()
|
contentDisposition::contentDisposition()
|
||||||
: m_name(contentDispositionTypes::INLINE)
|
: m_name(contentDispositionTypes::INLINE) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentDisposition::contentDisposition(const string& name)
|
contentDisposition::contentDisposition(const string& name)
|
||||||
: m_name(utility::stringUtils::toLower(name))
|
: m_name(utility::stringUtils::toLower(name)) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentDisposition::contentDisposition(const contentDisposition& type)
|
contentDisposition::contentDisposition(const contentDisposition& type)
|
||||||
: headerFieldValue(), m_name(type.m_name)
|
: headerFieldValue(), m_name(type.m_name) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDisposition::parseImpl
|
void contentDisposition::parseImpl(
|
||||||
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
|
const parsingContext& /* ctx */,
|
||||||
const size_t end, size_t* newPosition)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
m_name = utility::stringUtils::trim(utility::stringUtils::toLower
|
const size_t end,
|
||||||
(string(buffer.begin() + position, buffer.begin() + end)));
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
|
m_name = utility::stringUtils::trim(
|
||||||
|
utility::stringUtils::toLower(
|
||||||
|
string(buffer.begin() + position, buffer.begin() + end)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
setParsedBounds(position, end);
|
setParsedBounds(position, end);
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDisposition::generateImpl
|
void contentDisposition::generateImpl(
|
||||||
(const generationContext& /* ctx */, utility::outputStream& os,
|
const generationContext& /* ctx */,
|
||||||
const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t curLinePos,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
os << m_name;
|
os << m_name;
|
||||||
|
|
||||||
if (newLinePos)
|
if (newLinePos) {
|
||||||
*newLinePos = curLinePos + m_name.length();
|
*newLinePos = curLinePos + m_name.length();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentDisposition& contentDisposition::operator=(const string& name)
|
contentDisposition& contentDisposition::operator=(const string& name) {
|
||||||
{
|
|
||||||
m_name = utility::stringUtils::toLower(name);
|
m_name = utility::stringUtils::toLower(name);
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentDisposition::operator==(const contentDisposition& value) const
|
bool contentDisposition::operator==(const contentDisposition& value) const {
|
||||||
{
|
|
||||||
return (utility::stringUtils::toLower(m_name) == value.m_name);
|
return utility::stringUtils::toLower(m_name) == value.m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentDisposition::operator!=(const contentDisposition& value) const
|
bool contentDisposition::operator!=(const contentDisposition& value) const {
|
||||||
{
|
|
||||||
return !(*this == value);
|
return !(*this == value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component> contentDisposition::clone() const
|
shared_ptr <component> contentDisposition::clone() const {
|
||||||
{
|
|
||||||
return make_shared <contentDisposition>(*this);
|
return make_shared <contentDisposition>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDisposition::copyFrom(const component& other)
|
void contentDisposition::copyFrom(const component& other) {
|
||||||
{
|
|
||||||
const contentDisposition& d = dynamic_cast <const contentDisposition&>(other);
|
const contentDisposition& d = dynamic_cast <const contentDisposition&>(other);
|
||||||
|
|
||||||
m_name = d.m_name;
|
m_name = d.m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentDisposition& contentDisposition::operator=(const contentDisposition& other)
|
contentDisposition& contentDisposition::operator=(const contentDisposition& other) {
|
||||||
{
|
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string& contentDisposition::getName() const
|
const string& contentDisposition::getName() const {
|
||||||
{
|
|
||||||
return (m_name);
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDisposition::setName(const string& name)
|
void contentDisposition::setName(const string& name) {
|
||||||
{
|
|
||||||
m_name = name;
|
m_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <component> > contentDisposition::getChildComponents()
|
const std::vector <shared_ptr <component> > contentDisposition::getChildComponents() {
|
||||||
{
|
|
||||||
return std::vector <shared_ptr <component> >();
|
return std::vector <shared_ptr <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -29,15 +29,13 @@
|
|||||||
#include "vmime/headerFieldValue.hpp"
|
#include "vmime/headerFieldValue.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Content disposition (basic type).
|
/** Content disposition (basic type).
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT contentDisposition : public headerFieldValue {
|
||||||
|
|
||||||
class VMIME_EXPORT contentDisposition : public headerFieldValue
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
contentDisposition();
|
contentDisposition();
|
||||||
@ -78,18 +76,20 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parseImpl
|
void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -25,132 +25,136 @@
|
|||||||
#include "vmime/exception.hpp"
|
#include "vmime/exception.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
contentDispositionField::contentDispositionField()
|
contentDispositionField::contentDispositionField() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentDispositionField::contentDispositionField(contentDispositionField&)
|
contentDispositionField::contentDispositionField(contentDispositionField&)
|
||||||
: parameterizedHeaderField()
|
: parameterizedHeaderField() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentDispositionField::hasCreationDate() const
|
bool contentDispositionField::hasCreationDate() const {
|
||||||
{
|
|
||||||
return hasParameter("creation-date");
|
return hasParameter("creation-date");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const datetime contentDispositionField::getCreationDate() const
|
const datetime contentDispositionField::getCreationDate() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("creation-date");
|
shared_ptr <parameter> param = findParameter("creation-date");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValueAs <datetime>();
|
return param->getValueAs <datetime>();
|
||||||
else
|
} else {
|
||||||
return datetime::now();
|
return datetime::now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDispositionField::setCreationDate(const datetime& creationDate)
|
void contentDispositionField::setCreationDate(const datetime& creationDate) {
|
||||||
{
|
|
||||||
getParameter("creation-date")->setValue(creationDate);
|
getParameter("creation-date")->setValue(creationDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentDispositionField::hasModificationDate() const
|
bool contentDispositionField::hasModificationDate() const {
|
||||||
{
|
|
||||||
return hasParameter("modification-date");
|
return hasParameter("modification-date");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const datetime contentDispositionField::getModificationDate() const
|
const datetime contentDispositionField::getModificationDate() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("modification-date");
|
shared_ptr <parameter> param = findParameter("modification-date");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValueAs <datetime>();
|
return param->getValueAs <datetime>();
|
||||||
else
|
} else {
|
||||||
return datetime::now();
|
return datetime::now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDispositionField::setModificationDate(const datetime& modificationDate)
|
void contentDispositionField::setModificationDate(const datetime& modificationDate) {
|
||||||
{
|
|
||||||
getParameter("modification-date")->setValue(modificationDate);
|
getParameter("modification-date")->setValue(modificationDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentDispositionField::hasReadDate() const
|
bool contentDispositionField::hasReadDate() const {
|
||||||
{
|
|
||||||
return hasParameter("read-date");
|
return hasParameter("read-date");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const datetime contentDispositionField::getReadDate() const
|
const datetime contentDispositionField::getReadDate() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("read-date");
|
shared_ptr <parameter> param = findParameter("read-date");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValueAs <datetime>();
|
return param->getValueAs <datetime>();
|
||||||
else
|
} else {
|
||||||
return datetime::now();
|
return datetime::now();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDispositionField::setReadDate(const datetime& readDate)
|
void contentDispositionField::setReadDate(const datetime& readDate) {
|
||||||
{
|
|
||||||
getParameter("read-date")->setValue(readDate);
|
getParameter("read-date")->setValue(readDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentDispositionField::hasFilename() const
|
bool contentDispositionField::hasFilename() const {
|
||||||
{
|
|
||||||
return hasParameter("filename");
|
return hasParameter("filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const word contentDispositionField::getFilename() const
|
const word contentDispositionField::getFilename() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("filename");
|
shared_ptr <parameter> param = findParameter("filename");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValue();
|
return param->getValue();
|
||||||
else
|
} else {
|
||||||
return word();
|
return word();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDispositionField::setFilename(const word& filename)
|
void contentDispositionField::setFilename(const word& filename) {
|
||||||
{
|
|
||||||
getParameter("filename")->setValue(filename);
|
getParameter("filename")->setValue(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentDispositionField::hasSize() const
|
bool contentDispositionField::hasSize() const {
|
||||||
{
|
|
||||||
return hasParameter("size");
|
return hasParameter("size");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentDispositionField::getSize() const
|
const string contentDispositionField::getSize() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("size");
|
shared_ptr <parameter> param = findParameter("size");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValue().getBuffer();
|
return param->getValue().getBuffer();
|
||||||
else
|
} else {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDispositionField::setSize(const string& size)
|
void contentDispositionField::setSize(const string& size) {
|
||||||
{
|
|
||||||
getParameter("size")->setValue(word(size, vmime::charsets::US_ASCII));
|
getParameter("size")->setValue(word(size, vmime::charsets::US_ASCII));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -32,15 +32,13 @@
|
|||||||
#include "vmime/word.hpp"
|
#include "vmime/word.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Describes presentation information, as per RFC-2183.
|
/** Describes presentation information, as per RFC-2183.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField {
|
||||||
|
|
||||||
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory;
|
friend class headerFieldFactory;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -24,16 +24,15 @@
|
|||||||
#include "vmime/contentHandler.hpp"
|
#include "vmime/contentHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// No encoding = "binary" encoding
|
// No encoding = "binary" encoding
|
||||||
const encoding contentHandler::NO_ENCODING(encodingTypes::BINARY);
|
const encoding contentHandler::NO_ENCODING(encodingTypes::BINARY);
|
||||||
|
|
||||||
|
|
||||||
contentHandler::~contentHandler()
|
contentHandler::~contentHandler() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -34,12 +34,11 @@
|
|||||||
#include "vmime/mediaType.hpp"
|
#include "vmime/mediaType.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class VMIME_EXPORT contentHandler : public object
|
class VMIME_EXPORT contentHandler : public object {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Used to specify that enclosed data is not encoded. */
|
/** Used to specify that enclosed data is not encoded. */
|
||||||
@ -63,7 +62,11 @@ public:
|
|||||||
* @param enc encoding for output
|
* @param enc encoding for output
|
||||||
* @param maxLineLength maximum line length for output
|
* @param maxLineLength maximum line length for output
|
||||||
*/
|
*/
|
||||||
virtual void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const = 0;
|
virtual void generate(
|
||||||
|
utility::outputStream& os,
|
||||||
|
const vmime::encoding& enc,
|
||||||
|
const size_t maxLineLength = lineLengthLimits::infinite
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
/** Extract the contents into the specified stream. If needed, data
|
/** Extract the contents into the specified stream. If needed, data
|
||||||
* will be decoded before being written into the stream.
|
* will be decoded before being written into the stream.
|
||||||
@ -74,7 +77,10 @@ public:
|
|||||||
* @param progress progress listener, or NULL if you do not
|
* @param progress progress listener, or NULL if you do not
|
||||||
* want to receive progress notifications
|
* want to receive progress notifications
|
||||||
*/
|
*/
|
||||||
virtual void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0;
|
virtual void extract(
|
||||||
|
utility::outputStream& os,
|
||||||
|
utility::progressListener* progress = NULL
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
/** Extract the contents into the specified stream, without
|
/** Extract the contents into the specified stream, without
|
||||||
* decoding it. It may be useful in case the encoding is not
|
* decoding it. It may be useful in case the encoding is not
|
||||||
@ -84,7 +90,10 @@ public:
|
|||||||
* @param progress progress listener, or NULL if you do not
|
* @param progress progress listener, or NULL if you do not
|
||||||
* want to receive progress notifications
|
* want to receive progress notifications
|
||||||
*/
|
*/
|
||||||
virtual void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0;
|
virtual void extractRaw(
|
||||||
|
utility::outputStream& os,
|
||||||
|
utility::progressListener* progress = NULL
|
||||||
|
) const = 0;
|
||||||
|
|
||||||
/** Returns the actual length of data. WARNING: this can return 0 if no
|
/** Returns the actual length of data. WARNING: this can return 0 if no
|
||||||
* length was specified when setting data of this object, or if the
|
* length was specified when setting data of this object, or if the
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -25,89 +25,90 @@
|
|||||||
#include "vmime/exception.hpp"
|
#include "vmime/exception.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
contentTypeField::contentTypeField()
|
contentTypeField::contentTypeField() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentTypeField::contentTypeField(contentTypeField&)
|
contentTypeField::contentTypeField(contentTypeField&)
|
||||||
: parameterizedHeaderField()
|
: parameterizedHeaderField() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentTypeField::hasBoundary() const
|
bool contentTypeField::hasBoundary() const {
|
||||||
{
|
|
||||||
return hasParameter("boundary");
|
return hasParameter("boundary");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentTypeField::getBoundary() const
|
const string contentTypeField::getBoundary() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("boundary");
|
shared_ptr <parameter> param = findParameter("boundary");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValue().getBuffer();
|
return param->getValue().getBuffer();
|
||||||
else
|
} else {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentTypeField::setBoundary(const string& boundary)
|
void contentTypeField::setBoundary(const string& boundary) {
|
||||||
{
|
|
||||||
getParameter("boundary")->setValue(word(boundary, vmime::charsets::US_ASCII));
|
getParameter("boundary")->setValue(word(boundary, vmime::charsets::US_ASCII));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentTypeField::hasCharset() const
|
bool contentTypeField::hasCharset() const {
|
||||||
{
|
|
||||||
return hasParameter("charset");
|
return hasParameter("charset");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const charset contentTypeField::getCharset() const
|
const charset contentTypeField::getCharset() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("charset");
|
shared_ptr <parameter> param = findParameter("charset");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValueAs <charset>();
|
return param->getValueAs <charset>();
|
||||||
else
|
} else {
|
||||||
return charset();
|
return charset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentTypeField::setCharset(const charset& ch)
|
void contentTypeField::setCharset(const charset& ch) {
|
||||||
{
|
|
||||||
getParameter("charset")->setValue(ch);
|
getParameter("charset")->setValue(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool contentTypeField::hasReportType() const
|
bool contentTypeField::hasReportType() const {
|
||||||
{
|
|
||||||
return hasParameter("report-type");
|
return hasParameter("report-type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentTypeField::getReportType() const
|
const string contentTypeField::getReportType() const {
|
||||||
{
|
|
||||||
shared_ptr <parameter> param = findParameter("report-type");
|
shared_ptr <parameter> param = findParameter("report-type");
|
||||||
|
|
||||||
if (param)
|
if (param) {
|
||||||
return param->getValue().getBuffer();
|
return param->getValue().getBuffer();
|
||||||
else
|
} else {
|
||||||
return "";
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentTypeField::setReportType(const string& reportType)
|
void contentTypeField::setReportType(const string& reportType) {
|
||||||
{
|
|
||||||
getParameter("report-type")->setValue(word(reportType, vmime::charsets::US_ASCII));
|
getParameter("report-type")->setValue(word(reportType, vmime::charsets::US_ASCII));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -31,12 +31,11 @@
|
|||||||
#include "vmime/charset.hpp"
|
#include "vmime/charset.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class VMIME_EXPORT contentTypeField : public parameterizedHeaderField
|
class VMIME_EXPORT contentTypeField : public parameterizedHeaderField {
|
||||||
{
|
|
||||||
friend class headerFieldFactory;
|
friend class headerFieldFactory;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -24,61 +24,60 @@
|
|||||||
#include "vmime/context.hpp"
|
#include "vmime/context.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
context::context()
|
context::context()
|
||||||
: m_internationalizedEmail(false)
|
: m_internationalizedEmail(false) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
context::context(const context& ctx)
|
context::context(const context& ctx)
|
||||||
: object(),
|
: object(),
|
||||||
m_internationalizedEmail(ctx.m_internationalizedEmail)
|
m_internationalizedEmail(ctx.m_internationalizedEmail) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
context::~context()
|
context::~context() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool context::getInternationalizedEmailSupport() const
|
bool context::getInternationalizedEmailSupport() const {
|
||||||
{
|
|
||||||
return m_internationalizedEmail;
|
return m_internationalizedEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void context::setInternationalizedEmailSupport(const bool support)
|
void context::setInternationalizedEmailSupport(const bool support) {
|
||||||
{
|
|
||||||
m_internationalizedEmail = support;
|
m_internationalizedEmail = support;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const charsetConverterOptions& context::getCharsetConversionOptions() const
|
const charsetConverterOptions& context::getCharsetConversionOptions() const {
|
||||||
{
|
|
||||||
return m_charsetConvOptions;
|
return m_charsetConvOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void context::setCharsetConversionOptions(const charsetConverterOptions& opts)
|
void context::setCharsetConversionOptions(const charsetConverterOptions& opts) {
|
||||||
{
|
|
||||||
m_charsetConvOptions = opts;
|
m_charsetConvOptions = opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
context& context::operator=(const context& ctx)
|
context& context::operator=(const context& ctx) {
|
||||||
{
|
|
||||||
copyFrom(ctx);
|
copyFrom(ctx);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void context::copyFrom(const context& ctx)
|
void context::copyFrom(const context& ctx) {
|
||||||
{
|
|
||||||
m_internationalizedEmail = ctx.m_internationalizedEmail;
|
m_internationalizedEmail = ctx.m_internationalizedEmail;
|
||||||
m_charsetConvOptions = ctx.m_charsetConvOptions;
|
m_charsetConvOptions = ctx.m_charsetConvOptions;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -29,15 +29,13 @@
|
|||||||
#include "vmime/charsetConverterOptions.hpp"
|
#include "vmime/charsetConverterOptions.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Holds configuration parameters used either for parsing or generating messages.
|
/** Holds configuration parameters used either for parsing or generating messages.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT context : public object {
|
||||||
|
|
||||||
class VMIME_EXPORT context : public object
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~context();
|
virtual ~context();
|
||||||
@ -74,8 +72,8 @@ public:
|
|||||||
/** Switches between contexts temporarily.
|
/** Switches between contexts temporarily.
|
||||||
*/
|
*/
|
||||||
template <typename CTX_CLASS>
|
template <typename CTX_CLASS>
|
||||||
class switcher
|
class switcher {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Switches to the specified context.
|
/** Switches to the specified context.
|
||||||
@ -85,15 +83,15 @@ public:
|
|||||||
* @param newCtx new context
|
* @param newCtx new context
|
||||||
*/
|
*/
|
||||||
switcher(CTX_CLASS& newCtx)
|
switcher(CTX_CLASS& newCtx)
|
||||||
: m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx)
|
: m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx) {
|
||||||
{
|
|
||||||
CTX_CLASS::getDefaultContext().copyFrom(newCtx);
|
CTX_CLASS::getDefaultContext().copyFrom(newCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Restores back saved context.
|
/** Restores back saved context.
|
||||||
*/
|
*/
|
||||||
~switcher()
|
~switcher() {
|
||||||
{
|
|
||||||
CTX_CLASS::getDefaultContext().copyFrom(m_oldCtxData);
|
CTX_CLASS::getDefaultContext().copyFrom(m_oldCtxData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -31,21 +31,31 @@
|
|||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Date and time (basic type).
|
/** Date and time (basic type).
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT datetime : public headerFieldValue {
|
||||||
|
|
||||||
class VMIME_EXPORT datetime : public headerFieldValue
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
datetime();
|
datetime();
|
||||||
datetime(const int year, const int month, const int day);
|
datetime(
|
||||||
datetime(const int year, const int month, const int day, const int hour, const int minute, const int second, const int zone = GMT);
|
const int year,
|
||||||
|
const int month,
|
||||||
|
const int day
|
||||||
|
);
|
||||||
|
datetime(
|
||||||
|
const int year,
|
||||||
|
const int month,
|
||||||
|
const int day,
|
||||||
|
const int hour,
|
||||||
|
const int minute,
|
||||||
|
const int second,
|
||||||
|
const int zone = GMT
|
||||||
|
);
|
||||||
datetime(const datetime& d);
|
datetime(const datetime& d);
|
||||||
datetime(const string& date);
|
datetime(const string& date);
|
||||||
datetime(const time_t t, const int zone = GMT);
|
datetime(const time_t t, const int zone = GMT);
|
||||||
@ -54,8 +64,8 @@ public:
|
|||||||
~datetime();
|
~datetime();
|
||||||
|
|
||||||
// Some time zones (in minutes)
|
// Some time zones (in minutes)
|
||||||
enum TimeZones
|
enum TimeZones {
|
||||||
{
|
|
||||||
GMT_12 = -720, // GMT-12h
|
GMT_12 = -720, // GMT-12h
|
||||||
GMT_11 = -660, // GMT-11h
|
GMT_11 = -660, // GMT-11h
|
||||||
GMT_10 = -600, // GMT-10h
|
GMT_10 = -600, // GMT-10h
|
||||||
@ -124,8 +134,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Months list
|
// Months list
|
||||||
enum Months
|
enum Months {
|
||||||
{
|
|
||||||
// Long
|
// Long
|
||||||
JANUARY = 1,
|
JANUARY = 1,
|
||||||
FEBRUARY = 2,
|
FEBRUARY = 2,
|
||||||
@ -155,8 +165,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Days of week list
|
// Days of week list
|
||||||
enum DaysOfWeek
|
enum DaysOfWeek {
|
||||||
{
|
|
||||||
// Long
|
// Long
|
||||||
SUNDAY = 0,
|
SUNDAY = 0,
|
||||||
MONDAY = 1,
|
MONDAY = 1,
|
||||||
@ -242,18 +252,20 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parseImpl
|
void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -28,57 +28,75 @@
|
|||||||
#include "vmime/encoding.hpp"
|
#include "vmime/encoding.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
defaultAttachment::defaultAttachment()
|
defaultAttachment::defaultAttachment() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defaultAttachment::defaultAttachment(shared_ptr <const contentHandler> data,
|
defaultAttachment::defaultAttachment(
|
||||||
const encoding& enc, const mediaType& type, const text& desc, const word& name)
|
const shared_ptr <const contentHandler>& data,
|
||||||
: m_type(type), m_desc(desc), m_data(data), m_encoding(enc), m_name(name)
|
const encoding& enc,
|
||||||
{
|
const mediaType& type,
|
||||||
|
const text& desc,
|
||||||
|
const word& name
|
||||||
|
)
|
||||||
|
: m_type(type),
|
||||||
|
m_desc(desc),
|
||||||
|
m_data(data),
|
||||||
|
m_encoding(enc),
|
||||||
|
m_name(name) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defaultAttachment::defaultAttachment(shared_ptr <const contentHandler> data,
|
defaultAttachment::defaultAttachment(
|
||||||
const mediaType& type, const text& desc, const word& name)
|
const shared_ptr <const contentHandler>& data,
|
||||||
: m_type(type), m_desc(desc), m_data(data),
|
const mediaType& type,
|
||||||
m_encoding(encoding::decide(data)), m_name(name)
|
const text& desc,
|
||||||
{
|
const word& name
|
||||||
|
)
|
||||||
|
: m_type(type),
|
||||||
|
m_desc(desc),
|
||||||
|
m_data(data),
|
||||||
|
m_encoding(encoding::decide(data)),
|
||||||
|
m_name(name) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defaultAttachment::defaultAttachment(const defaultAttachment& attach)
|
defaultAttachment::defaultAttachment(const defaultAttachment& attach)
|
||||||
: attachment(), m_type(attach.m_type), m_desc(attach.m_desc),
|
: attachment(),
|
||||||
|
m_type(attach.m_type),
|
||||||
|
m_desc(attach.m_desc),
|
||||||
m_data(vmime::clone(attach.m_data)),
|
m_data(vmime::clone(attach.m_data)),
|
||||||
m_encoding(attach.m_encoding), m_name(attach.m_name)
|
m_encoding(attach.m_encoding),
|
||||||
{
|
m_name(attach.m_name) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defaultAttachment::~defaultAttachment()
|
defaultAttachment::~defaultAttachment() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach)
|
defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach) {
|
||||||
{
|
|
||||||
m_type = attach.m_type;
|
m_type = attach.m_type;
|
||||||
m_desc = attach.m_desc;
|
m_desc = attach.m_desc;
|
||||||
m_name = attach.m_name;
|
m_name = attach.m_name;
|
||||||
m_data = vmime::clone(attach.m_data);
|
m_data = vmime::clone(attach.m_data);
|
||||||
m_encoding = attach.m_encoding;
|
m_encoding = attach.m_encoding;
|
||||||
|
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void defaultAttachment::generateIn(shared_ptr <bodyPart> parent) const
|
void defaultAttachment::generateIn(const shared_ptr <bodyPart>& parent) const {
|
||||||
{
|
|
||||||
// Create and append a new part for this attachment
|
// Create and append a new part for this attachment
|
||||||
shared_ptr <bodyPart> part = make_shared <bodyPart>();
|
shared_ptr <bodyPart> part = make_shared <bodyPart>();
|
||||||
parent->getBody()->appendPart(part);
|
parent->getBody()->appendPart(part);
|
||||||
@ -87,8 +105,8 @@ void defaultAttachment::generateIn(shared_ptr <bodyPart> parent) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void defaultAttachment::generatePart(shared_ptr <bodyPart> part) const
|
void defaultAttachment::generatePart(const shared_ptr <bodyPart>& part) const {
|
||||||
{
|
|
||||||
// Set header fields
|
// Set header fields
|
||||||
part->getHeader()->ContentType()->setValue(m_type);
|
part->getHeader()->ContentType()->setValue(m_type);
|
||||||
if (!m_desc.isEmpty()) part->getHeader()->ContentDescription()->setValue(m_desc);
|
if (!m_desc.isEmpty()) part->getHeader()->ContentDescription()->setValue(m_desc);
|
||||||
@ -101,44 +119,44 @@ void defaultAttachment::generatePart(shared_ptr <bodyPart> part) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const mediaType defaultAttachment::getType() const
|
const mediaType defaultAttachment::getType() const {
|
||||||
{
|
|
||||||
return m_type;
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const text defaultAttachment::getDescription() const
|
const text defaultAttachment::getDescription() const {
|
||||||
{
|
|
||||||
return m_desc;
|
return m_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const word defaultAttachment::getName() const
|
const word defaultAttachment::getName() const {
|
||||||
{
|
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const shared_ptr <const contentHandler> defaultAttachment::getData() const
|
const shared_ptr <const contentHandler> defaultAttachment::getData() const {
|
||||||
{
|
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const encoding defaultAttachment::getEncoding() const
|
const encoding defaultAttachment::getEncoding() const {
|
||||||
{
|
|
||||||
return m_encoding;
|
return m_encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <const object> defaultAttachment::getPart() const
|
shared_ptr <const object> defaultAttachment::getPart() const {
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <const header> defaultAttachment::getHeader() const
|
shared_ptr <const header> defaultAttachment::getHeader() const {
|
||||||
{
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -29,15 +29,13 @@
|
|||||||
#include "vmime/encoding.hpp"
|
#include "vmime/encoding.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Default implementation for attachments.
|
/** Default implementation for attachments.
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT defaultAttachment : public attachment {
|
||||||
|
|
||||||
class VMIME_EXPORT defaultAttachment : public attachment
|
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// For use in derived classes.
|
// For use in derived classes.
|
||||||
@ -45,8 +43,21 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
defaultAttachment(shared_ptr <const contentHandler> data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD);
|
defaultAttachment(
|
||||||
defaultAttachment(shared_ptr <const contentHandler> data, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD);
|
const shared_ptr <const contentHandler>& data,
|
||||||
|
const encoding& enc,
|
||||||
|
const mediaType& type,
|
||||||
|
const text& desc = NULL_TEXT,
|
||||||
|
const word& name = NULL_WORD
|
||||||
|
);
|
||||||
|
|
||||||
|
defaultAttachment(
|
||||||
|
const shared_ptr <const contentHandler>& data,
|
||||||
|
const mediaType& type,
|
||||||
|
const text& desc = NULL_TEXT,
|
||||||
|
const word& name = NULL_WORD
|
||||||
|
);
|
||||||
|
|
||||||
defaultAttachment(const defaultAttachment& attach);
|
defaultAttachment(const defaultAttachment& attach);
|
||||||
|
|
||||||
~defaultAttachment();
|
~defaultAttachment();
|
||||||
@ -74,11 +85,11 @@ protected:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
// No need to override "generateIn", use "generatePart" instead (see below).
|
// No need to override "generateIn", use "generatePart" instead (see below).
|
||||||
void generateIn(shared_ptr <bodyPart> parent) const;
|
void generateIn(const shared_ptr <bodyPart>& parent) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void generatePart(shared_ptr <bodyPart> part) const;
|
virtual void generatePart(const shared_ptr <bodyPart>& part) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -27,25 +27,30 @@
|
|||||||
#include "vmime/utility/stringUtils.hpp"
|
#include "vmime/utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
disposition::disposition()
|
disposition::disposition() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
disposition::disposition(const string& actionMode, const string& sendingMode,
|
disposition::disposition(
|
||||||
const string& type, const string& modifier)
|
const string& actionMode,
|
||||||
: m_actionMode(actionMode), m_sendingMode(sendingMode), m_type(type)
|
const string& sendingMode,
|
||||||
{
|
const string& type,
|
||||||
|
const string& modifier
|
||||||
|
)
|
||||||
|
: m_actionMode(actionMode),
|
||||||
|
m_sendingMode(sendingMode),
|
||||||
|
m_type(type) {
|
||||||
|
|
||||||
m_modifiers.push_back(modifier);
|
m_modifiers.push_back(modifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component> disposition::clone() const
|
shared_ptr <component> disposition::clone() const {
|
||||||
{
|
|
||||||
shared_ptr <disposition> disp = make_shared <disposition>();
|
shared_ptr <disposition> disp = make_shared <disposition>();
|
||||||
|
|
||||||
disp->m_actionMode = m_actionMode;
|
disp->m_actionMode = m_actionMode;
|
||||||
@ -55,12 +60,12 @@ shared_ptr <component> disposition::clone() const
|
|||||||
|
|
||||||
std::copy(m_modifiers.begin(), m_modifiers.end(), disp->m_modifiers.begin());
|
std::copy(m_modifiers.begin(), m_modifiers.end(), disp->m_modifiers.begin());
|
||||||
|
|
||||||
return (disp);
|
return disp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::copyFrom(const component& other)
|
void disposition::copyFrom(const component& other) {
|
||||||
{
|
|
||||||
const disposition& disp = dynamic_cast <const disposition&>(other);
|
const disposition& disp = dynamic_cast <const disposition&>(other);
|
||||||
|
|
||||||
m_actionMode = disp.m_actionMode;
|
m_actionMode = disp.m_actionMode;
|
||||||
@ -72,71 +77,71 @@ void disposition::copyFrom(const component& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
disposition& disposition::operator=(const disposition& other)
|
disposition& disposition::operator=(const disposition& other) {
|
||||||
{
|
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <component> > disposition::getChildComponents()
|
const std::vector <shared_ptr <component> > disposition::getChildComponents() {
|
||||||
{
|
|
||||||
return std::vector <shared_ptr <component> >();
|
return std::vector <shared_ptr <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::setActionMode(const string& mode)
|
void disposition::setActionMode(const string& mode) {
|
||||||
{
|
|
||||||
m_actionMode = mode;
|
m_actionMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string& disposition::getActionMode() const
|
const string& disposition::getActionMode() const {
|
||||||
{
|
|
||||||
return (m_actionMode);
|
return m_actionMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::setSendingMode(const string& mode)
|
void disposition::setSendingMode(const string& mode) {
|
||||||
{
|
|
||||||
m_sendingMode = mode;
|
m_sendingMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string& disposition::getSendingMode() const
|
const string& disposition::getSendingMode() const {
|
||||||
{
|
|
||||||
return (m_sendingMode);
|
return m_sendingMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::setType(const string& type)
|
void disposition::setType(const string& type) {
|
||||||
{
|
|
||||||
m_type = type;
|
m_type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string& disposition::getType() const
|
const string& disposition::getType() const {
|
||||||
{
|
|
||||||
return (m_type);
|
return m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::addModifier(const string& modifier)
|
void disposition::addModifier(const string& modifier) {
|
||||||
{
|
|
||||||
if (!hasModifier(modifier))
|
if (!hasModifier(modifier)) {
|
||||||
m_modifiers.push_back(utility::stringUtils::toLower(modifier));
|
m_modifiers.push_back(utility::stringUtils::toLower(modifier));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::removeModifier(const string& modifier)
|
void disposition::removeModifier(const string& modifier) {
|
||||||
{
|
|
||||||
const string modifierLC = utility::stringUtils::toLower(modifier);
|
const string modifierLC = utility::stringUtils::toLower(modifier);
|
||||||
|
|
||||||
for (std::vector <string>::iterator it = m_modifiers.begin() ;
|
for (std::vector <string>::iterator it = m_modifiers.begin() ;
|
||||||
it != m_modifiers.end() ; ++it)
|
it != m_modifiers.end() ; ++it) {
|
||||||
{
|
|
||||||
if (*it == modifierLC)
|
if (*it == modifierLC) {
|
||||||
{
|
|
||||||
m_modifiers.erase(it);
|
m_modifiers.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -144,37 +149,42 @@ void disposition::removeModifier(const string& modifier)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::removeAllModifiers()
|
void disposition::removeAllModifiers() {
|
||||||
{
|
|
||||||
m_modifiers.clear();
|
m_modifiers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool disposition::hasModifier(const string& modifier) const
|
bool disposition::hasModifier(const string& modifier) const {
|
||||||
{
|
|
||||||
const string modifierLC = utility::stringUtils::toLower(modifier);
|
const string modifierLC = utility::stringUtils::toLower(modifier);
|
||||||
|
|
||||||
for (std::vector <string>::const_iterator it = m_modifiers.begin() ;
|
for (std::vector <string>::const_iterator it = m_modifiers.begin() ;
|
||||||
it != m_modifiers.end() ; ++it)
|
it != m_modifiers.end() ; ++it) {
|
||||||
{
|
|
||||||
if (*it == modifierLC)
|
if (*it == modifierLC) {
|
||||||
return (true);
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <string> disposition::getModifierList() const
|
const std::vector <string> disposition::getModifierList() const {
|
||||||
{
|
|
||||||
return (m_modifiers);
|
return m_modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::parseImpl
|
void disposition::parseImpl(
|
||||||
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
|
const parsingContext& /* ctx */,
|
||||||
const size_t end, size_t* newPosition)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
// disposition-mode ";" disposition-type
|
// disposition-mode ";" disposition-type
|
||||||
// [ "/" disposition-modifier *( "," disposition-modifier ) ]
|
// [ "/" disposition-modifier *( "," disposition-modifier ) ]
|
||||||
//
|
//
|
||||||
@ -182,105 +192,116 @@ void disposition::parseImpl
|
|||||||
|
|
||||||
size_t pos = position;
|
size_t pos = position;
|
||||||
|
|
||||||
while (pos < end && parserHelpers::isSpace(buffer[pos]))
|
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
|
||||||
++pos;
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
// -- disposition-mode
|
// -- disposition-mode
|
||||||
const size_t modeStart = pos;
|
const size_t modeStart = pos;
|
||||||
size_t modeEnd = pos;
|
size_t modeEnd = pos;
|
||||||
|
|
||||||
while (pos < end && buffer[pos] != ';')
|
while (pos < end && buffer[pos] != ';') {
|
||||||
{
|
|
||||||
++modeEnd;
|
++modeEnd;
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1]))
|
while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1])) {
|
||||||
--modeEnd;
|
--modeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
const string mode = string(buffer.begin() + modeStart, buffer.begin() + modeEnd);
|
const string mode = string(buffer.begin() + modeStart, buffer.begin() + modeEnd);
|
||||||
const size_t slash = mode.find('/');
|
const size_t slash = mode.find('/');
|
||||||
|
|
||||||
if (slash != string::npos)
|
if (slash != string::npos) {
|
||||||
{
|
|
||||||
m_actionMode = string(mode.begin(), mode.begin() + slash);
|
m_actionMode = string(mode.begin(), mode.begin() + slash);
|
||||||
m_sendingMode = string(mode.begin() + slash + 1, mode.end());
|
m_sendingMode = string(mode.begin() + slash + 1, mode.end());
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
m_actionMode = mode;
|
m_actionMode = mode;
|
||||||
m_sendingMode.clear();
|
m_sendingMode.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos < end)
|
if (pos < end) {
|
||||||
{
|
|
||||||
// Skip ';'
|
// Skip ';'
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (pos < end && parserHelpers::isSpace(buffer[pos]))
|
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
|
||||||
++pos;
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
// -- disposition-type
|
// -- disposition-type
|
||||||
const size_t typeStart = pos;
|
const size_t typeStart = pos;
|
||||||
size_t typeEnd = pos;
|
size_t typeEnd = pos;
|
||||||
|
|
||||||
while (pos < end && buffer[pos] != '/')
|
while (pos < end && buffer[pos] != '/') {
|
||||||
{
|
|
||||||
++typeEnd;
|
++typeEnd;
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1]))
|
while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1])) {
|
||||||
--typeEnd;
|
--typeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
m_type = string(buffer.begin() + typeStart, buffer.begin() + typeEnd);
|
m_type = string(buffer.begin() + typeStart, buffer.begin() + typeEnd);
|
||||||
|
|
||||||
m_modifiers.clear();
|
m_modifiers.clear();
|
||||||
|
|
||||||
if (pos < end) // modifiers follow
|
if (pos < end) { // modifiers follow
|
||||||
{
|
|
||||||
// Skip '/'
|
// Skip '/'
|
||||||
++pos;
|
++pos;
|
||||||
|
|
||||||
while (pos < end)
|
while (pos < end) {
|
||||||
{
|
|
||||||
while (pos < end && parserHelpers::isSpace(buffer[pos]))
|
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
|
||||||
++pos;
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t modifierStart = pos;
|
const size_t modifierStart = pos;
|
||||||
size_t modifierEnd = pos;
|
size_t modifierEnd = pos;
|
||||||
|
|
||||||
while (pos < end && buffer[pos] != ',')
|
while (pos < end && buffer[pos] != ',') {
|
||||||
{
|
|
||||||
++modifierEnd;
|
++modifierEnd;
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1]))
|
while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1])) {
|
||||||
--modifierEnd;
|
--modifierEnd;
|
||||||
|
}
|
||||||
|
|
||||||
if (modifierEnd > modifierStart)
|
if (modifierEnd > modifierStart) {
|
||||||
{
|
|
||||||
m_modifiers.push_back(string(buffer.begin() + modifierStart,
|
m_modifiers.push_back(
|
||||||
buffer.begin() + modifierEnd));
|
string(
|
||||||
|
buffer.begin() + modifierStart,
|
||||||
|
buffer.begin() + modifierEnd
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip ','
|
// Skip ','
|
||||||
if (pos < end)
|
if (pos < end) {
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
*newPosition = pos;
|
*newPosition = pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void disposition::generateImpl
|
void disposition::generateImpl(
|
||||||
(const generationContext& ctx, utility::outputStream& os,
|
const generationContext& ctx,
|
||||||
const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t curLinePos,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
size_t pos = curLinePos;
|
size_t pos = curLinePos;
|
||||||
|
|
||||||
const string actionMode = (m_actionMode.empty() ? "automatic-action" : m_actionMode);
|
const string actionMode = (m_actionMode.empty() ? "automatic-action" : m_actionMode);
|
||||||
@ -289,8 +310,7 @@ void disposition::generateImpl
|
|||||||
os << actionMode << "/" << sendingMode << ";";
|
os << actionMode << "/" << sendingMode << ";";
|
||||||
pos += actionMode.length() + 1 + sendingMode.length() + 1;
|
pos += actionMode.length() + 1 + sendingMode.length() + 1;
|
||||||
|
|
||||||
if (pos > ctx.getMaxLineLength())
|
if (pos > ctx.getMaxLineLength()) {
|
||||||
{
|
|
||||||
os << NEW_LINE_SEQUENCE;
|
os << NEW_LINE_SEQUENCE;
|
||||||
pos = NEW_LINE_SEQUENCE_LENGTH;
|
pos = NEW_LINE_SEQUENCE_LENGTH;
|
||||||
}
|
}
|
||||||
@ -300,18 +320,19 @@ void disposition::generateImpl
|
|||||||
os << type;
|
os << type;
|
||||||
pos += type.length();
|
pos += type.length();
|
||||||
|
|
||||||
if (m_modifiers.size() >= 1)
|
if (m_modifiers.size() >= 1) {
|
||||||
{
|
|
||||||
for (std::vector <string>::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i)
|
for (std::vector <string>::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i) {
|
||||||
{
|
|
||||||
const string mod = utility::stringUtils::trim(m_modifiers[i]);
|
const string mod = utility::stringUtils::trim(m_modifiers[i]);
|
||||||
|
|
||||||
if (!mod.empty())
|
if (!mod.empty()) {
|
||||||
{
|
|
||||||
if (n == 0)
|
if (n == 0) {
|
||||||
os << "/";
|
os << "/";
|
||||||
else
|
} else {
|
||||||
os << ",";
|
os << ",";
|
||||||
|
}
|
||||||
|
|
||||||
os << mod;
|
os << mod;
|
||||||
pos += 1 + mod.length();
|
pos += 1 + mod.length();
|
||||||
@ -321,8 +342,9 @@ void disposition::generateImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newLinePos)
|
if (newLinePos) {
|
||||||
*newLinePos = pos;
|
*newLinePos = pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -31,19 +31,22 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Disposition - from RFC-3798 (basic type).
|
/** Disposition - from RFC-3798 (basic type).
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT disposition : public headerFieldValue {
|
||||||
|
|
||||||
class VMIME_EXPORT disposition : public headerFieldValue
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
disposition();
|
disposition();
|
||||||
disposition(const string& actionMode, const string& sendingMode, const string& type, const string& modifier);
|
disposition(
|
||||||
|
const string& actionMode,
|
||||||
|
const string& sendingMode,
|
||||||
|
const string& type,
|
||||||
|
const string& modifier
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component> clone() const;
|
shared_ptr <component> clone() const;
|
||||||
@ -137,18 +140,20 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parseImpl
|
void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -156,4 +161,3 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
#endif // VMIME_DISPOSITION_HPP_INCLUDED
|
#endif // VMIME_DISPOSITION_HPP_INCLUDED
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -31,8 +31,7 @@
|
|||||||
#include "vmime/utility/stringUtils.hpp"
|
#include "vmime/utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** Decode an IDNA-encoded domain name ("xn--5rtw95l.xn--wgv71a")
|
/** Decode an IDNA-encoded domain name ("xn--5rtw95l.xn--wgv71a")
|
||||||
@ -41,48 +40,52 @@ namespace vmime
|
|||||||
* @param idnaDomain domain name encoded with IDNA
|
* @param idnaDomain domain name encoded with IDNA
|
||||||
* @return decoded domain name in UTF-8
|
* @return decoded domain name in UTF-8
|
||||||
*/
|
*/
|
||||||
static const string domainNameFromIDNA(const string& idnaDomain)
|
static const string domainNameFromIDNA(const string& idnaDomain) {
|
||||||
{
|
|
||||||
std::ostringstream domainName;
|
std::ostringstream domainName;
|
||||||
size_t p = 0;
|
size_t p = 0;
|
||||||
|
|
||||||
for (size_t n = idnaDomain.find('.', p) ;
|
for (size_t n = idnaDomain.find('.', p) ;
|
||||||
(n = idnaDomain.find('.', p)) != string::npos ; p = n + 1)
|
(n = idnaDomain.find('.', p)) != string::npos ; p = n + 1) {
|
||||||
{
|
|
||||||
const string encodedPart(idnaDomain.begin() + p, idnaDomain.begin() + n);
|
const string encodedPart(idnaDomain.begin() + p, idnaDomain.begin() + n);
|
||||||
|
|
||||||
if (encodedPart.length() > 4 &&
|
if (encodedPart.length() > 4 &&
|
||||||
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
|
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
|
||||||
encodedPart[2] == '-' && encodedPart[3] == '-')
|
encodedPart[2] == '-' && encodedPart[3] == '-') {
|
||||||
{
|
|
||||||
string decodedPart;
|
string decodedPart;
|
||||||
charset::convert(encodedPart, decodedPart,
|
charset::convert(
|
||||||
vmime::charsets::IDNA, vmime::charsets::UTF_8);
|
encodedPart, decodedPart,
|
||||||
|
vmime::charsets::IDNA, vmime::charsets::UTF_8
|
||||||
|
);
|
||||||
|
|
||||||
domainName << decodedPart << '.';
|
domainName << decodedPart << '.';
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
domainName << encodedPart << '.'; // not encoded
|
domainName << encodedPart << '.'; // not encoded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p < idnaDomain.length())
|
if (p < idnaDomain.length()) {
|
||||||
{
|
|
||||||
const string encodedPart(idnaDomain.begin() + p, idnaDomain.end());
|
const string encodedPart(idnaDomain.begin() + p, idnaDomain.end());
|
||||||
|
|
||||||
if (encodedPart.length() > 4 &&
|
if (encodedPart.length() > 4 &&
|
||||||
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
|
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
|
||||||
encodedPart[2] == '-' && encodedPart[3] == '-')
|
encodedPart[2] == '-' && encodedPart[3] == '-') {
|
||||||
{
|
|
||||||
string decodedPart;
|
string decodedPart;
|
||||||
charset::convert(encodedPart, decodedPart,
|
charset::convert(
|
||||||
vmime::charsets::IDNA, vmime::charsets::UTF_8);
|
encodedPart, decodedPart,
|
||||||
|
vmime::charsets::IDNA, vmime::charsets::UTF_8
|
||||||
|
);
|
||||||
|
|
||||||
domainName << decodedPart;
|
domainName << decodedPart;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
domainName << encodedPart; // not encoded
|
domainName << encodedPart; // not encoded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,26 +100,30 @@ static const string domainNameFromIDNA(const string& idnaDomain)
|
|||||||
* @param domainName domain name in UTF-8
|
* @param domainName domain name in UTF-8
|
||||||
* @return domain name encoded with IDNA
|
* @return domain name encoded with IDNA
|
||||||
*/
|
*/
|
||||||
static const string domainNameToIDNA(const string& domainName)
|
static const string domainNameToIDNA(const string& domainName) {
|
||||||
{
|
|
||||||
std::ostringstream idnaDomain;
|
std::ostringstream idnaDomain;
|
||||||
size_t p = 0;
|
size_t p = 0;
|
||||||
|
|
||||||
for (size_t n = domainName.find('.', p) ;
|
for (size_t n = domainName.find('.', p) ;
|
||||||
(n = domainName.find('.', p)) != string::npos ; p = n + 1)
|
(n = domainName.find('.', p)) != string::npos ; p = n + 1) {
|
||||||
{
|
|
||||||
string idnaPart;
|
string idnaPart;
|
||||||
charset::convert(string(domainName.begin() + p, domainName.begin() + n),
|
charset::convert(
|
||||||
idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA);
|
string(domainName.begin() + p, domainName.begin() + n), idnaPart,
|
||||||
|
vmime::charsets::UTF_8, vmime::charsets::IDNA
|
||||||
|
);
|
||||||
|
|
||||||
idnaDomain << idnaPart << '.';
|
idnaDomain << idnaPart << '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p < domainName.length())
|
if (p < domainName.length()) {
|
||||||
{
|
|
||||||
string idnaPart;
|
string idnaPart;
|
||||||
charset::convert(string(domainName.begin() + p, domainName.end()),
|
charset::convert(
|
||||||
idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA);
|
string(domainName.begin() + p, domainName.end()), idnaPart,
|
||||||
|
vmime::charsets::UTF_8, vmime::charsets::IDNA
|
||||||
|
);
|
||||||
|
|
||||||
idnaDomain << idnaPart;
|
idnaDomain << idnaPart;
|
||||||
}
|
}
|
||||||
@ -127,52 +134,60 @@ static const string domainNameToIDNA(const string& domainName)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
emailAddress::emailAddress()
|
emailAddress::emailAddress() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emailAddress::emailAddress(const emailAddress& eml)
|
emailAddress::emailAddress(const emailAddress& eml)
|
||||||
: component(), m_localName(eml.m_localName), m_domainName(eml.m_domainName)
|
: component(),
|
||||||
{
|
m_localName(eml.m_localName),
|
||||||
|
m_domainName(eml.m_domainName) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emailAddress::emailAddress(const string& email)
|
emailAddress::emailAddress(const string& email) {
|
||||||
{
|
|
||||||
parse(email);
|
parse(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emailAddress::emailAddress(const char* email)
|
emailAddress::emailAddress(const char* email) {
|
||||||
{
|
|
||||||
parse(email);
|
parse(email);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emailAddress::emailAddress(const string& localName, const string& domainName)
|
emailAddress::emailAddress(const string& localName, const string& domainName)
|
||||||
: component(), m_localName(word(localName, vmime::charsets::UTF_8)),
|
: component(),
|
||||||
m_domainName(word(domainName, vmime::charsets::UTF_8))
|
m_localName(word(localName, vmime::charsets::UTF_8)),
|
||||||
{
|
m_domainName(word(domainName, vmime::charsets::UTF_8)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emailAddress::emailAddress(const word& localName, const word& domainName)
|
emailAddress::emailAddress(const word& localName, const word& domainName)
|
||||||
: component(), m_localName(localName), m_domainName(domainName)
|
: component(),
|
||||||
{
|
m_localName(localName),
|
||||||
|
m_domainName(domainName) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emailAddress::parseImpl
|
void emailAddress::parseImpl(
|
||||||
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
|
const parsingContext& /* ctx */,
|
||||||
const size_t end, size_t* newPosition)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
const char* const pend = buffer.data() + end;
|
const char* const pend = buffer.data() + end;
|
||||||
const char* const pstart = buffer.data() + position;
|
const char* const pstart = buffer.data() + position;
|
||||||
const char* p = pstart;
|
const char* p = pstart;
|
||||||
|
|
||||||
enum ParserStates
|
enum ParserStates {
|
||||||
{
|
|
||||||
State_Before,
|
State_Before,
|
||||||
State_LocalPartStart,
|
State_LocalPartStart,
|
||||||
State_LocalPartMiddle,
|
State_LocalPartMiddle,
|
||||||
@ -199,45 +214,47 @@ void emailAddress::parseImpl
|
|||||||
int commentLevel = 0;
|
int commentLevel = 0;
|
||||||
bool localPartIsRFC2047 = false;
|
bool localPartIsRFC2047 = false;
|
||||||
|
|
||||||
while (p < pend && !stop)
|
while (p < pend && !stop) {
|
||||||
{
|
|
||||||
const char c = *p;
|
const char c = *p;
|
||||||
|
|
||||||
if ((localPart.str().length() + domainPart.str().length()) >= 256)
|
if ((localPart.str().length() + domainPart.str().length()) >= 256) {
|
||||||
{
|
|
||||||
state = State_Error;
|
state = State_Error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state)
|
switch (state) {
|
||||||
{
|
|
||||||
case State_Before:
|
case State_Before:
|
||||||
|
|
||||||
if (parserHelpers::isSpace(c))
|
if (parserHelpers::isSpace(c)) {
|
||||||
++p;
|
++p;
|
||||||
else
|
} else {
|
||||||
state = State_LocalPartStart;
|
state = State_LocalPartStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case State_LocalPartStart:
|
case State_LocalPartStart:
|
||||||
|
|
||||||
if (c == '"')
|
if (c == '"') {
|
||||||
{
|
|
||||||
state = State_LocalPartQuoted;
|
state = State_LocalPartQuoted;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '=')
|
} else if (c == '=') {
|
||||||
{
|
|
||||||
state = State_LocalPartRFC2047Start;
|
state = State_LocalPartRFC2047Start;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '(')
|
} else if (c == '(') {
|
||||||
{
|
|
||||||
state = State_LocalPartComment;
|
state = State_LocalPartComment;
|
||||||
++commentLevel;
|
++commentLevel;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
state = State_LocalPartMiddle;
|
state = State_LocalPartMiddle;
|
||||||
localPart << c;
|
localPart << c;
|
||||||
++p;
|
++p;
|
||||||
@ -247,33 +264,32 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_LocalPartComment:
|
case State_LocalPartComment:
|
||||||
|
|
||||||
if (escapeNext)
|
if (escapeNext) {
|
||||||
{
|
|
||||||
escapeNext = false;
|
escapeNext = false;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '\\')
|
} else if (c == '\\') {
|
||||||
{
|
|
||||||
escapeNext = true;
|
escapeNext = true;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '(')
|
} else if (c == '(') {
|
||||||
{
|
|
||||||
++commentLevel;
|
++commentLevel;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == ')')
|
} else if (c == ')') {
|
||||||
{
|
|
||||||
if (--commentLevel == 0)
|
if (--commentLevel == 0) {
|
||||||
{
|
|
||||||
// End of comment
|
// End of comment
|
||||||
state = State_LocalPartMiddle;
|
state = State_LocalPartMiddle;
|
||||||
}
|
}
|
||||||
|
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Comment continues
|
// Comment continues
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@ -282,34 +298,34 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_LocalPartQuoted:
|
case State_LocalPartQuoted:
|
||||||
|
|
||||||
if (escapeNext)
|
if (escapeNext) {
|
||||||
{
|
|
||||||
escapeNext = false;
|
escapeNext = false;
|
||||||
|
|
||||||
if (c == '"' || c == '\\')
|
if (c == '"' || c == '\\') {
|
||||||
{
|
|
||||||
localPart << c;
|
localPart << c;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// This char cannot be escaped
|
// This char cannot be escaped
|
||||||
state = State_Error;
|
state = State_Error;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (c == '"')
|
} else if (c == '"') {
|
||||||
{
|
|
||||||
// End of quoted string
|
// End of quoted string
|
||||||
state = State_LocalPartMiddle;
|
state = State_LocalPartMiddle;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '\\')
|
} else if (c == '\\') {
|
||||||
{
|
|
||||||
escapeNext = true;
|
escapeNext = true;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
localPart << c;
|
localPart << c;
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@ -318,15 +334,15 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_LocalPartRFC2047Start:
|
case State_LocalPartRFC2047Start:
|
||||||
|
|
||||||
if (c == '?')
|
if (c == '?') {
|
||||||
{
|
|
||||||
state = State_LocalPartRFC2047Middle;
|
state = State_LocalPartRFC2047Middle;
|
||||||
localPart << "=?";
|
localPart << "=?";
|
||||||
localPartIsRFC2047 = true;
|
localPartIsRFC2047 = true;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
state = State_LocalPartMiddle;
|
state = State_LocalPartMiddle;
|
||||||
localPart << '=';
|
localPart << '=';
|
||||||
localPart << c;
|
localPart << c;
|
||||||
@ -337,39 +353,39 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_LocalPartMiddle:
|
case State_LocalPartMiddle:
|
||||||
|
|
||||||
if (c == '.')
|
if (c == '.') {
|
||||||
{
|
|
||||||
prevIsDot = true;
|
prevIsDot = true;
|
||||||
localPart << c;
|
localPart << c;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '"' && prevIsDot)
|
} else if (c == '"' && prevIsDot) {
|
||||||
{
|
|
||||||
prevIsDot = false;
|
prevIsDot = false;
|
||||||
state = State_LocalPartQuoted;
|
state = State_LocalPartQuoted;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '(')
|
} else if (c == '(') {
|
||||||
{
|
|
||||||
// By allowing comments anywhere in the local part,
|
// By allowing comments anywhere in the local part,
|
||||||
// we are more permissive than RFC-2822
|
// we are more permissive than RFC-2822
|
||||||
state = State_LocalPartComment;
|
state = State_LocalPartComment;
|
||||||
++commentLevel;
|
++commentLevel;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '@')
|
} else if (c == '@') {
|
||||||
{
|
|
||||||
atFound = true;
|
atFound = true;
|
||||||
state = State_DomainPartStart;
|
state = State_DomainPartStart;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (parserHelpers::isSpace(c))
|
} else if (parserHelpers::isSpace(c)) {
|
||||||
{
|
|
||||||
// Allow not specifying domain part
|
// Allow not specifying domain part
|
||||||
state = State_End;
|
state = State_End;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
prevIsDot = false;
|
prevIsDot = false;
|
||||||
localPart << c;
|
localPart << c;
|
||||||
++p;
|
++p;
|
||||||
@ -379,13 +395,13 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_LocalPartRFC2047Middle:
|
case State_LocalPartRFC2047Middle:
|
||||||
|
|
||||||
if (c == '?')
|
if (c == '?') {
|
||||||
{
|
|
||||||
state = State_LocalPartRFC2047MiddleQM;
|
state = State_LocalPartRFC2047MiddleQM;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
localPart << c;
|
localPart << c;
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@ -394,15 +410,15 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_LocalPartRFC2047MiddleQM:
|
case State_LocalPartRFC2047MiddleQM:
|
||||||
|
|
||||||
if (c == '=')
|
if (c == '=') {
|
||||||
{
|
|
||||||
// End of RFC-2047 encoded word
|
// End of RFC-2047 encoded word
|
||||||
state = State_LocalPartRFC2047End;
|
state = State_LocalPartRFC2047End;
|
||||||
localPart << "?=";
|
localPart << "?=";
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
state = State_LocalPartRFC2047Middle;
|
state = State_LocalPartRFC2047Middle;
|
||||||
localPart << '?';
|
localPart << '?';
|
||||||
localPart << c;
|
localPart << c;
|
||||||
@ -413,14 +429,14 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_LocalPartRFC2047End:
|
case State_LocalPartRFC2047End:
|
||||||
|
|
||||||
if (c == '@')
|
if (c == '@') {
|
||||||
{
|
|
||||||
atFound = true;
|
atFound = true;
|
||||||
state = State_DomainPartStart;
|
state = State_DomainPartStart;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
state = State_End;
|
state = State_End;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,14 +444,14 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_DomainPartStart:
|
case State_DomainPartStart:
|
||||||
|
|
||||||
if (c == '(')
|
if (c == '(') {
|
||||||
{
|
|
||||||
state = State_DomainPartComment;
|
state = State_DomainPartComment;
|
||||||
++commentLevel;
|
++commentLevel;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
state = State_DomainPartMiddle;
|
state = State_DomainPartMiddle;
|
||||||
domainPart << c;
|
domainPart << c;
|
||||||
++p;
|
++p;
|
||||||
@ -445,20 +461,20 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_DomainPartMiddle:
|
case State_DomainPartMiddle:
|
||||||
|
|
||||||
if (parserHelpers::isSpace(c))
|
if (parserHelpers::isSpace(c)) {
|
||||||
{
|
|
||||||
state = State_End;
|
state = State_End;
|
||||||
}
|
|
||||||
else if (c == '(')
|
} else if (c == '(') {
|
||||||
{
|
|
||||||
// By allowing comments anywhere in the domain part,
|
// By allowing comments anywhere in the domain part,
|
||||||
// we are more permissive than RFC-2822
|
// we are more permissive than RFC-2822
|
||||||
state = State_DomainPartComment;
|
state = State_DomainPartComment;
|
||||||
++commentLevel;
|
++commentLevel;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
domainPart << c;
|
domainPart << c;
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@ -467,33 +483,33 @@ void emailAddress::parseImpl
|
|||||||
|
|
||||||
case State_DomainPartComment:
|
case State_DomainPartComment:
|
||||||
|
|
||||||
if (escapeNext)
|
if (escapeNext) {
|
||||||
{
|
|
||||||
escapeNext = false;
|
escapeNext = false;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '\\')
|
} else if (c == '\\') {
|
||||||
{
|
|
||||||
escapeNext = true;
|
escapeNext = true;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == '(')
|
} else if (c == '(') {
|
||||||
{
|
|
||||||
++commentLevel;
|
++commentLevel;
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else if (c == ')')
|
} else if (c == ')') {
|
||||||
{
|
|
||||||
if (--commentLevel == 0)
|
if (--commentLevel == 0) {
|
||||||
{
|
|
||||||
// End of comment
|
// End of comment
|
||||||
state = State_DomainPartMiddle;
|
state = State_DomainPartMiddle;
|
||||||
}
|
}
|
||||||
|
|
||||||
++p;
|
++p;
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Comment continues
|
// Comment continues
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
@ -508,50 +524,57 @@ void emailAddress::parseImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == pend && state != State_Error)
|
if (p == pend && state != State_Error) {
|
||||||
{
|
|
||||||
if (state == State_DomainPartMiddle)
|
if (state == State_DomainPartMiddle) {
|
||||||
state = State_End;
|
state = State_End;
|
||||||
else if (state == State_LocalPartMiddle)
|
} else if (state == State_LocalPartMiddle) {
|
||||||
state = State_End; // allow not specifying domain part
|
state = State_End; // allow not specifying domain part
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != State_End) {
|
||||||
|
|
||||||
if (state != State_End)
|
|
||||||
{
|
|
||||||
m_localName = word("invalid", vmime::charsets::UTF_8);
|
m_localName = word("invalid", vmime::charsets::UTF_8);
|
||||||
m_domainName = word("invalid", vmime::charsets::UTF_8);
|
m_domainName = word("invalid", vmime::charsets::UTF_8);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If the domain part is missing, use local host name
|
|
||||||
if (domainPart.str().empty() && !atFound)
|
|
||||||
domainPart << platform::getHandler()->getHostName();
|
|
||||||
|
|
||||||
if (localPartIsRFC2047)
|
} else {
|
||||||
|
|
||||||
|
// If the domain part is missing, use local host name
|
||||||
|
if (domainPart.str().empty() && !atFound) {
|
||||||
|
domainPart << platform::getHandler()->getHostName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localPartIsRFC2047) {
|
||||||
m_localName.parse(localPart.str());
|
m_localName.parse(localPart.str());
|
||||||
else
|
} else {
|
||||||
m_localName = word(localPart.str(), vmime::charsets::UTF_8);
|
m_localName = word(localPart.str(), vmime::charsets::UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
m_domainName = word(domainNameFromIDNA(domainPart.str()), vmime::charsets::UTF_8);
|
m_domainName = word(domainNameFromIDNA(domainPart.str()), vmime::charsets::UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
setParsedBounds(position, p - pend);
|
setParsedBounds(position, p - pend);
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
*newPosition = p - pend;
|
*newPosition = p - pend;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emailAddress::generateImpl
|
void emailAddress::generateImpl(
|
||||||
(const generationContext& ctx, utility::outputStream& os,
|
const generationContext& ctx,
|
||||||
const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t curLinePos,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
string localPart, domainPart;
|
string localPart, domainPart;
|
||||||
|
|
||||||
if (ctx.getInternationalizedEmailSupport() &&
|
if (ctx.getInternationalizedEmailSupport() &&
|
||||||
(!utility::stringUtils::is7bit(m_localName.getBuffer()) ||
|
(!utility::stringUtils::is7bit(m_localName.getBuffer()) ||
|
||||||
!utility::stringUtils::is7bit(m_domainName.getBuffer())))
|
!utility::stringUtils::is7bit(m_domainName.getBuffer()))) {
|
||||||
{
|
|
||||||
// Local part
|
// Local part
|
||||||
string localPartUTF8(m_localName.getConvertedText(vmime::charsets::UTF_8));
|
string localPartUTF8(m_localName.getConvertedText(vmime::charsets::UTF_8));
|
||||||
word localPartWord(localPartUTF8, vmime::charsets::UTF_8);
|
word localPartWord(localPartUTF8, vmime::charsets::UTF_8);
|
||||||
@ -561,9 +584,9 @@ void emailAddress::generateImpl
|
|||||||
|
|
||||||
// Domain part
|
// Domain part
|
||||||
domainPart = m_domainName.getConvertedText(vmime::charsets::UTF_8);
|
domainPart = m_domainName.getConvertedText(vmime::charsets::UTF_8);
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
// Local part
|
// Local part
|
||||||
vmime::utility::outputStreamStringAdapter os(localPart);
|
vmime::utility::outputStreamStringAdapter os(localPart);
|
||||||
m_localName.generate(ctx, os, 0, NULL, text::QUOTE_IF_NEEDED, NULL);
|
m_localName.generate(ctx, os, 0, NULL, text::QUOTE_IF_NEEDED, NULL);
|
||||||
@ -576,8 +599,8 @@ void emailAddress::generateImpl
|
|||||||
<< "@"
|
<< "@"
|
||||||
<< domainPart;
|
<< domainPart;
|
||||||
|
|
||||||
if (newLinePos)
|
if (newLinePos) {
|
||||||
{
|
|
||||||
*newLinePos = curLinePos
|
*newLinePos = curLinePos
|
||||||
+ localPart.length()
|
+ localPart.length()
|
||||||
+ 1 // @
|
+ 1 // @
|
||||||
@ -586,21 +609,21 @@ void emailAddress::generateImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool emailAddress::operator==(const class emailAddress& eml) const
|
bool emailAddress::operator==(const class emailAddress& eml) const {
|
||||||
{
|
|
||||||
return (m_localName == eml.m_localName &&
|
return m_localName == eml.m_localName &&
|
||||||
m_domainName == eml.m_domainName);
|
m_domainName == eml.m_domainName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool emailAddress::operator!=(const class emailAddress& eml) const
|
bool emailAddress::operator!=(const class emailAddress& eml) const {
|
||||||
{
|
|
||||||
return !(*this == eml);
|
return !(*this == eml);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emailAddress::copyFrom(const component& other)
|
void emailAddress::copyFrom(const component& other) {
|
||||||
{
|
|
||||||
const emailAddress& source = dynamic_cast <const emailAddress&>(other);
|
const emailAddress& source = dynamic_cast <const emailAddress&>(other);
|
||||||
|
|
||||||
m_localName = source.m_localName;
|
m_localName = source.m_localName;
|
||||||
@ -608,57 +631,57 @@ void emailAddress::copyFrom(const component& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
emailAddress& emailAddress::operator=(const emailAddress& other)
|
emailAddress& emailAddress::operator=(const emailAddress& other) {
|
||||||
{
|
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
return (*this);
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component>emailAddress::clone() const
|
shared_ptr <component>emailAddress::clone() const {
|
||||||
{
|
|
||||||
return make_shared <emailAddress>(*this);
|
return make_shared <emailAddress>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const word& emailAddress::getLocalName() const
|
const word& emailAddress::getLocalName() const {
|
||||||
{
|
|
||||||
return m_localName;
|
return m_localName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emailAddress::setLocalName(const word& localName)
|
void emailAddress::setLocalName(const word& localName) {
|
||||||
{
|
|
||||||
m_localName = localName;
|
m_localName = localName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const word& emailAddress::getDomainName() const
|
const word& emailAddress::getDomainName() const {
|
||||||
{
|
|
||||||
return m_domainName;
|
return m_domainName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emailAddress::setDomainName(const word& domainName)
|
void emailAddress::setDomainName(const word& domainName) {
|
||||||
{
|
|
||||||
m_domainName = domainName;
|
m_domainName = domainName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <component> > emailAddress::getChildComponents()
|
const std::vector <shared_ptr <component> > emailAddress::getChildComponents() {
|
||||||
{
|
|
||||||
return std::vector <shared_ptr <component> >();
|
return std::vector <shared_ptr <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool emailAddress::isEmpty() const
|
bool emailAddress::isEmpty() const {
|
||||||
{
|
|
||||||
return m_localName.isEmpty();
|
return m_localName.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string emailAddress::toString() const
|
const string emailAddress::toString() const {
|
||||||
{
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
utility::outputStreamAdapter adapter(oss);
|
utility::outputStreamAdapter adapter(oss);
|
||||||
|
|
||||||
@ -671,8 +694,8 @@ const string emailAddress::toString() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const text emailAddress::toText() const
|
const text emailAddress::toText() const {
|
||||||
{
|
|
||||||
text txt;
|
text txt;
|
||||||
txt.appendWord(make_shared <vmime::word>(m_localName));
|
txt.appendWord(make_shared <vmime::word>(m_localName));
|
||||||
txt.appendWord(make_shared <vmime::word>("@", vmime::charsets::US_ASCII));
|
txt.appendWord(make_shared <vmime::word>("@", vmime::charsets::US_ASCII));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -29,15 +29,13 @@
|
|||||||
#include "vmime/text.hpp"
|
#include "vmime/text.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/** An email address: local name and domain name (basic type).
|
/** An email address: local name and domain name (basic type).
|
||||||
*/
|
*/
|
||||||
|
class VMIME_EXPORT emailAddress : public component {
|
||||||
|
|
||||||
class VMIME_EXPORT emailAddress : public component
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
emailAddress();
|
emailAddress();
|
||||||
@ -114,18 +112,20 @@ public:
|
|||||||
using component::generate;
|
using component::generate;
|
||||||
|
|
||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parseImpl
|
void parseImpl(
|
||||||
(const parsingContext& ctx,
|
const parsingContext& ctx,
|
||||||
const string& buffer,
|
const string& buffer,
|
||||||
const size_t position,
|
const size_t position,
|
||||||
const size_t end,
|
const size_t end,
|
||||||
size_t* newPosition = NULL);
|
size_t* newPosition = NULL
|
||||||
|
);
|
||||||
|
|
||||||
void generateImpl
|
void generateImpl(
|
||||||
(const generationContext& ctx,
|
const generationContext& ctx,
|
||||||
utility::outputStream& os,
|
utility::outputStream& os,
|
||||||
const size_t curLinePos = 0,
|
const size_t curLinePos = 0,
|
||||||
size_t* newLinePos = NULL) const;
|
size_t* newLinePos = NULL
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -24,92 +24,101 @@
|
|||||||
#include "vmime/emptyContentHandler.hpp"
|
#include "vmime/emptyContentHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
emptyContentHandler::emptyContentHandler()
|
emptyContentHandler::emptyContentHandler() {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <contentHandler> emptyContentHandler::clone() const
|
shared_ptr <contentHandler> emptyContentHandler::clone() const {
|
||||||
{
|
|
||||||
return make_shared <emptyContentHandler>();
|
return make_shared <emptyContentHandler>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emptyContentHandler::generate(utility::outputStream& /* os */, const vmime::encoding& /* enc */,
|
void emptyContentHandler::generate(
|
||||||
const size_t /* maxLineLength */) const
|
utility::outputStream& /* os */,
|
||||||
{
|
const vmime::encoding& /* enc */,
|
||||||
|
const size_t /* maxLineLength */
|
||||||
|
) const {
|
||||||
|
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emptyContentHandler::extract(utility::outputStream& /* os */,
|
void emptyContentHandler::extract(
|
||||||
|
utility::outputStream& /* os */,
|
||||||
utility::progressListener* progress) const
|
utility::progressListener* progress) const
|
||||||
{
|
{
|
||||||
if (progress)
|
if (progress) {
|
||||||
progress->start(0);
|
progress->start(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
|
|
||||||
if (progress)
|
if (progress) {
|
||||||
progress->stop(0);
|
progress->stop(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emptyContentHandler::extractRaw(utility::outputStream& /* os */,
|
void emptyContentHandler::extractRaw(
|
||||||
utility::progressListener* progress) const
|
utility::outputStream& /* os */,
|
||||||
{
|
utility::progressListener* progress
|
||||||
if (progress)
|
) const {
|
||||||
|
|
||||||
|
if (progress) {
|
||||||
progress->start(0);
|
progress->start(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
|
|
||||||
if (progress)
|
if (progress) {
|
||||||
progress->stop(0);
|
progress->stop(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t emptyContentHandler::getLength() const
|
size_t emptyContentHandler::getLength() const {
|
||||||
{
|
|
||||||
return (0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool emptyContentHandler::isEmpty() const
|
bool emptyContentHandler::isEmpty() const {
|
||||||
{
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool emptyContentHandler::isEncoded() const
|
|
||||||
{
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const vmime::encoding& emptyContentHandler::getEncoding() const
|
|
||||||
{
|
|
||||||
return (NO_ENCODING);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool emptyContentHandler::isBuffered() const
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emptyContentHandler::setContentTypeHint(const mediaType& type)
|
bool emptyContentHandler::isEncoded() const {
|
||||||
{
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const vmime::encoding& emptyContentHandler::getEncoding() const {
|
||||||
|
|
||||||
|
return NO_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool emptyContentHandler::isBuffered() const {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void emptyContentHandler::setContentTypeHint(const mediaType& type) {
|
||||||
|
|
||||||
m_contentType = type;
|
m_contentType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const mediaType emptyContentHandler::getContentTypeHint() const
|
const mediaType emptyContentHandler::getContentTypeHint() const {
|
||||||
{
|
|
||||||
return m_contentType;
|
return m_contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -28,22 +28,32 @@
|
|||||||
#include "vmime/contentHandler.hpp"
|
#include "vmime/contentHandler.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class VMIME_EXPORT emptyContentHandler : public contentHandler
|
class VMIME_EXPORT emptyContentHandler : public contentHandler {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
emptyContentHandler();
|
emptyContentHandler();
|
||||||
|
|
||||||
shared_ptr <contentHandler> clone() const;
|
shared_ptr <contentHandler> clone() const;
|
||||||
|
|
||||||
void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const;
|
void generate(
|
||||||
|
utility::outputStream& os,
|
||||||
|
const vmime::encoding& enc,
|
||||||
|
const size_t maxLineLength = lineLengthLimits::infinite
|
||||||
|
) const;
|
||||||
|
|
||||||
void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const;
|
void extract(
|
||||||
void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const;
|
utility::outputStream& os,
|
||||||
|
utility::progressListener* progress = NULL
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void extractRaw(
|
||||||
|
utility::outputStream& os,
|
||||||
|
utility::progressListener* progress = NULL
|
||||||
|
) const;
|
||||||
|
|
||||||
size_t getLength() const;
|
size_t getLength() const;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// VMime library (http://www.vmime.org)
|
// VMime library (http://www.vmime.org)
|
||||||
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
|
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or
|
// This program is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU General Public License as
|
// modify it under the terms of the GNU General Public License as
|
||||||
@ -30,118 +30,140 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime {
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
encoding::encoding()
|
encoding::encoding()
|
||||||
: m_name(encodingTypes::SEVEN_BIT),
|
: m_name(encodingTypes::SEVEN_BIT),
|
||||||
m_usage(USAGE_UNKNOWN)
|
m_usage(USAGE_UNKNOWN) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding::encoding(const string& name)
|
encoding::encoding(const string& name)
|
||||||
: m_name(utility::stringUtils::toLower(name)),
|
: m_name(utility::stringUtils::toLower(name)),
|
||||||
m_usage(USAGE_UNKNOWN)
|
m_usage(USAGE_UNKNOWN) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding::encoding(const string& name, const EncodingUsage usage)
|
encoding::encoding(const string& name, const EncodingUsage usage)
|
||||||
: m_name(utility::stringUtils::toLower(name)),
|
: m_name(utility::stringUtils::toLower(name)),
|
||||||
m_usage(usage)
|
m_usage(usage) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding::encoding(const encoding& enc)
|
encoding::encoding(const encoding& enc)
|
||||||
: headerFieldValue(), m_name(enc.m_name), m_usage(enc.m_usage)
|
: headerFieldValue(),
|
||||||
{
|
m_name(enc.m_name),
|
||||||
|
m_usage(enc.m_usage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoding::parseImpl
|
void encoding::parseImpl(
|
||||||
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
|
const parsingContext& /* ctx */,
|
||||||
const size_t end, size_t* newPosition)
|
const string& buffer,
|
||||||
{
|
const size_t position,
|
||||||
|
const size_t end,
|
||||||
|
size_t* newPosition
|
||||||
|
) {
|
||||||
|
|
||||||
m_usage = USAGE_UNKNOWN;
|
m_usage = USAGE_UNKNOWN;
|
||||||
|
|
||||||
m_name = utility::stringUtils::toLower(utility::stringUtils::trim
|
m_name = utility::stringUtils::toLower(
|
||||||
(utility::stringUtils::unquote(utility::stringUtils::trim
|
utility::stringUtils::trim(
|
||||||
(string(buffer.begin() + position, buffer.begin() + end)))));
|
utility::stringUtils::unquote(
|
||||||
|
utility::stringUtils::trim(
|
||||||
|
string(buffer.begin() + position, buffer.begin() + end)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (m_name.empty())
|
if (m_name.empty()) {
|
||||||
m_name = encodingTypes::SEVEN_BIT; // assume default "7-bit"
|
m_name = encodingTypes::SEVEN_BIT; // assume default "7-bit"
|
||||||
|
}
|
||||||
|
|
||||||
setParsedBounds(position, end);
|
setParsedBounds(position, end);
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition) {
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoding::generateImpl
|
void encoding::generateImpl(
|
||||||
(const generationContext& /* ctx */, utility::outputStream& os,
|
const generationContext& /* ctx */,
|
||||||
const size_t curLinePos, size_t* newLinePos) const
|
utility::outputStream& os,
|
||||||
{
|
const size_t curLinePos,
|
||||||
|
size_t* newLinePos
|
||||||
|
) const {
|
||||||
|
|
||||||
os << m_name;
|
os << m_name;
|
||||||
|
|
||||||
if (newLinePos)
|
if (newLinePos) {
|
||||||
*newLinePos = curLinePos + m_name.length();
|
*newLinePos = curLinePos + m_name.length();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <utility::encoder::encoder> encoding::getEncoder() const
|
shared_ptr <utility::encoder::encoder> encoding::getEncoder() const {
|
||||||
{
|
|
||||||
shared_ptr <utility::encoder::encoder> encoder =
|
shared_ptr <utility::encoder::encoder> encoder =
|
||||||
utility::encoder::encoderFactory::getInstance()->create(generate());
|
utility::encoder::encoderFactory::getInstance()->create(generate());
|
||||||
|
|
||||||
// FIXME: this should not be here (move me into QP encoder instead?)
|
// FIXME: this should not be here (move me into QP encoder instead?)
|
||||||
if (m_usage == USAGE_TEXT && m_name == encodingTypes::QUOTED_PRINTABLE)
|
if (m_usage == USAGE_TEXT && m_name == encodingTypes::QUOTED_PRINTABLE) {
|
||||||
encoder->getProperties()["text"] = true;
|
encoder->getProperties()["text"] = true;
|
||||||
|
}
|
||||||
|
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding& encoding::operator=(const encoding& other)
|
encoding& encoding::operator=(const encoding& other) {
|
||||||
{
|
|
||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding& encoding::operator=(const string& name)
|
encoding& encoding::operator=(const string& name) {
|
||||||
{
|
|
||||||
m_name = utility::stringUtils::toLower(name);
|
m_name = utility::stringUtils::toLower(name);
|
||||||
m_usage = USAGE_UNKNOWN;
|
m_usage = USAGE_UNKNOWN;
|
||||||
return (*this);
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool encoding::operator==(const encoding& value) const
|
bool encoding::operator==(const encoding& value) const {
|
||||||
{
|
|
||||||
return (utility::stringUtils::toLower(m_name) == value.m_name);
|
return utility::stringUtils::toLower(m_name) == value.m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool encoding::operator!=(const encoding& value) const
|
bool encoding::operator!=(const encoding& value) const {
|
||||||
{
|
|
||||||
return !(*this == value);
|
return !(*this == value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const encoding encoding::decideImpl
|
const encoding encoding::decideImpl(
|
||||||
(const string::const_iterator begin, const string::const_iterator end)
|
const string::const_iterator begin,
|
||||||
{
|
const string::const_iterator end
|
||||||
|
) {
|
||||||
|
|
||||||
const string::difference_type length = end - begin;
|
const string::difference_type length = end - begin;
|
||||||
const string::difference_type count = std::count_if
|
const string::difference_type count = std::count_if(
|
||||||
(begin, end, std::bind2nd(std::less<unsigned char>(), 127));
|
begin, end,
|
||||||
|
std::bind2nd(std::less<unsigned char>(), 127)
|
||||||
|
);
|
||||||
|
|
||||||
// All is in 7-bit US-ASCII --> 7-bit (or Quoted-Printable...)
|
// All is in 7-bit US-ASCII --> 7-bit (or Quoted-Printable...)
|
||||||
if (length == count)
|
if (length == count) {
|
||||||
{
|
|
||||||
// Now, we check if there is any line with more than
|
// Now, we check if there is any line with more than
|
||||||
// "lineLengthLimits::convenient" characters (7-bit requires that)
|
// "lineLengthLimits::convenient" characters (7-bit requires that)
|
||||||
string::const_iterator p = begin;
|
string::const_iterator p = begin;
|
||||||
@ -149,49 +171,51 @@ const encoding encoding::decideImpl
|
|||||||
const size_t maxLen = lineLengthLimits::convenient;
|
const size_t maxLen = lineLengthLimits::convenient;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
for ( ; p != end && len <= maxLen ; )
|
for ( ; p != end && len <= maxLen ; ) {
|
||||||
{
|
|
||||||
if (*p == '\n')
|
if (*p == '\n') {
|
||||||
{
|
|
||||||
len = 0;
|
len = 0;
|
||||||
++p;
|
++p;
|
||||||
|
|
||||||
// May or may not need to be encoded, we don't take
|
// May or may not need to be encoded, we don't take
|
||||||
// any risk (avoid problems with SMTP)
|
// any risk (avoid problems with SMTP)
|
||||||
if (p != end && *p == '.')
|
if (p != end && *p == '.') {
|
||||||
len = maxLen + 1;
|
len = maxLen + 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
} else {
|
||||||
|
|
||||||
++len;
|
++len;
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > maxLen)
|
if (len > maxLen) {
|
||||||
return (encoding(encodingTypes::QUOTED_PRINTABLE));
|
return encoding(encodingTypes::QUOTED_PRINTABLE);
|
||||||
else
|
} else {
|
||||||
return (encoding(encodingTypes::SEVEN_BIT));
|
return encoding(encodingTypes::SEVEN_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Less than 20% non US-ASCII --> Quoted-Printable
|
// Less than 20% non US-ASCII --> Quoted-Printable
|
||||||
else if ((length - count) <= length / 5)
|
} else if ((length - count) <= length / 5) {
|
||||||
{
|
|
||||||
return (encoding(encodingTypes::QUOTED_PRINTABLE));
|
return encoding(encodingTypes::QUOTED_PRINTABLE);
|
||||||
}
|
|
||||||
// Otherwise --> Base64
|
// Otherwise --> Base64
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
return (encoding(encodingTypes::BASE64));
|
return encoding(encodingTypes::BASE64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool encoding::shouldReencode() const
|
bool encoding::shouldReencode() const {
|
||||||
{
|
|
||||||
if (m_name == encodingTypes::BASE64 ||
|
if (m_name == encodingTypes::BASE64 ||
|
||||||
m_name == encodingTypes::QUOTED_PRINTABLE ||
|
m_name == encodingTypes::QUOTED_PRINTABLE ||
|
||||||
m_name == encodingTypes::UUENCODE)
|
m_name == encodingTypes::UUENCODE) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,18 +223,21 @@ bool encoding::shouldReencode() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const encoding encoding::decide
|
const encoding encoding::decide(
|
||||||
(shared_ptr <const contentHandler> data, const EncodingUsage usage)
|
const shared_ptr <const contentHandler>& data,
|
||||||
{
|
const EncodingUsage usage
|
||||||
|
) {
|
||||||
|
|
||||||
// Do not re-encode data if it is already encoded
|
// Do not re-encode data if it is already encoded
|
||||||
if (data->isEncoded() && !data->getEncoding().shouldReencode())
|
if (data->isEncoded() && !data->getEncoding().shouldReencode()) {
|
||||||
return data->getEncoding();
|
return data->getEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
encoding enc;
|
encoding enc;
|
||||||
|
|
||||||
if (usage == USAGE_TEXT && data->isBuffered() &&
|
if (usage == USAGE_TEXT && data->isBuffered() &&
|
||||||
data->getLength() > 0 && data->getLength() < 32768)
|
data->getLength() > 0 && data->getLength() < 32768) {
|
||||||
{
|
|
||||||
// Extract data into temporary buffer
|
// Extract data into temporary buffer
|
||||||
string buffer;
|
string buffer;
|
||||||
utility::outputStreamStringAdapter os(buffer);
|
utility::outputStreamStringAdapter os(buffer);
|
||||||
@ -219,9 +246,9 @@ const encoding encoding::decide
|
|||||||
os.flush();
|
os.flush();
|
||||||
|
|
||||||
enc = decideImpl(buffer.begin(), buffer.end());
|
enc = decideImpl(buffer.begin(), buffer.end());
|
||||||
}
|
|
||||||
else
|
} else {
|
||||||
{
|
|
||||||
enc = encoding(encodingTypes::BASE64);
|
enc = encoding(encodingTypes::BASE64);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,19 +258,23 @@ const encoding encoding::decide
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const encoding encoding::decide(shared_ptr <const contentHandler> data,
|
const encoding encoding::decide(
|
||||||
const charset& chset, const EncodingUsage usage)
|
const shared_ptr <const contentHandler>& data,
|
||||||
{
|
const charset& chset,
|
||||||
// Do not re-encode data if it is already encoded
|
const EncodingUsage usage
|
||||||
if (data->isEncoded() && !data->getEncoding().shouldReencode())
|
) {
|
||||||
return data->getEncoding();
|
|
||||||
|
// Do not re-encode data if it is already encoded
|
||||||
|
if (data->isEncoded() && !data->getEncoding().shouldReencode()) {
|
||||||
|
return data->getEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usage == USAGE_TEXT) {
|
||||||
|
|
||||||
if (usage == USAGE_TEXT)
|
|
||||||
{
|
|
||||||
encoding recEncoding;
|
encoding recEncoding;
|
||||||
|
|
||||||
if (chset.getRecommendedEncoding(recEncoding))
|
if (chset.getRecommendedEncoding(recEncoding)) {
|
||||||
{
|
|
||||||
recEncoding.setUsage(usage);
|
recEncoding.setUsage(usage);
|
||||||
return recEncoding;
|
return recEncoding;
|
||||||
}
|
}
|
||||||
@ -253,46 +284,46 @@ const encoding encoding::decide(shared_ptr <const contentHandler> data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
shared_ptr <component> encoding::clone() const
|
shared_ptr <component> encoding::clone() const {
|
||||||
{
|
|
||||||
return make_shared <encoding>(*this);
|
return make_shared <encoding>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoding::copyFrom(const component& other)
|
void encoding::copyFrom(const component& other) {
|
||||||
{
|
|
||||||
const encoding& e = dynamic_cast <const encoding&>(other);
|
const encoding& e = dynamic_cast <const encoding&>(other);
|
||||||
|
|
||||||
m_name = e.m_name;
|
m_name = e.m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string& encoding::getName() const
|
const string& encoding::getName() const {
|
||||||
{
|
|
||||||
return (m_name);
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoding::setName(const string& name)
|
void encoding::setName(const string& name) {
|
||||||
{
|
|
||||||
m_name = name;
|
m_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding::EncodingUsage encoding::getUsage() const
|
encoding::EncodingUsage encoding::getUsage() const {
|
||||||
{
|
|
||||||
return m_usage;
|
return m_usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void encoding::setUsage(const EncodingUsage usage)
|
void encoding::setUsage(const EncodingUsage usage) {
|
||||||
{
|
|
||||||
m_usage = usage;
|
m_usage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <shared_ptr <component> > encoding::getChildComponents()
|
const std::vector <shared_ptr <component> > encoding::getChildComponents() {
|
||||||
{
|
|
||||||
return std::vector <shared_ptr <component> >();
|
return std::vector <shared_ptr <component> >();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user