Merge branch 'master' into master

This commit is contained in:
Vincent Richard 2018-09-07 20:32:51 +02:00 committed by GitHub
commit 71968d978d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
558 changed files with 26544 additions and 22623 deletions

View File

@ -12,7 +12,7 @@
# 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)
@ -68,6 +68,11 @@ SET(VMIME_API_VERSION ${VMIME_API_VERSION_CURRENT}.${VMIME_API_VERSION_REVISION}
# Set base name
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
FILE(
GLOB_RECURSE
@ -109,6 +114,10 @@ IF(VMIME_BUILD_SHARED_LIBRARY)
${VMIME_LIBRARY_INCLUDE_FILES}
)
TARGET_INCLUDE_DIRECTORIES(${VMIME_LIBRARY_NAME} PUBLIC
$<INSTALL_INTERFACE:include>
)
GENERATE_EXPORT_HEADER(
${VMIME_LIBRARY_NAME}
BASE_NAME VMIME
@ -154,6 +163,10 @@ IF(VMIME_BUILD_STATIC_LIBRARY)
${VMIME_LIBRARY_INCLUDE_FILES}
)
TARGET_INCLUDE_DIRECTORIES(${VMIME_LIBRARY_NAME}-static PUBLIC
$<INSTALL_INTERFACE:include>
)
GENERATE_EXPORT_HEADER(
${VMIME_LIBRARY_NAME}-static
BASE_NAME VMIME
@ -199,6 +212,7 @@ SET(CMAKE_INSTALL_LIBDIR lib CACHE PATH "Output directory for libraries")
IF(VMIME_BUILD_SHARED_LIBRARY)
INSTALL(
TARGETS ${VMIME_LIBRARY_NAME}
EXPORT ${VMIME_LIBRARY_NAME}-config
LIBRARY 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)
INSTALL(
TARGETS ${VMIME_LIBRARY_NAME}-static
EXPORT ${VMIME_LIBRARY_NAME}-config
LIBRARY 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
#)
install(EXPORT ${VMIME_LIBRARY_NAME}-config DESTINATION cmake)
##############################################################################
# Tests
@ -783,89 +800,6 @@ ELSE()
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
@ -997,12 +931,12 @@ IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
SET(
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_DEBUG "-O0 -g")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
#SET(CMAKE_EXE_LINKER_FLAGS "-s")
@ -1012,12 +946,12 @@ ELSE()
SET(
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_DEBUG "-O0 -g")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 ${CMAKE_CXX_FLAGS_DEBUG}")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
#SET(CMAKE_EXE_LINKER_FLAGS "-s")

76
HACKING
View File

@ -80,25 +80,52 @@ width to its preferred settings (eg. 4 or 8 spaces).
2.2. Brace position
-------------------
Open braces should always be at the beginning of the line after the statement
that begins the block. Contents of the brace should be indented by 1 tab.
Open braces should always be at the end of the line of the statement that
begins the block. Contents of the brace should be indented by 1 tab.
if (expr) {
if (expr)
{
do_something();
do_another_thing();
}
else
{
} 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
-----------------------
switch (expr)
{
switch (expr) {
case 0:
something;
@ -109,44 +136,35 @@ that begins the block. Contents of the brace should be indented by 1 tab.
something_else;
break;
case 2:
{
case 2: {
int var = 42;
another_thing;
break;
}
}
2.4. Single instruction
-----------------------
Omit braces around simple single-statement body:
Don't omit braces around simple single-statement body:
if (...)
if (...) {
something;
}
and not:
if (...)
{
something;
}
Except when body spans over multiple lines:
if (...)
{
something_too_long_for(
a_single_line);
}
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
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.
Tabs should NOT be used to indent at the end of a line:
class myClass
{
class myClass {
private:
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).
* Put the inclusion for the class's header file as the first inclusion in
the implementation file.
* Put the #include for the class's header file first in the implementation
file.
* Put the copyright header at the top of each file.

View File

@ -1 +0,0 @@
build

View File

@ -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

View File

@ -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)

View File

@ -1,8 +0,0 @@
int main(void)
{
if (!__func__)
return 1;
if (!(*__func__))
return 1;
return 0;
}

View File

@ -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;
}

View File

@ -1,7 +0,0 @@
int main(void)
{
// must fail because there is no initializer
auto i;
return 0;
}

View File

@ -1,8 +0,0 @@
auto foo(int i) -> int {
return i - 1;
}
int main()
{
return foo(1);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,5 +0,0 @@
int main()
{
int ret = 0;
return ([&ret]() -> int { return ret; })();
}

View File

@ -1,7 +0,0 @@
int main(void)
{
long long l;
unsigned long long ul;
return ((sizeof(l) >= 8) && (sizeof(ul) >= 8)) ? 0 : 1;
}

View File

@ -1,6 +0,0 @@
int main(void)
{
void *v = nullptr;
return v ? 1 : 0;
}

View File

@ -1,6 +0,0 @@
int main(void)
{
int i = nullptr;
return 1;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,9 +0,0 @@
struct foo {
int baz;
double bar;
};
int main(void)
{
return (sizeof(foo::bar) == 4) ? 0 : 1;
}

View File

@ -1,5 +0,0 @@
int main(void)
{
static_assert(0 < 1, "your ordering of integers is screwed");
return 0;
}

View File

@ -1,5 +0,0 @@
int main(void)
{
static_assert(1 < 0, "your ordering of integers is screwed");
return 0;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -46,17 +46,17 @@ use the function {\vcode vmime::make\_shared} instead of the {\vcode new}
operator.
\begin{lstlisting}[caption={Smarts pointers and creating objects}]
class myObject : public vmime::object
{
class myObject : public vmime::object {
public:
myObject(const vmime::string& name)
: m_name(name)
{
: m_name(name) {
}
void sayHello()
{
void sayHello() {
std::cout << "Hello " << m_name << std::endl;
}
@ -65,8 +65,8 @@ private:
vmime::string m_name;
};
int main()
{
int main() {
vmime::shared_ptr <myObject> obj =
vmime::make_shared <myObject>("world");
@ -105,12 +105,12 @@ directly or indirectly to itself). The following example illustrates a
typical problem of reference counting:
\begin{lstlisting}
class parent : public vmime::object
{
class parent : public vmime::object {
public:
void createChild(vmime::shared_ptr <child> c)
{
void createChild(vmime::shared_ptr <child> c) {
m_child = c;
}
@ -119,13 +119,13 @@ private:
vmime::shared_ptr <child> m_child;
};
class child : public vmime::object
{
class child : public vmime::object {
public:
child(vmime::shared_ptr <parent> p)
: m_parent(p)
{
: m_parent(p) {
}
private:
@ -133,8 +133,8 @@ private:
vmime::shared_ptr <parent> m_parent;
};
int main()
{
int main() {
vmime::shared_ptr <parent> p = vmime::make_shared <parent>();
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:
\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 << " what = " << e.what() << std::endl;
// Recursively print all encapsuled exceptions
if (e.other() != NULL)
if (e.other() != NULL) {
os << *e.other();
}
return os;
}
...
try
{
try {
// ...some call to VMime...
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << e; // VMime exception
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << e.what(); // standard exception
}
\end{lstlisting}
@ -250,7 +251,8 @@ vmime::datetime d1("Sat, 08 Oct 2005 14:07:52 +0200");
vmime::datetime d2(
/* date */ 2005, vmime::datetime::OCTOBER, 8,
/* time */ 14, 7, 52,
/* zone */ vmime::datetime::GMT2);
/* zone */ vmime::datetime::GMT2
);
// Getting day of week
const int dow = d2.getWeekDay(); // 'dow' should be datetime::SATURDAY
@ -275,7 +277,8 @@ media type with:
\begin{lstlisting}
vmime::mediaType theType(
/* top-level type */ vmime::mediaTypes::IMAGE,
/* sub-type */ vmime::mediaTypes::IMAGE_JPEG);
/* sub-type */ vmime::mediaTypes::IMAGE_JPEG
);
// theType.getType() is "image"
// theType.getSubType() is "jpeg"
@ -594,8 +597,9 @@ std::ifstream* fileStream = new std::ifstream();
fileStream->open("/home/vincent/paris.jpg", std::ios::binary);
if (!*fileStream)
if (!*fileStream) {
// handle error
}
vmime::shared_ptr <utility::stream> dataStream =
vmime::make_shared <vmime::utility::inputStreamPointerAdapter>(fileStream);
@ -608,8 +612,7 @@ vmime::shared_ptr <contentHandler> data =
vmime::make_shared <vmime::streamContentHandler>(dataStream, 0);
// 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,
/* content type */ vmime::mediaType("image/jpeg"),
/* description */ vmime::text("Holiday photo"),
@ -647,10 +650,11 @@ vmime::shared_ptr <const vmime::contentHandler> cth = body->getContents();
// Then, extract and convert the contents
vmime::utility::outputStreamAdapter out(std::cout);
vmime::utility::charsetFilteredOutputStream fout
(/* source charset */ body->getCharset(),
vmime::utility::charsetFilteredOutputStream fout(
/* source charset */ body->getCharset(),
/* dest charset */ vmime::charset("utf-8"),
/* dest stream */ out);
/* dest stream */ out
);
cth->extract(fout);
@ -778,8 +782,8 @@ vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
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
vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
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>::const_iterator it;
for (it = props.begin() ; it != props.end() ; ++it)
for (it = props.begin() ; it != props.end() ; ++it) {
std::cout << " - " << *it << std::endl;
}
\end{lstlisting}

View File

@ -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
\href{http://www.gnu.org/software/gnutls/}{GNU TLS Library} if you
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}
% ============================================================================

View File

@ -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:
\begin{verbatim}
Copyright (C) 2002-2013 Vincent Richard
Copyright (C) 2002 Vincent Richard
VMime library is free software; you can redistribute it and/or
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):
\begin{verbatim}
Copyright (C) 2004-2013 Vincent Richard
Copyright (C) 2004 Vincent Richard
Permission is granted to copy, distribute and/or modify
this document under the terms of the GNU Free Documentation

View File

@ -94,8 +94,8 @@ vmime::messageParser mp(msg);
std::cout << "Message has " << mp.getAttachmentCount()
<< " 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);
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()
<< " 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);
// 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::dynamicCast <const vmime::htmlTextPart>(tp);
@ -118,18 +118,18 @@ for (int i = 0 ; i < mp.getTextPartCount() ; ++i)
// Plain text is in tp->getPlainText()
// 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 =
htp->getObjectAt(j);
// Identifier (Content-Id or Content-Location) is obj->getId()
// Object data is in obj->getData()
}
}
// text/plain or anything else
else
{
} else {
// Text is in tp->getText()
}
}
@ -172,8 +172,7 @@ hdr->appendField(subjectField);
vmime::shared_ptr <vmime::headerField> fromField =
hfFactory->create(vmime::fields::FROM);
fromField->setValue
(vmime::make_shared <vmime::mailbox>("me@vmime.org"));
fromField->setValue(vmime::make_shared <vmime::mailbox>("me@vmime.org"));
hdr->appendField(fromField);
// Append a 'To:' field
@ -190,8 +189,11 @@ toField->setValue(recipients);
hdr->appendField(toField);
// Set the body contents
bdy->setContents(vmime::make_shared <vmime::stringContentHandler>
("This is the text of your message..."));
bdy->setContents(
vmime::make_shared <vmime::stringContentHandler>(
"This is the text of your message..."
)
);
// Output raw message data to standard output
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
using {\vcode vmime::messageBuilder}}]
try
{
try {
vmime::messageBuilder mb;
// Fill in some header fields and message body
mb.setSubject(vmime::text("Message subject"));
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
mb.getRecipients().appendAddress
(vmime::make_shared <vmime::mailbox>("you@vmime.org"));
mb.getRecipients().appendAddress(
vmime::make_shared <vmime::mailbox>("you@vmime.org")
);
mb.getTextPart()->setCharset(vmime::charsets::ISO8859_15);
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>
("This is the text of your message..."));
mb.getTextPart()->setText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the text of your message..."
)
);
// Message construction
vmime::shared_ptr <vmime::message> msg = mb.construct();
@ -227,15 +233,15 @@ try
// Output raw message data to standard output
vmime::utility::outputStreamAdapter out(std::cout);
msg->generate(out);
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << "vmime::exception: " << e.what() << std::endl;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << "std::exception: " << e.what() << std::endl;
}
\end{lstlisting}
@ -250,8 +256,7 @@ previous example to attach a file to the message:
{\vcode vmime::messageBuilder}}]
// Create an attachment
vmime::shared_ptr <vmime::fileAttachment> att =
vmime::make_shared <vmime::fileAttachment>
(
vmime::make_shared <vmime::fileAttachment>(
/* full path to file */ "/home/vincent/paris.jpg",
/* content type */ vmime::mediaType("image/jpeg),
/* 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
att->getFileInfo().setFilename("paris.jpg");
att->getFileInfo().setCreationDate
(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
att->getFileInfo().setCreationDate(
vmime::datetime("30 Apr 2003 14:30:00 +0200")
);
// Add this attachment to the message
mb.appendAttachment(att);
@ -283,14 +289,19 @@ using the {\vcode vmime::messageBuilder}}]
// Fill in some header fields
mb.setSubject(vmime::text("An HTML message"));
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
mb.getRecipients().appendAddress
(vmime::make_shared <vmime::mailbox>("you@vmime.org"));
mb.getRecipients().appendAddress(
vmime::make_shared <vmime::mailbox>("you@vmime.org")
);
// 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
// the message builder construct the two text parts.
mb.constructTextPart(vmime::mediaType
(vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML));
mb.constructTextPart(
vmime::mediaType(
vmime::mediaTypes::TEXT,
vmime::mediaTypes::TEXT_HTML
)
);
// 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.
@ -306,12 +317,18 @@ const vmime::string id = textPart->addObject("<...image data...>",
// -- Set the text
textPart->setCharset(vmime::charsets::ISO8859_15);
textPart->setText(vmime::make_shared <vmime::stringContentHandler>
("This is the <b>HTML text</b>, and the image:<br/>"
"<img src=\"") + id + vmime::string("\"/>"));
textPart->setText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the <b>HTML text</b>, and the image:<br/>"
"<img src=\"") + id + vmime::string("\"/>"
)
);
textPart->setPlainText(vmime::make_shared <vmime::stringContentHandler>
("This is the plain text."));
textPart->setPlainText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the plain text."
)
);
\end{lstlisting}
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"));
vmime::shared_ptr <vmime::contentHandler> imageCts =
vmime::make_shared <vmime::streamContentHandler>
(imageFile->getFileReader()->getInputStream(), imageFile->getLength());
vmime::make_shared <vmime::streamContentHandler>(
imageFile->getFileReader()->getInputStream(),
imageFile->getLength()
);
const vmime::string cid = textPart.addObject(imageCts,
vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
const vmime::string cid = textPart.addObject(
imageCts,
vmime::mediaType(
vmime::mediaTypes::IMAGE,
vmime::mediaTypes::IMAGE_JPEG
)
);
\end{lstlisting}
@ -361,8 +385,8 @@ extract its contents to the standard output:
\begin{lstlisting}[caption={Testing if a body part is an attachment}]
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
vmime::shared_ptr <const vmime::attachment> attach =
attachmentHelper::getBodyPartAttachment(part);
@ -394,8 +418,7 @@ vmime::shared_ptr <vmime::message> msg; // suppose we have a message
// Create an attachment
vmime::shared_ptr <vmime::fileAttachment> att =
vmime::make_shared <vmime::fileAttachment>
(
vmime::make_shared <vmime::fileAttachment>(
/* full path to file */ "/home/vincent/paris.jpg",
/* content type */ vmime::mediaType("image/jpeg),
/* description */ vmime::text("My holidays in Paris")

View File

@ -300,10 +300,10 @@ The following example shows how to use a custom authenticator to request
the user to enter her/his credentials:
\begin{lstlisting}[caption={A simple interactive authenticator}]
class myAuthenticator : public vmime::security::defaultAuthenticator
{
const string getUsername() const
{
class myAuthenticator : public vmime::security::defaultAuthenticator {
const string getUsername() const {
std::cout << "Enter your username: " << std::endl;
vmime::string res;
@ -312,8 +312,8 @@ class myAuthenticator : public vmime::security::defaultAuthenticator
return res;
}
const string getPassword() const
{
const string getPassword() const {
std::cout << "Enter your password: " << std::endl;
vmime::string res;
@ -331,9 +331,10 @@ This is how to use it:
vmime::shared_ptr <vmime::net::session> sess = vmime::net::session::create();
// Next, initialize a service which will use our authenticator
vmime::shared_ptr <vmime::net::store> st =
sess->getStore(vmime::utility::url("imap://imap.example.com"),
/* use our authenticator */ vmime::make_shared <myAuthenticator>());
vmime::shared_ptr <vmime::net::store> st = sess->getStore(
vmime::utility::url("imap://imap.example.com"),
/* use our authenticator */ vmime::make_shared <myAuthenticator>()
);
\end{lstlisting}
\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.
\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
const std::vector <vmime::shared_ptr <mechanism> > getAcceptableMechanisms
(const std::vector <vmime::shared_ptr <mechanism> >& available,
vmime::shared_ptr <mechanism> suggested) const
{
const std::vector <vmime::shared_ptr <mechanism> > getAcceptableMechanisms(
const std::vector <vmime::shared_ptr <mechanism> >& available,
const vmime::shared_ptr <mechanism>& suggested
) const {
// Here, you can sort the SASL mechanisms in the order they will be
// tried. If no SASL mechanism is acceptable (ie. for example, not
// enough secure), you can return an empty list.
@ -372,8 +374,8 @@ class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticat
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
// try the specified mechanism.
//
@ -435,7 +437,8 @@ tr->send(
/* expeditor */ from,
/* recipient(s) */ to,
/* data */ is,
/* total length */ msgData.length());
/* total length */ msgData.length()
);
// We have finished using the service
tr->disconnect();
@ -556,22 +559,26 @@ std::vector <ref <vmime::net::message> > allMessages =
folder->getMessages(vmime::net::messageSet::byNumber(1, -1));
// -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::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];
const int flags = msg->getFlags();
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;
if (flags & vmime::net::message::FLAG_DELETED)
}
if (flags & vmime::net::message::FLAG_DELETED) {
std::cout << " - is deleted" << std::endl;
}
vmime::shared_ptr <const vmime::header> hdr = msg->getHeader();
@ -698,8 +705,8 @@ running.
An interface called {\vcode timeoutHandler} is provided:
\begin{lstlisting}
class timeoutHandler : public object
{
class timeoutHandler : public object {
/** Called to test if the time limit has been reached.
*
* @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:
\begin{lstlisting}[caption={Implementing a simple timeout handler}]
class myTimeoutHandler : public vmime::net::timeoutHandler
{
class myTimeoutHandler : public vmime::net::timeoutHandler {
public:
myTimeoutHandler()
{
myTimeoutHandler() {
m_startTime = time(NULL);
}
const bool isTimeOut()
{
return (time(NULL) >= m_startTime + 30); // 30 seconds timeout
const bool isTimeOut() {
return time(NULL) >= m_startTime + 30; // 30 seconds timeout
}
void resetTimeOut()
{
void resetTimeOut() {
m_startTime = time(NULL);
}
const bool handleTimeOut()
{
const bool handleTimeOut() {
std::cout << "Operation timed out." << std::endl;
<< "Press [Y] to continue, or [N] to "
<< "cancel the operation." << std::endl;
@ -766,7 +773,7 @@ public:
std::string response;
std::cin >> response;
return (response == "y" || response == "Y");
return response == "y" || response == "Y";
}
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.
\begin{lstlisting}
class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
{
class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory {
public:
ref <timeoutHandler> create()
{
ref <timeoutHandler> create() {
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}]
vmime::shared_ptr <vmime::security::cert::X509Certificate>
loadX509CertificateFromFile(const std::string& path)
{
loadX509CertificateFromFile(const std::string& path) {
std::ifstream certFile;
certFile.open(path.c_str(), std::ios::in | std::ios::binary);
if (!certFile)
{
if (!certFile) {
// ...handle error...
}
vmime::utility::inputStreamAdapter is(certFile);
vmime::shared_ptr <vmime::security::cert::X509Certificate> cert;
// Try DER format
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);
cert = vmime::security::cert::X509Certificate::import(is);
return cert;
}
@ -988,12 +984,12 @@ use this in a production application as this is obviously a serious security
issue):
\begin{lstlisting}[caption={A custom certificate verifier}]
class myCertVerifier : public vmime::security::cert::certificateVerifier
{
class myCertVerifier : public vmime::security::cert::certificateVerifier {
public:
void verify(vmime::shared_ptr <certificateChain> certs)
{
void verify(const vmime::shared_ptr <certificateChain>& certs) {
// Obtain the subject's certificate
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
@ -1006,8 +1002,9 @@ public:
std::string 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
}
// Don't trust this certificate
throw vmime::security::cert::certificateException();
@ -1090,3 +1087,117 @@ The following constants are available:
\hline
\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...}"").

View File

@ -26,7 +26,7 @@ You can simply build your program with:
to use the static version, or with:
\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}
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/platforms/posix/posixHandler.hpp>
int main()
{
int main() {
vmime::platform::
setHandler <vmime::platforms::posix::posixHandler>();

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -39,23 +39,20 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// 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.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageBuilder mb;
// Fill in the basic fields
@ -74,9 +71,12 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// 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 " \
"using the vmime::messageBuilder component."));
"using the vmime::messageBuilder component."
)
);
// Construction
vmime::shared_ptr <vmime::message> msg = mb.construct();
@ -87,20 +87,21 @@ int main()
vmime::utility::outputStreamAdapter out(std::cout);
msg->generate(out);
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
//throw;
throw;
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -39,23 +39,20 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// 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.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageBuilder mb;
// Fill in the basic fields
@ -74,13 +71,16 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// 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 " \
"with attachment, using the vmime::messageBuilder component."));
"with attachment, using the vmime::messageBuilder component."
)
);
// 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
vmime::mediaType("application/octet-stream"), // content type
vmime::text("My first attachment") // description
@ -101,20 +101,21 @@ int main()
std::cout << "==================" << std::endl;
std::cout << std::endl;
std::cout << dataToSend << std::endl;
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -39,23 +39,20 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// 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.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageBuilder mb;
// Fill in the basic fields
@ -74,12 +71,17 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// Set the content-type to "text/html"
mb.constructTextPart(vmime::mediaType
(vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML));
mb.constructTextPart(
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.
// 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
// -- the image into HTML content).
@ -93,18 +95,33 @@ int main()
imageFile->getFileReader();
vmime::shared_ptr <vmime::contentHandler> imageCts =
vmime::make_shared <vmime::streamContentHandler>
(fileReader->getInputStream(), imageFile->getLength());
vmime::make_shared <vmime::streamContentHandler>(
fileReader->getInputStream(),
imageFile->getLength()
);
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj = textPart.addObject
(imageCts, vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj =
textPart.addObject(
imageCts,
vmime::mediaType(
vmime::mediaTypes::IMAGE,
vmime::mediaTypes::IMAGE_JPEG
)
);
// -- message text
textPart.setText(vmime::make_shared <vmime::stringContentHandler>
(vmime::string("This is the <b>HTML text</b>.<br/>"
"<img src=\"") + obj->getReferenceId() + vmime::string("\"/>")));
textPart.setPlainText(vmime::make_shared <vmime::stringContentHandler>
("This is the plain text (without HTML formatting)."));
textPart.setText(
vmime::make_shared <vmime::stringContentHandler>(
vmime::string("This is the <b>HTML text</b>.<br/>"
"<img src=\"") + obj->getReferenceId() + vmime::string("\"/>")
)
);
textPart.setPlainText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the plain text (without HTML formatting)."
)
);
// Construction
vmime::shared_ptr <vmime::message> msg = mb.construct();
@ -116,20 +133,21 @@ int main()
std::cout << "==================" << std::endl;
std::cout << std::endl;
std::cout << dataToSend << std::endl;
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -39,71 +39,70 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// 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.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageParser mp("<...MIME message content...>");
// 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);
// Output content-type of the part
std::cout << part.getType().generate() << std::endl;
// 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);
// HTML text is in "hp.getText()"
// Corresponding plain text is in "hp.getPlainText()"
// 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);
// Identifier (content-id or content-location) is in "obj.getId()"
// Object data is in "obj.getData()"
}
}
// text/plain
else
{
} else {
const vmime::textPart& tp = dynamic_cast<const vmime::textPart&>(part);
// Text is in "tp.getText()"
}
}
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
return 0;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -39,28 +39,25 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// 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.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageParser mp("<...MIME message content...>");
// 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);
// Media type (content type) is in "att.getType()"
@ -68,19 +65,21 @@ int main()
// Description is in "att.getDescription()"
// Data is in "att.getData()"
}
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
return 0;
}

View File

@ -1,6 +1,6 @@
//
// 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
// 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
* 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::net::serviceFactory::getInstance();
std::ostringstream res;
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);
if (serv.getType() == type)
{
if (count != 0)
if (serv.getType() == type) {
if (count != 0) {
res << ", ";
}
res << serv.getName();
++count;
@ -73,14 +74,14 @@ static const std::string findAvailableProtocols(const vmime::net::service::Type
// 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 << " what = " << e.what() << std::endl;
// 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 =
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;
}
if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e))
{
if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e)) {
const vmime::exceptions::invalid_response& ir =
dynamic_cast <const vmime::exceptions::invalid_response&>(e);
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 =
dynamic_cast <const vmime::exceptions::connection_greeting_error&>(e);
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 =
dynamic_cast <const vmime::exceptions::authentication_error&>(e);
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 =
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;
}
if (e.other() != NULL)
if (e.other()) {
os << *e.other();
}
return os;
}
@ -133,16 +135,21 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
* @param s structure object
* @param level current depth
*/
static void printStructure(vmime::shared_ptr <const vmime::net::messageStructure> s, const int level = 0)
{
for (size_t i = 0 ; i < s->getPartCount() ; ++i)
{
static void printStructure(
vmime::shared_ptr <const vmime::net::messageStructure> s,
const int level = 0
) {
for (size_t i = 0 ; i < s->getPartCount() ; ++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 << (part->getNumber() + 1) << ". "
std::cout
<< (part->getNumber() + 1) << ". "
<< part->getType().generate()
<< " [" << part->getSize() << " byte(s)]"
<< 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();
if (n.empty()) // root folder
{
if (n.empty()) { // root folder
return "/";
}
else
{
} else {
vmime::shared_ptr <vmime::net::folder> p = f->getParent();
return getFolderPathString(p) + n + "/";
}
@ -172,38 +179,43 @@ static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::fo
*
* @param folder current folder
*/
static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const int level = 0)
{
for (int j = 0 ; j < level * 2 ; ++j)
static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const int level = 0) {
for (int j = 0 ; j < level * 2 ; ++j) {
std::cout << " ";
}
const vmime::net::folderAttributes attr = folder->getAttributes();
std::ostringstream attrStr;
if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL)
if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_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";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_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";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_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";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_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";
}
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN)
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN) {
attrStr << " \\flag:HasChildren";
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN)
}
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN) {
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];
}
std::cout << getFolderPathString(folder);
std::cout << " " << attrStr.str();
@ -211,21 +223,23 @@ static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const in
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);
}
}
/** Print a menu on the standard output.
*
* @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;
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 << std::endl;
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;
if (choice < 1 || choice > choices.size())
if (choice < 1 || choice > choices.size()) {
return 0;
else
} else {
return choice;
}
}
/** Send a message interactively.
*/
static void sendMessage()
{
try
{
static void sendMessage() {
try {
// Request user to enter an URL
std::cout << "Enter an URL to connect to transport service." << 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;
if (url.getUsername().empty() || url.getPassword().empty())
if (url.getUsername().empty() || url.getPassword().empty()) {
tr = g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>());
else
} else {
tr = g_session->getTransport(url);
}
#if VMIME_HAVE_TLS_SUPPORT
@ -283,15 +299,17 @@ static void sendMessage()
// Set the object responsible for verifying certificates, in the
// case a secured connection is used (TLS/SSL)
tr->setCertificateVerifier
(vmime::make_shared <interactiveCertificateVerifier>());
tr->setCertificateVerifier(
vmime::make_shared <interactiveCertificateVerifier>()
);
#endif // VMIME_HAVE_TLS_SUPPORT
// You can also set some properties (see example7 to know the properties
// 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);
}
// Trace communication between client and server
vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
@ -307,8 +325,8 @@ static void sendMessage()
vmime::mailbox from(fromString);
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.flush();
@ -317,24 +335,26 @@ static void sendMessage()
cont = (toString.size() != 0);
if (cont)
if (cont) {
to.appendMailbox(vmime::make_shared <vmime::mailbox>(toString));
}
}
std::cout << "Enter message data, including headers (end with '.' on a single line):" << std::endl;
std::ostringstream data;
for (bool cont = true ; cont ; )
{
for (bool cont = true ; cont ; ) {
std::string line;
std::getline(std::cin, line);
if (line == ".")
if (line == ".") {
cont = false;
else
} else {
data << line << "\r\n";
}
}
// Connect to server
tr->connect();
@ -357,15 +377,15 @@ static void sendMessage()
std::cout << traceStream->str();
tr->disconnect();
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << std::endl;
std::cerr << e << std::endl;
throw;
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << std::endl;
std::cerr << "std::exception: " << e.what() << std::endl;
throw;
@ -375,10 +395,10 @@ static void sendMessage()
/** Connect to a message store interactively.
*/
static void connectStore()
{
try
{
static void connectStore() {
try {
// Request user to enter an URL
std::cout << "Enter an URL to connect to store service." << 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".
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>());
else
} else {
st = g_session->getStore(url);
}
#if VMIME_HAVE_TLS_SUPPORT
@ -411,8 +432,9 @@ static void connectStore()
// Set the object responsible for verifying certificates, in the
// case a secured connection is used (TLS/SSL)
st->setCertificateVerifier
(vmime::make_shared <interactiveCertificateVerifier>());
st->setCertificateVerifier(
vmime::make_shared <interactiveCertificateVerifier>()
);
#endif // VMIME_HAVE_TLS_SUPPORT
@ -441,13 +463,13 @@ static void connectStore()
std::cout << 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;
MessageList msgList;
try
{
try {
std::vector <std::string> choices;
choices.push_back("Show message flags");
@ -470,8 +492,8 @@ static void connectStore()
vmime::shared_ptr <vmime::net::message> msg;
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.flush();
@ -483,20 +505,20 @@ static void connectStore()
vmime::size_t num = 0;
iss >> num;
if (num < 1 || num > f->getMessageCount())
{
if (num < 1 || num > f->getMessageCount()) {
std::cerr << "Invalid message number." << std::endl;
continue;
}
MessageList::iterator it = msgList.find(num);
if (it != msgList.end())
{
if (it != msgList.end()) {
msg = (*it).second;
}
else
{
} else {
msg = f->getMessage(num);
msgList.insert(MessageList::value_type(num, msg));
}
@ -504,25 +526,31 @@ static void connectStore()
std::cout << std::endl;
}
switch (choice)
{
switch (choice) {
// Show message flags
case 1:
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;
if (msg->getFlags() & vmime::net::message::FLAG_RECENT)
}
if (msg->getFlags() & vmime::net::message::FLAG_RECENT) {
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;
if (msg->getFlags() & vmime::net::message::FLAG_DELETED)
}
if (msg->getFlags() & vmime::net::message::FLAG_DELETED) {
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;
if (msg->getFlags() & vmime::net::message::FLAG_PASSED)
}
if (msg->getFlags() & vmime::net::message::FLAG_PASSED) {
std::cout << "FLAG_PASSED" << std::endl;
}
break;
@ -541,8 +569,8 @@ static void connectStore()
break;
// Show message envelope
case 4:
{
case 4: {
vmime::net::fetchAttributes attr(vmime::net::fetchAttributes::ENVELOPE);
// If you also want to fetch "Received: " fields:
@ -555,37 +583,38 @@ static void connectStore()
break;
}
// Extract whole message
case 5:
{
case 5: {
vmime::utility::outputStreamAdapter out(std::cout);
msg->extract(out);
break;
}
// Extract attachments
case 6:
{
case 6: {
vmime::shared_ptr <vmime::message> parsedMsg = msg->getParsedMessage();
std::vector <vmime::shared_ptr <const vmime::attachment> > attchs =
vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg);
if (attchs.size() > 0)
{
if (attchs.size() > 0) {
std::cout << attchs.size() << " attachments found." << std::endl;
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;
// Get attachment size
vmime::size_t size = 0;
if (att->getData()->isEncoded())
if (att->getData()->isEncoded()) {
size = att->getData()->getEncoding().getEncoder()->getDecodedSize(att->getData()->getLength());
else
} else {
size = att->getData()->getLength();
}
std::cout << "Found attachment '" << att->getName().getBuffer() << "'"
<< ", size is " << size << " bytes:" << std::endl;
@ -618,17 +647,17 @@ static void connectStore()
att->getData()->extract(*output.get());
*/
}
}
else
{
} else {
std::cout << "No attachments found." << std::endl;
}
break;
}
// Status
case 7:
{
case 7: {
vmime::size_t count, unseen;
f->status(count, unseen);
@ -636,17 +665,16 @@ static void connectStore()
break;
}
// List folders
case 8:
{
vmime::shared_ptr <vmime::net::folder>
root = st->getRootFolder();
case 8: {
vmime::shared_ptr <vmime::net::folder> root = st->getRootFolder();
printFolders(root);
break;
}
// Change folder
case 9:
{
case 9: {
std::cout << "Enter folder path (eg. /root/subfolder):" << std::endl;
std::cout.flush();
@ -655,20 +683,22 @@ static void connectStore()
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);
const std::string x = (p == std::string::npos)
? std::string(path.begin() + s, path.end())
: std::string(path.begin() + s, path.begin() + p);
if (!x.empty())
if (!x.empty()) {
newFolder = newFolder->getFolder(vmime::utility::path::component(x));
}
if (p == std::string::npos)
if (p == std::string::npos) {
break;
}
}
newFolder->open(vmime::net::folder::MODE_READ_WRITE);
@ -683,8 +713,8 @@ static void connectStore()
break;
}
// Add message
case 10:
{
case 10: {
vmime::messageBuilder mb;
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
@ -694,32 +724,35 @@ static void connectStore()
mb.setRecipients(to);
mb.setSubject(vmime::text("Test message from VMime example6"));
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
"Body of test message from VMime example6."));
mb.getTextPart()->setText(
vmime::make_shared <vmime::stringContentHandler>(
"Body of test message from VMime example6."
)
);
vmime::shared_ptr <vmime::message> msg = mb.construct();
vmime::net::messageSet set = f->addMessage(msg);
if (set.isEmpty())
{
if (set.isEmpty()) {
std::cout << "Message has successfully been added, "
<< "but its UID/number is not known." << std::endl;
}
else
{
} else {
const vmime::net::messageRange& range = set.getRangeAt(0);
if (set.isUIDSet())
{
if (set.isUIDSet()) {
const vmime::net::message::uid uid =
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
std::cout << "Message has successfully been added, "
<< "its UID is '" << uid << "'." << std::endl;
}
else
{
} else {
const vmime::size_t number =
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
@ -731,30 +764,30 @@ static void connectStore()
break;
}
// Copy message
case 11:
{
case 11: {
vmime::net::messageSet set = f->copyMessages(f->getFullPath(),
vmime::net::messageSet::byNumber(msg->getNumber()));
if (set.isEmpty())
{
if (set.isEmpty()) {
std::cout << "Message has successfully been copied, "
<< "but its UID/number is not known." << std::endl;
}
else
{
} else {
const vmime::net::messageRange& range = set.getRangeAt(0);
if (set.isUIDSet())
{
if (set.isUIDSet()) {
const vmime::net::message::uid uid =
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
std::cout << "Message has successfully been copied, "
<< "its UID is '" << uid << "'." << std::endl;
}
else
{
} else {
const vmime::size_t number =
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"));
if (!g->exists())
if (!g->exists()) {
g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES);
}
f->copyMessages(g->getFullPath());
}
*/
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << std::endl;
std::cerr << e << std::endl;
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << std::endl;
std::cerr << "std::exception: " << e.what() << std::endl;
}
} // for(cont)
st->disconnect();
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << std::endl;
std::cerr << e << std::endl;
throw;
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << std::endl;
std::cerr << "std::exception: " << e.what() << std::endl;
throw;
@ -848,16 +883,16 @@ static void connectStore()
*
* @return true to quit the program, false to continue
*/
static bool menu()
{
static bool menu() {
std::vector <std::string> items;
items.push_back("Connect to a message store");
items.push_back("Send a message");
items.push_back("Quit");
switch (printMenu(items))
{
switch (printMenu(items)) {
// Connect to store
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.
// The locale should use UTF-8 encoding for these tests to run successfully.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
for (bool quit = false ; !quit ; )
{
for (bool quit = false ; !quit ; ) {
// Loop on main menu
quit = menu();
}
return 0;
}

View File

@ -3,52 +3,57 @@
#if VMIME_HAVE_SASL_SUPPORT
// SASL authentication handler
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> >& available,
vmime::shared_ptr <vmime::security::sasl::SASLMechanism> suggested) const
{
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> >& available,
const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& suggested
) const {
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();
if (suggested && available[i]->getName() == suggested->getName())
if (suggested && available[i]->getName() == suggested->getName()) {
std::cout << "(suggested)";
}
}
std::cout << std::endl << std::endl;
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;
defaultSASLAuthenticator::setSASLMechanism(mech);
}
const vmime::string getUsername() const
{
if (m_username.empty())
const vmime::string getUsername() const {
if (m_username.empty()) {
m_username = getUserInput("Username");
}
return m_username;
}
const vmime::string getPassword() const
{
if (m_password.empty())
const vmime::string getPassword() const {
if (m_password.empty()) {
m_password = getUserInput("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.flush();
@ -67,26 +72,28 @@ private:
#else // !VMIME_HAVE_SASL_SUPPORT
// Simple authentication handler
class interactiveAuthenticator : public vmime::security::defaultAuthenticator
{
const vmime::string getUsername() const
{
if (m_username.empty())
class interactiveAuthenticator : public vmime::security::defaultAuthenticator {
const vmime::string getUsername() const {
if (m_username.empty()) {
m_username = getUserInput("Username");
}
return m_username;
}
const vmime::string getPassword() const
{
if (m_password.empty())
const vmime::string getPassword() const {
if (m_password.empty()) {
m_password = getUserInput("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.flush();
@ -103,4 +110,3 @@ private:
};
#endif // VMIME_HAVE_SASL_SUPPORT

View File

@ -3,20 +3,23 @@
#if VMIME_HAVE_TLS_SUPPORT
// Certificate verifier (TLS/SSL)
class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier
{
class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier {
public:
void verify(vmime::shared_ptr <vmime::security::cert::certificateChain> chain, const vmime::string& hostname)
{
try
{
void verify(
const vmime::shared_ptr <vmime::security::cert::certificateChain>& chain,
const vmime::string& hostname
) {
try {
setX509TrustedCerts(m_trustedCerts);
defaultCertificateVerifier::verify(chain, hostname);
}
catch (vmime::security::cert::certificateException&)
{
} catch (vmime::security::cert::certificateException&) {
// Obtain subject's certificate
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
@ -29,13 +32,14 @@ public:
std::getline(std::cin, answer);
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
if (cert->getType() == "X.509")
{
m_trustedCerts.push_back(vmime::dynamicCast
<vmime::security::cert::X509Certificate>(cert));
if (cert->getType() == "X.509") {
m_trustedCerts.push_back(
vmime::dynamicCast <vmime::security::cert::X509Certificate>(cert)
);
setX509TrustedCerts(m_trustedCerts);
defaultCertificateVerifier::verify(chain, hostname);
@ -44,8 +48,7 @@ public:
return;
}
throw vmime::security::cert::certificateException
("User did not accept the certificate.");
throw vmime::security::cert::certificateException("User did not accept the certificate.");
}
}
@ -59,4 +62,3 @@ std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> >
interactiveCertificateVerifier::m_trustedCerts;
#endif // VMIME_HAVE_TLS_SUPPORT

View File

@ -5,17 +5,17 @@
* Used to stop the current operation after too much time, or if the user
* requested cancellation.
*/
class timeoutHandler : public vmime::net::timeoutHandler
{
class timeoutHandler : public vmime::net::timeoutHandler {
public:
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
// the current operation. If you return true, handleTimeOut() will
// be called just after this, and before actually cancelling the
@ -25,15 +25,15 @@ public:
return (time(NULL) - m_start) >= 10; // seconds
}
void resetTimeOut()
{
void resetTimeOut() {
// Called at the beginning of an operation (eg. connecting,
// a read() or a write() on a socket...)
m_start = time(NULL);
}
bool handleTimeOut()
{
bool handleTimeOut() {
// If isTimeOut() returned true, this function will be called. This
// allows you to interact with the user, ie. display a prompt to
// 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:
vmime::shared_ptr <vmime::net::timeoutHandler> create()
{
vmime::shared_ptr <vmime::net::timeoutHandler> create() {
return vmime::make_shared <timeoutHandler>();
}
};

View File

@ -1,25 +1,29 @@
/** Tracer used to demonstrate logging communication between client and server.
*/
class myTracer : public vmime::net::tracer {
class myTracer : public vmime::net::tracer
{
public:
myTracer(vmime::shared_ptr <std::ostringstream> stream,
vmime::shared_ptr <vmime::net::service> serv, const int connectionId)
: m_stream(stream), m_service(serv), m_connectionId(connectionId)
{
myTracer(
const vmime::shared_ptr <std::ostringstream>& stream,
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
<< "] C: " << line << std::endl;
}
void traceReceive(const vmime::string& line)
{
void traceReceive(const vmime::string& line) {
*m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId
<< "] S: " << line << std::endl;
}
@ -31,18 +35,21 @@ private:
const int m_connectionId;
};
class myTracerFactory : public vmime::net::tracerFactory
{
class myTracerFactory : public vmime::net::tracerFactory {
public:
myTracerFactory(vmime::shared_ptr <std::ostringstream> stream)
: m_stream(stream)
{
myTracerFactory(const vmime::shared_ptr <std::ostringstream>& stream)
: m_stream(stream) {
}
vmime::shared_ptr <vmime::net::tracer> create
(vmime::shared_ptr <vmime::net::service> serv, const int connectionId)
{
vmime::shared_ptr <vmime::net::tracer> create(
const vmime::shared_ptr <vmime::net::service>& serv,
const int connectionId
) {
return vmime::make_shared <myTracer>(m_stream, serv, connectionId);
}
@ -50,4 +57,3 @@ private:
vmime::shared_ptr <std::ostringstream> m_stream;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -39,16 +39,16 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
// Enumerate encoders
vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
vmime::utility::encoder::encoderFactory::getInstance();
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>
enc = ef->getEncoderAt(i);
@ -59,9 +59,10 @@ int main()
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 << std::endl;
@ -71,8 +72,8 @@ int main()
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);
std::cout << " * " << serv.getName() << std::endl;
@ -81,16 +82,15 @@ int main()
serv.getInfos().getAvailableProperties();
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::string name = serv.getInfos().getPropertyPrefix() + p.getName();
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_STRING: type = "TYPE_STRING"; break;
case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break;
@ -99,10 +99,12 @@ int main()
vmime::string flags;
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED)
if (p.getFlags() & vmime::net::serviceInfos::property::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";
}
std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName();
std::cout << " (type=" << type << ", flags=" << flags;
@ -111,5 +113,6 @@ int main()
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// 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
// 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;
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();
for (int i = 0 ; i < children.size() ; ++i)
{
for (int i = 0 ; i < children.size() ; ++i) {
insertRowInModel(model, children[i], &iter);
}
}
void updateTreeView()
{
void updateTreeView() {
GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));
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;
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();
}
void openFile(const std::string& filename)
{
void openFile(const std::string& filename) {
std::ifstream file;
file.open(filename.c_str(), std::ios::in | std::ios::binary);
if (!file)
{
if (!file) {
std::cerr << "Can't open file '" << filename << "'." << std::endl;
return;
}
@ -132,12 +134,10 @@ void openFile(const std::string& filename)
vmime::string data;
char buffer[16384];
do
{
do {
file.read(buffer, sizeof(buffer));
data += vmime::string(buffer, file.gcount());
}
while (file.gcount());
} while (file.gcount());
vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
msg->parse(data);
@ -147,13 +147,13 @@ void openFile(const std::string& filename)
char* convData = g_convert_with_fallback(data.c_str(), data.length(),
"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)),
"GLib UTF-8 conversion error.", -1);
}
else
{
} else {
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)),
convData, strlen(convData));
@ -164,16 +164,19 @@ void openFile(const std::string& filename)
}
static void onFileOpen()
{
GtkWidget* dlg = gtk_file_chooser_dialog_new
("Open Message File", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
static void onFileOpen() {
GtkWidget* dlg = gtk_file_chooser_dialog_new(
"Open Message File",
GTK_WINDOW(window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
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));
openFile(filename);
@ -187,8 +190,7 @@ static void onFileOpen()
// UI definitions
static const GtkActionEntry uiActions[] =
{
static const GtkActionEntry uiActions[] = {
{ "FileMenu", NULL, "_File" },
{ "FileOpen", GTK_STOCK_OPEN, "_Open...", "<control>O", NULL, G_CALLBACK(onFileOpen) },
{ "FileExit", GTK_STOCK_QUIT, "_Exit", "<control>Q", NULL, G_CALLBACK(gtk_main_quit) }
@ -205,8 +207,8 @@ static const char* uiDefinition =
"</ui>";
int main(int argc, char* argv[])
{
int main(int argc, char* argv[]) {
// VMime initialization
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
@ -290,5 +292,3 @@ int main(int argc, char* argv[])
return 0;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -29,12 +29,11 @@
#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
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition, bool *isLastAddressOfGroup)
{
shared_ptr <address> address::parseNext(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition,
bool *isLastAddressOfGroup
) {
bool escaped = false;
bool quoted = false;
bool quotedRFC2047 = false;
@ -78,36 +82,45 @@ shared_ptr <address> address::parseNext
bool stop = false;
int commentLevel = 0;
if (isLastAddressOfGroup)
if (isLastAddressOfGroup) {
*isLastAddressOfGroup = false;
}
size_t pos = position;
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
const size_t start = pos;
while (!stop && pos < end)
{
if (escaped)
{
while (!stop && pos < end) {
if (escaped) {
escaped = false;
}
else
{
switch (buffer[pos])
{
} else {
switch (buffer[pos]) {
case '\\':
escaped = true;
break;
case '"':
quoted = !quoted;
break;
case '<':
inRouteAddr = true;
break;
case '>':
inRouteAddr = false;
break;
@ -118,15 +131,15 @@ shared_ptr <address> address::parseNext
case ')':
if (commentLevel > 0)
if (commentLevel > 0) {
--commentLevel;
}
break;
case '=':
if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?')
{
if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?') {
++pos;
quotedRFC2047 = true;
}
@ -135,8 +148,7 @@ shared_ptr <address> address::parseNext
case '?':
if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=')
{
if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=') {
++pos;
quotedRFC2047 = false;
}
@ -145,20 +157,22 @@ shared_ptr <address> address::parseNext
default:
{
if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr)
{
switch (buffer[pos])
{
if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr) {
switch (buffer[pos]) {
case ';':
if (isGroup)
{
if (pos + 1 < end && buffer[pos + 1] == ',')
if (isGroup) {
if (pos + 1 < end && buffer[pos + 1] == ',') {
++pos;
}
}
if (isLastAddressOfGroup)
if (isLastAddressOfGroup) {
*isLastAddressOfGroup = true;
}
stop = true;
break;
@ -170,7 +184,10 @@ shared_ptr <address> address::parseNext
case ',':
if (!isGroup) stop = true;
if (!isGroup) {
stop = true;
}
break;
}
}
@ -181,32 +198,35 @@ shared_ptr <address> address::parseNext
}
}
if (!stop)
if (!stop) {
++pos;
}
}
if (newPosition)
{
if (pos == end)
if (newPosition) {
if (pos == end) {
*newPosition = end;
else
} else {
*newPosition = pos + 1; // ',' or ';'
}
}
// Parse extracted address (mailbox or group)
if (pos != start)
{
if (pos != start) {
shared_ptr <address> parsedAddress;
if (isGroup)
if (isGroup) {
parsedAddress = make_shared <mailboxGroup>();
else
} else {
parsedAddress = make_shared <mailbox>();
}
parsedAddress->parse(ctx, buffer, start, pos, NULL);
parsedAddress->setParsedBounds(start, pos);
return (parsedAddress);
return parsedAddress;
}
return null;

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -29,8 +29,7 @@
#include "vmime/headerFieldValue.hpp"
namespace vmime
{
namespace vmime {
/** 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
* and mailboxGroup classes.
*/
class VMIME_EXPORT address : public headerFieldValue {
class VMIME_EXPORT address : public headerFieldValue
{
protected:
address();
@ -74,10 +72,14 @@ public:
* 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
*/
static shared_ptr <address> parseNext
(const parsingContext& ctx, const string& buffer,
const size_t position, const size_t end,
size_t* newPosition, bool *isLastAddressOfGroup);
static shared_ptr <address> parseNext(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition,
bool *isLastAddressOfGroup
);
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -28,181 +28,204 @@
#include "vmime/mailboxGroup.hpp"
namespace vmime
{
namespace vmime {
addressList::addressList()
{
addressList::addressList() {
}
addressList::addressList(const addressList& addrList)
: headerFieldValue()
{
: headerFieldValue() {
copyFrom(addrList);
}
addressList::~addressList()
{
addressList::~addressList() {
removeAllAddresses();
}
void addressList::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void addressList::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
removeAllAddresses();
size_t pos = position;
while (pos < end)
{
while (pos < end) {
shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL);
if (parsedAddress != NULL)
if (parsedAddress) {
m_list.push_back(parsedAddress);
}
}
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void addressList::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void addressList::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
size_t pos = curLinePos;
generationContext tmpCtx(ctx);
tmpCtx.setMaxLineLength(tmpCtx.getMaxLineLength() - 2);
if (!m_list.empty())
{
for (std::vector <shared_ptr <address> >::const_iterator i = m_list.begin() ; ; )
{
if (!m_list.empty()) {
for (std::vector <shared_ptr <address> >::const_iterator i = m_list.begin() ; ; ) {
(*i)->generate(ctx, os, pos, &pos);
if (++i == m_list.end())
if (++i == m_list.end()) {
break;
}
os << ", ";
pos += 2;
}
}
if (newLinePos)
if (newLinePos) {
*newLinePos = pos;
}
}
void addressList::copyFrom(const component& other)
{
void addressList::copyFrom(const component& other) {
const addressList& addrList = dynamic_cast <const addressList&>(other);
removeAllAddresses();
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));
}
}
addressList& addressList::operator=(const addressList& other)
{
addressList& addressList::operator=(const addressList& other) {
copyFrom(other);
return (*this);
return *this;
}
addressList& addressList::operator=(const mailboxList& other)
{
addressList& addressList::operator=(const mailboxList& other) {
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()));
}
return (*this);
return *this;
}
shared_ptr <component> addressList::clone() const
{
shared_ptr <component> addressList::clone() const {
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);
}
void addressList::insertAddressBefore(shared_ptr <address> beforeAddress, shared_ptr <address> addr)
{
const std::vector <shared_ptr <address> >::iterator it = std::find
(m_list.begin(), m_list.end(), beforeAddress);
void addressList::insertAddressBefore(const shared_ptr <address>& beforeAddress, const shared_ptr <address>& addr) {
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");
}
m_list.insert(it, addr);
}
void addressList::insertAddressBefore(const size_t pos, shared_ptr <address> addr)
{
if (pos >= m_list.size())
void addressList::insertAddressBefore(const size_t pos, const shared_ptr <address>& addr) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(m_list.begin() + pos, addr);
}
void addressList::insertAddressAfter(shared_ptr <address> afterAddress, shared_ptr <address> addr)
{
const std::vector <shared_ptr <address> >::iterator it = std::find
(m_list.begin(), m_list.end(), afterAddress);
void addressList::insertAddressAfter(
const shared_ptr <address>& afterAddress,
const shared_ptr <address>& addr
) {
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");
}
m_list.insert(it + 1, addr);
}
void addressList::insertAddressAfter(const size_t pos, shared_ptr <address> addr)
{
if (pos >= m_list.size())
void addressList::insertAddressAfter(const size_t pos, const shared_ptr <address>& addr) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(m_list.begin() + pos + 1, addr);
}
void addressList::removeAddress(shared_ptr <address> addr)
{
const std::vector <shared_ptr <address> >::iterator it = std::find
(m_list.begin(), m_list.end(), addr);
void addressList::removeAddress(const shared_ptr <address>& 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");
}
m_list.erase(it);
}
void addressList::removeAddress(const size_t pos)
{
if (pos >= m_list.size())
void addressList::removeAddress(const size_t pos) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
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();
}
size_t addressList::getAddressCount() const
{
return (m_list.size());
size_t addressList::getAddressCount() const {
return m_list.size();
}
bool addressList::isEmpty() const
{
return (m_list.empty());
bool addressList::isEmpty() const {
return m_list.empty();
}
shared_ptr <address> addressList::getAddressAt(const size_t pos)
{
return (m_list[pos]);
shared_ptr <address> addressList::getAddressAt(const size_t pos) {
return m_list[pos];
}
const shared_ptr <const address> addressList::getAddressAt(const size_t pos) const
{
return (m_list[pos]);
const shared_ptr <const address> addressList::getAddressAt(const size_t pos) const {
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;
list.reserve(m_list.size());
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);
}
return (list);
return list;
}
const std::vector <shared_ptr <address> > addressList::getAddressList()
{
return (m_list);
const std::vector <shared_ptr <address> > addressList::getAddressList() {
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;
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>();
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;
if (addr->isGroup())
{
if (addr->isGroup()) {
const std::vector <shared_ptr <const mailbox> > mailboxes =
dynamicCast <const mailboxGroup>(addr)->getMailboxList();
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));
}
}
else
{
} else {
res->appendMailbox(dynamicCast <mailbox>(addr->clone()));
}
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -31,8 +31,7 @@
#include "vmime/address.hpp"
namespace vmime
{
namespace vmime {
class mailboxList;
@ -40,9 +39,8 @@ class mailboxList;
/** A list of addresses.
*/
class VMIME_EXPORT addressList : public headerFieldValue {
class VMIME_EXPORT addressList : public headerFieldValue
{
public:
addressList();
@ -63,7 +61,7 @@ public:
*
* @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.
*
@ -71,7 +69,10 @@ public:
* @param addr address to insert
* @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.
*
@ -80,7 +81,7 @@ public:
* @param addr address to insert
* @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.
*
@ -88,7 +89,10 @@ public:
* @param addr address to insert
* @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.
*
@ -96,14 +100,14 @@ public:
* @param addr address to insert
* @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.
*
* @param addr address to remove
* @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.
*
@ -171,18 +175,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,15 +34,13 @@
#include "vmime/encoding.hpp"
namespace vmime
{
namespace vmime {
/** Base class for all types of attachment.
*/
class VMIME_EXPORT attachment : public object {
class VMIME_EXPORT attachment : public object
{
friend class messageBuilder;
friend class messageParser;
friend class attachmentHelper;
@ -108,7 +106,7 @@ protected:
*
* @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;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -33,36 +33,39 @@
#include <iterator>
namespace vmime
{
namespace vmime {
// static
bool attachmentHelper::isBodyPartAnAttachment
(shared_ptr <const bodyPart> part, const unsigned int options)
{
bool attachmentHelper::isBodyPartAnAttachment(
const shared_ptr <const bodyPart>& part,
const unsigned int options
) {
// First, try with "Content-Disposition" field.
// If not present, we will try with "Content-Type" field.
shared_ptr <const contentDispositionField> cdf =
part->getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
if (cdf)
{
if (cdf) {
const contentDisposition disp = *cdf->getValue <contentDisposition>();
if (disp.getName() != contentDispositionTypes::INLINE)
if (disp.getName() != contentDispositionTypes::INLINE) {
return true;
}
if ((options & INLINE_OBJECTS) == 0) {
if ((options & INLINE_OBJECTS) == 0)
{
// If the Content-Disposition is 'inline' and there is no
// Content-Id or Content-Location field, it may be an attachment
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 (part->getParentPart() == NULL)
if (!part->getParentPart()) {
return false;
}
return true;
}
@ -78,41 +81,47 @@ bool attachmentHelper::isBodyPartAnAttachment
shared_ptr <const contentTypeField> ctf =
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
if (ctf)
{
if (ctf) {
type = *ctf->getValue <mediaType>();
if (ctf->hasParameter("name"))
if (ctf->hasParameter("name")) {
hasContentTypeName = true;
}
else
{
} else {
// 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
// an attachment
if (part->getParentPart() == NULL)
if (!part->getParentPart()) {
return false;
}
// No "Content-type" field: assume "application/octet-stream".
type = mediaType(mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM);
type = mediaType(
mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM
);
}
if (type.getType() != mediaTypes::TEXT &&
type.getType() != mediaTypes::MULTIPART)
{
type.getType() != mediaTypes::MULTIPART) {
// Compatibility with (obsolete) RFC-1341: if there is a "name" parameter
// on the "Content-Type" field, then we assume it is an attachment
if (hasContentTypeName)
if (hasContentTypeName) {
return true;
}
if ((options & INLINE_OBJECTS) == 0) {
if ((options & INLINE_OBJECTS) == 0)
{
// If a "Content-Id" field is present, it might be an
// embedded object (MHTML messages)
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID))
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID)) {
return false;
}
}
return true;
}
@ -122,35 +131,40 @@ bool attachmentHelper::isBodyPartAnAttachment
// static
shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment
(shared_ptr <const bodyPart> part, const unsigned int options)
{
if (!isBodyPartAnAttachment(part, options))
shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment(
const shared_ptr <const bodyPart>& part,
const unsigned int options
) {
if (!isBodyPartAnAttachment(part, options)) {
return null;
}
mediaType type;
shared_ptr <const contentTypeField> ctf =
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
if (ctf)
{
if (ctf) {
type = *ctf->getValue <mediaType>();
}
else
{
} else {
// No "Content-type" field: assume "application/octet-stream".
type = mediaType(mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM);
type = mediaType(
mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM
);
}
if (type.getType() == mediaTypes::MESSAGE &&
type.getSubType() == mediaTypes::MESSAGE_RFC822)
{
type.getSubType() == mediaTypes::MESSAGE_RFC822) {
return make_shared <generatedMessageAttachment>(part);
}
else
{
} else {
return make_shared <bodyPartAttachment>(part);
}
}
@ -158,32 +172,36 @@ shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment
// static
const std::vector <shared_ptr <const attachment> >
attachmentHelper::findAttachmentsInMessage
(shared_ptr <const message> msg, const unsigned int options)
{
attachmentHelper::findAttachmentsInMessage(
const shared_ptr <const message>& msg,
const unsigned int options
) {
return findAttachmentsInBodyPart(msg, options);
}
// static
const std::vector <shared_ptr <const attachment> >
attachmentHelper::findAttachmentsInBodyPart
(shared_ptr <const bodyPart> part, const unsigned int options)
{
attachmentHelper::findAttachmentsInBodyPart(
const shared_ptr <const bodyPart>& part,
const unsigned int options
) {
std::vector <shared_ptr <const attachment> > atts;
// Test this part
if (isBodyPartAnAttachment(part, options))
{
if (isBodyPartAnAttachment(part, options)) {
atts.push_back(getBodyPartAttachment(part, options));
}
// Find in sub-parts
else
{
} else {
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 =
findAttachmentsInBodyPart(bdy->getPartAt(i), options);
@ -196,35 +214,39 @@ const std::vector <shared_ptr <const attachment> >
// 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,
// create it in the root part. This (very simple) algorithm should
// work in the most cases.
vmime::mediaType mpMixed(vmime::mediaTypes::MULTIPART,
vmime::mediaTypes::MULTIPART_MIXED);
vmime::mediaType mpMixed(
vmime::mediaTypes::MULTIPART,
vmime::mediaTypes::MULTIPART_MIXED
);
shared_ptr <bodyPart> part = findBodyPart(msg, mpMixed);
if (part == NULL) // create it
{
if (msg->getBody()->getPartCount() != 0)
{
if (!part) { // create it
if (msg->getBody()->getPartCount() != 0) {
// Create a new container part for the parts that were in
// the root part of the message
shared_ptr <bodyPart> container = make_shared <bodyPart>();
if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
{
container->getHeader()->ContentType()->setValue
(msg->getHeader()->ContentType()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) {
container->getHeader()->ContentType()->setValue(
msg->getHeader()->ContentType()->getValue()
);
}
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
{
container->getHeader()->ContentTransferEncoding()->setValue
(msg->getHeader()->ContentTransferEncoding()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) {
container->getHeader()->ContentTransferEncoding()->setValue(
msg->getHeader()->ContentTransferEncoding()->getValue()
);
}
// 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();
for (unsigned int i = 0 ; i < partList.size() ; ++i)
for (unsigned int i = 0 ; i < partList.size() ; ++i) {
container->getBody()->appendPart(partList[i]);
}
msg->getBody()->appendPart(container);
}
else
{
} else {
// The message is a simple (RFC-822) message, and do not
// contains any MIME part. Move the contents from the
// root to a new child part.
shared_ptr <bodyPart> child = make_shared <bodyPart>();
if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
{
child->getHeader()->ContentType()->setValue
(msg->getHeader()->ContentType()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) {
child->getHeader()->ContentType()->setValue(
msg->getHeader()->ContentType()->getValue()
);
}
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
{
child->getHeader()->ContentTransferEncoding()->setValue
(msg->getHeader()->ContentTransferEncoding()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) {
child->getHeader()->ContentTransferEncoding()->setValue(
msg->getHeader()->ContentTransferEncoding()->getValue()
);
}
child->getBody()->setContents(msg->getBody()->getContents());
@ -278,35 +303,37 @@ void attachmentHelper::addAttachment(shared_ptr <message> msg, shared_ptr <attac
// static
shared_ptr <bodyPart> attachmentHelper::findBodyPart
(shared_ptr <bodyPart> part, const mediaType& type)
{
if (part->getBody()->getContentType() == type)
shared_ptr <bodyPart> attachmentHelper::findBodyPart(
const shared_ptr <bodyPart>& part,
const mediaType& type
) {
if (part->getBody()->getContentType() == type) {
return part;
}
// Try in sub-parts
shared_ptr <body> bdy = part->getBody();
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i)
{
shared_ptr <bodyPart> found =
findBodyPart(bdy->getPartAt(i), type);
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) {
if (found != NULL)
shared_ptr <bodyPart> found = findBodyPart(bdy->getPartAt(i), type);
if (found) {
return found;
}
}
return null;
}
// 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);
addAttachment(msg, att);
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -31,14 +31,13 @@
#include "vmime/message.hpp"
namespace vmime
{
namespace vmime {
/** Retrieve attachment information from message parts.
*/
class VMIME_EXPORT attachmentHelper
{
class VMIME_EXPORT attachmentHelper {
public:
/** Options for use with the following functions:
@ -46,8 +45,7 @@ public:
* getBodyPartAttachment,
* and isBodyPartAnAttachment.
*/
enum FindOptions
{
enum FindOptions {
INLINE_OBJECTS = (1 << 0) /**< Recognize and return inline objects. The aim is to
consider MHTML objects (parts with a "Content-Id" or
a "Content-Location", such as inline images) as attachments. */
@ -59,7 +57,10 @@ public:
* @param options search options (see FindOptions)
* @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.
* If the specified body part does not contain attachment
@ -69,8 +70,10 @@ public:
* @param options search options (see FindOptions)
* @return attachment found in the part, or NULL
*/
static shared_ptr <const attachment>
getBodyPartAttachment(shared_ptr <const bodyPart> part, const unsigned int options = 0);
static shared_ptr <const attachment> getBodyPartAttachment(
const shared_ptr <const bodyPart>& part,
const unsigned int options = 0
);
/** Find all attachments contained in the specified part
* and all its children parts.
@ -81,7 +84,10 @@ public:
* @return a list of attachments found
*/
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.
* This is simply a recursive call to getBodyPartAttachment().
@ -91,26 +97,37 @@ public:
* @return a list of attachments found
*/
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.
*
* @param msg message into which to add the attachment
* @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.
*
* @param msg message into which to add the attachment
* @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:
static shared_ptr <bodyPart> findBodyPart
(shared_ptr <bodyPart> part, const mediaType& type);
static shared_ptr <bodyPart> findBodyPart(
const shared_ptr <bodyPart>& part,
const mediaType& type
);
};
@ -118,4 +135,3 @@ protected:
#endif // VMIME_ATTACHMENTHELPER_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -48,8 +48,7 @@
#endif
namespace vmime
{
namespace vmime {
/** "Null" (empty) string.
@ -108,8 +107,8 @@ nullPtrType null;
// Line length limits
namespace lineLengthLimits
{
namespace lineLengthLimits {
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).
//
class initializer
{
public:
struct initializer {
initializer() {
initializer()
{
parsingContext::getDefaultContext();
generationContext::getDefaultContext();

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -37,8 +37,8 @@
#include "vmime/constants.hpp"
namespace vmime
{
namespace vmime {
class text;
class word;
class charset;
@ -53,8 +53,8 @@ namespace vmime
#ifndef VMIME_BUILDING_DOC
// Null pointer
struct nullPtrType
{
struct nullPtrType {
template <typename T>
operator shared_ptr <T>() { return shared_ptr <T>(); }
};
@ -78,48 +78,49 @@ namespace vmime
//
template <typename T, size_t N>
inline T const* cbegin(T const (&array)[N])
{
return (array);
inline T const* cbegin(T const (&array)[N]) {
return array;
}
template <typename T, size_t N>
inline T const* cend(T const (&array)[N])
{
return (array + N);
inline T const* cend(T const (&array)[N]) {
return array + N;
}
template <typename T, size_t N>
inline T* begin(T (&array)[N])
{
return (array);
inline T* begin(T (&array)[N]) {
return array;
}
template <typename T, size_t N>
inline T* end(T (&array)[N])
{
return (array + N);
inline T* end(T (&array)[N]) {
return array + N;
}
template <typename T, size_t N>
inline size_t count(T const (&/* array */)[N])
{
return (N);
inline size_t count(T const (&/* array */)[N]) {
return N;
}
// Copy one vector to another, with type conversion
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();
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];
}
}
/*
@ -154,12 +155,11 @@ namespace vmime
character limit) for the sake of robustness.
*/
namespace lineLengthLimits
{
namespace lineLengthLimits {
extern VMIME_EXPORT const size_t infinite;
enum
{
enum {
max = 998,
convenient = 78
};
@ -192,8 +192,8 @@ namespace vmime
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
*/
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());
}
@ -201,8 +201,8 @@ namespace vmime
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
*/
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());
}
@ -210,8 +210,8 @@ namespace vmime
* This is an alias for dynamic_pointer_cast <T>(obj.clone()).
*/
template <class T>
shared_ptr <T> clone(const T& obj)
{
shared_ptr <T> clone(const T& obj) {
return dynamic_pointer_cast <T>(obj.clone());
}
@ -220,24 +220,24 @@ namespace vmime
* type Type, and DerivedType is derived from Type.
*/
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);
}
/** Const cast helper.
*/
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);
}
/** Inherit from this class to indicate the subclass is not copyable,
* ie. you want to prohibit copy construction and copy assignment.
*/
class VMIME_EXPORT noncopyable
{
class VMIME_EXPORT noncopyable {
protected:
noncopyable() { }

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -37,8 +37,7 @@
#include "vmime/contentHandler.hpp"
namespace vmime
{
namespace vmime {
class bodyPart;
@ -46,9 +45,8 @@ class bodyPart;
/** Body section of a MIME part.
*/
class VMIME_EXPORT body : public component {
class VMIME_EXPORT body : public component
{
friend class bodyPart;
public:
@ -60,7 +58,7 @@ public:
*
* @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.
*
@ -68,7 +66,10 @@ public:
* @param part part to insert
* @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.
*
@ -76,7 +77,7 @@ public:
* the beginning of the list)
* @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.
*
@ -84,21 +85,24 @@ public:
* @param part part to insert
* @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.
*
* @param pos position of the part before the new part
* @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.
*
* @param part part to remove
* @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.
*
@ -182,14 +186,17 @@ public:
*
* @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.
*
* @param contents new body 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.
*
@ -197,7 +204,11 @@ public:
* @param type type 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.
*
@ -206,8 +217,12 @@ public:
* @param chset charset of contents
* @param enc contents encoding
*/
void setContents(shared_ptr <const contentHandler> contents, const mediaType& type,
const charset& chset, const encoding& enc);
void setContents(
const shared_ptr <const contentHandler>& contents,
const mediaType& type,
const charset& chset,
const encoding& enc
);
/** Set the MIME type and charset of contents.
* If a charset is defined, it will not be modified.
@ -301,7 +316,7 @@ private:
bool isRootPart() const;
void initNewPart(shared_ptr <bodyPart> part);
void initNewPart(const shared_ptr <bodyPart>& part);
protected:
@ -317,24 +332,30 @@ protected:
* before the CRLF or "--" which follows)
* @return the position of the boundary string, or npos if not found
*/
size_t findNextBoundaryPosition
(shared_ptr <utility::parserInputStreamAdapter> parser, const string& boundary,
const size_t position, const size_t end,
size_t* boundaryStart, size_t* boundaryEnd);
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
shared_ptr <utility::parserInputStreamAdapter> parser,
size_t findNextBoundaryPosition(
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const string& boundary,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* boundaryStart,
size_t* boundaryEnd
);
void generateImpl
(const generationContext& ctx,
// Component parsing & assembling
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,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -24,23 +24,26 @@
#include "vmime/bodyPart.hpp"
namespace vmime
{
namespace vmime {
bodyPart::bodyPart()
: m_header(make_shared <header>()),
m_body(make_shared <body>()),
m_parent()
{
m_parent() {
m_body->setParentPart(this);
}
void bodyPart::parseImpl
(const parsingContext& ctx, shared_ptr <utility::parserInputStreamAdapter> parser,
const size_t position, const size_t end, size_t* newPosition)
{
void bodyPart::parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition
) {
// Parse the headers
size_t pos = position;
m_header->parse(ctx, parser, pos, end, &pos);
@ -50,34 +53,39 @@ void bodyPart::parseImpl
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void bodyPart::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t /* curLinePos */, size_t* newLinePos) const
{
void bodyPart::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t /* curLinePos */,
size_t* newLinePos
) const {
m_header->generate(ctx, os);
os << CRLF;
m_body->generate(ctx, os);
if (newLinePos)
if (newLinePos) {
*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);
}
shared_ptr <component> bodyPart::clone() const
{
shared_ptr <component> bodyPart::clone() const {
shared_ptr <bodyPart> p = make_shared <bodyPart>();
p->m_parent = NULL;
@ -85,12 +93,12 @@ shared_ptr <component> bodyPart::clone() const
p->m_header->copyFrom(*m_header);
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);
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);
return (*this);
return *this;
}
const shared_ptr <const header> bodyPart::getHeader() const
{
return (m_header);
const shared_ptr <const header> bodyPart::getHeader() const {
return m_header;
}
shared_ptr <header> bodyPart::getHeader()
{
return (m_header);
shared_ptr <header> bodyPart::getHeader() {
return m_header;
}
void bodyPart::setHeader(shared_ptr <header> h)
{
void bodyPart::setHeader(const shared_ptr <header>& h) {
m_header = h;
}
const shared_ptr <const body> bodyPart::getBody() const
{
return (m_body);
const shared_ptr <const body> bodyPart::getBody() const {
return m_body;
}
shared_ptr <body> bodyPart::getBody()
{
return (m_body);
shared_ptr <body> bodyPart::getBody() {
return m_body;
}
void bodyPart::setBody(shared_ptr <body> b)
{
void bodyPart::setBody(const shared_ptr <body>& b) {
bodyPart* oldPart = b->m_part;
m_body = b;
m_body->setParentPart(this);
// A body is associated to one and only one part
if (oldPart != NULL)
if (oldPart) {
oldPart->setBody(make_shared <body>());
}
}
bodyPart* bodyPart::getParentPart()
{
bodyPart* bodyPart::getParentPart() {
return m_parent;
}
const bodyPart* bodyPart::getParentPart() const
{
const bodyPart* bodyPart::getParentPart() const {
return m_parent;
}
shared_ptr <bodyPart> bodyPart::createChildPart()
{
shared_ptr <bodyPart> bodyPart::createChildPart() {
shared_ptr <bodyPart> part = make_shared <bodyPart>();
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;
}
const std::vector <shared_ptr <component> > bodyPart::getChildComponents()
{
const std::vector <shared_ptr <component> > bodyPart::getChildComponents() {
std::vector <shared_ptr <component> > list;
list.push_back(m_header);
list.push_back(m_body);
return (list);
return list;
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -32,15 +32,13 @@
#include "vmime/body.hpp"
namespace vmime
{
namespace vmime {
/** A MIME part.
*/
class VMIME_EXPORT bodyPart : public component {
class VMIME_EXPORT bodyPart : public component
{
friend class body;
public:
@ -63,7 +61,7 @@ public:
*
* @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.
*
@ -81,7 +79,7 @@ public:
*
* @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.
*
@ -131,21 +129,23 @@ protected:
*
* @param part child part to attach
*/
void importChildPart(shared_ptr <bodyPart> part);
void importChildPart(const shared_ptr <bodyPart>& part);
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
shared_ptr <utility::parserInputStreamAdapter> parser,
void parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -24,75 +24,77 @@
#include "vmime/bodyPartAttachment.hpp"
namespace vmime
{
namespace vmime {
bodyPartAttachment::bodyPartAttachment(shared_ptr <const bodyPart> part)
: m_part(part)
{
bodyPartAttachment::bodyPartAttachment(const shared_ptr <const bodyPart>& part)
: m_part(part) {
}
const mediaType bodyPartAttachment::getType() const
{
const mediaType bodyPartAttachment::getType() const {
shared_ptr <const contentTypeField> ctf = getContentType();
if (ctf)
{
if (ctf) {
return *ctf->getValue <mediaType>();
}
else
{
} else {
// No "Content-type" field: assume "application/octet-stream".
return mediaType(mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM);
return mediaType(
mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM
);
}
}
const word bodyPartAttachment::getName() const
{
const word bodyPartAttachment::getName() const {
word name;
// Try the 'filename' parameter of 'Content-Disposition' field
shared_ptr <const contentDispositionField> cdf = getContentDisposition();
if (cdf && cdf->hasFilename())
{
if (cdf && cdf->hasFilename()) {
name = cdf->getFilename();
}
// Try the 'name' parameter of 'Content-Type' field
else
{
} else {
shared_ptr <const contentTypeField> ctf = getContentType();
if (ctf)
{
if (ctf) {
shared_ptr <const parameter> prm = ctf->findParameter("name");
if (prm != NULL)
if (prm) {
name = prm->getValue();
}
}
}
return name;
}
const text bodyPartAttachment::getDescription() const
{
const text bodyPartAttachment::getDescription() const {
text description;
shared_ptr <const headerField> cd =
getHeader()->findField(fields::CONTENT_DESCRIPTION);
if (cd)
{
if (cd) {
description = *cd->getValue <text>();
}
else
{
} else {
// 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();
}
const shared_ptr <const contentHandler> bodyPartAttachment::getData() const
{
const shared_ptr <const contentHandler> bodyPartAttachment::getData() const {
return m_part->getBody()->getContents();
}
shared_ptr <const object> bodyPartAttachment::getPart() const
{
shared_ptr <const object> bodyPartAttachment::getPart() const {
return m_part;
}
shared_ptr <const header> bodyPartAttachment::getHeader() const
{
shared_ptr <const header> bodyPartAttachment::getHeader() const {
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);
}
shared_ptr <const contentTypeField> bodyPartAttachment::getContentType() const
{
shared_ptr <const contentTypeField> bodyPartAttachment::getContentType() const {
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
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,17 +34,16 @@
#include "vmime/contentTypeField.hpp"
namespace vmime
{
namespace vmime {
/** An attachment related to a local body part.
*/
class VMIME_EXPORT bodyPartAttachment : public attachment
{
class VMIME_EXPORT bodyPartAttachment : public attachment {
public:
bodyPartAttachment(shared_ptr <const bodyPart> part);
bodyPartAttachment(const shared_ptr <const bodyPart>& part);
const mediaType getType() const;
const word getName() const;
@ -58,7 +57,7 @@ public:
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 contentTypeField> getContentType() const;
@ -75,4 +74,3 @@ private:
#endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -32,74 +32,93 @@
namespace vmime
{
namespace vmime {
charset::charset()
: m_name(charsets::US_ASCII)
{
: m_name(charsets::US_ASCII) {
}
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 (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";
}
}
charset::charset(const char* name)
: m_name(name)
{
: m_name(name) {
}
void charset::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
m_name = utility::stringUtils::trim
(string(buffer.begin() + position, buffer.begin() + end));
void charset::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t 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 (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";
}
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
void charset::generateImpl
(const generationContext& /* ctx */, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
os << m_name;
if (newLinePos)
*newLinePos = curLinePos + m_name.length();
}
void charset::convert(utility::inputStream& in, utility::outputStream& out,
const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
void charset::generateImpl(
const generationContext& /* ctx */,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
os << m_name;
if (newLinePos) {
*newLinePos = curLinePos + m_name.length();
}
}
void charset::convert(
utility::inputStream& in,
utility::outputStream& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
shared_ptr <charsetConverter> conv = charsetConverter::create(source, dest, opts);
conv->convert(in, out);
}
void charset::convert(const string& in, string& out, const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
if (source == dest)
{
void charset::convert(
const string& in,
string& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
if (source == dest) {
out = in;
return;
}
@ -109,27 +128,26 @@ void charset::convert(const string& in, string& out, const charset& source, cons
}
bool charset::isValidText
(const string& text, string::size_type* firstInvalidByte) const
{
bool charset::isValidText(const string& text, string::size_type* firstInvalidByte) const {
charsetConverterOptions opts;
opts.silentlyReplaceInvalidSequences = false;
charsetConverter::status st;
try
{
try {
std::string out;
// Try converting to UTF-8
shared_ptr <charsetConverter> conv = charsetConverter::create(*this, vmime::charset("utf-8"), opts);
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
if (firstInvalidByte)
{
if (firstInvalidByte) {
if (st.inputBytesRead < text.length())
*firstInvalidByte = st.inputBytesRead;
else
@ -139,77 +157,79 @@ bool charset::isValidText
return false;
}
if (firstInvalidByte)
if (firstInvalidByte) {
*firstInvalidByte = text.length();
}
return true;
}
const charset charset::getLocalCharset()
{
return (platform::getHandler()->getLocalCharset());
const charset charset::getLocalCharset() {
return platform::getHandler()->getLocalCharset();
}
charset& charset::operator=(const charset& other)
{
charset& charset::operator=(const charset& other) {
copyFrom(other);
return (*this);
return *this;
}
bool charset::operator==(const charset& value) const
{
return (utility::stringUtils::isStringEqualNoCase(m_name, value.m_name));
bool charset::operator==(const charset& value) const {
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);
}
shared_ptr <component> charset::clone() const
{
shared_ptr <component> charset::clone() const {
return make_shared <charset>(m_name);
}
const string& charset::getName() const
{
return (m_name);
const string& charset::getName() const {
return m_name;
}
void charset::copyFrom(const component& other)
{
void charset::copyFrom(const component& other) {
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> >();
}
// Explicitly force encoding for some charsets
struct CharsetEncodingEntry
{
struct CharsetEncodingEntry {
CharsetEncodingEntry(const string& charset_, const string& encoding_)
: charset(charset_), encoding(encoding_)
{
: charset(charset_), encoding(encoding_) {
}
const string charset;
const string encoding;
};
CharsetEncodingEntry g_charsetEncodingMap[] =
{
CharsetEncodingEntry g_charsetEncodingMap[] = {
// Use QP encoding for ISO-8859-x charsets
CharsetEncodingEntry("iso-8859", 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
const string cset = utility::stringUtils::toLower(getName());
for (unsigned int i = 0 ; i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ; ++i)
{
if (cset.find(g_charsetEncodingMap[i].charset) != string::npos)
{
for (unsigned int i = 0 ;
i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ;
++i) {
if (cset.find(g_charsetEncodingMap[i].charset) != string::npos) {
enc = g_charsetEncodingMap[i].encoding;
return true;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -32,8 +32,7 @@
#include "vmime/component.hpp"
namespace vmime
{
namespace vmime {
class encoding; // forward reference
@ -41,9 +40,8 @@ class encoding; // forward reference
/** Charset description (basic type).
*/
class VMIME_EXPORT charset : public component {
class VMIME_EXPORT charset : public component
{
public:
charset();
@ -102,9 +100,13 @@ public:
* @throws exceptions::charset_conv_error if an unexpected error occurred
* during the conversion
*/
static void convert(const string& in, string& out,
const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
static void convert(
const string& in,
string& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
/** Convert the contents of an input stream in a specified charset
* 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
* during the conversion
*/
static void convert(utility::inputStream& in, utility::outputStream& out,
const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
static void convert(
utility::inputStream& in,
utility::outputStream& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
/** Checks whether the specified text is valid in this charset.
*
@ -147,18 +153,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -26,25 +26,26 @@
#include "vmime/charsetConverter_idna.hpp"
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::create
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
if (source == "idna" || dest == "idna")
shared_ptr <charsetConverter> charsetConverter::create(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
if (source == "idna" || dest == "idna") {
return make_shared <charsetConverter_idna>(source, dest, opts);
else
} else {
return createGenericConverter(source, dest, opts);
}
}
charsetConverter::status::status()
: inputBytesRead(0), outputBytesWritten(0)
{
: inputBytesRead(0), outputBytesWritten(0) {
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -33,12 +33,10 @@
#include "vmime/utility/filteredStream.hpp"
namespace vmime
{
namespace vmime {
namespace utility
{
namespace utility {
/** A filtered output stream which applies a charset conversion
@ -52,9 +50,8 @@ namespace utility
* 'silentlyReplaceInvalidSequences' flag is set to false in
* 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.
*/
class VMIME_EXPORT charsetConverter : public object {
class VMIME_EXPORT charsetConverter : public object
{
public:
/** Holds information about a conversion.
*/
struct status
{
struct status {
status();
@ -91,9 +87,11 @@ public:
* @param dest output charset
* @param opts conversion options
*/
static shared_ptr <charsetConverter> create
(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
static shared_ptr <charsetConverter> create(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
/** Convert a string buffer from one charset to another
* charset (in-memory conversion)
@ -128,7 +126,11 @@ public:
* @throws exceptions::charset_conv_error if an unexpected error occurred
* 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
* conversion to input bytes. Please note that it may not be
@ -138,15 +140,19 @@ public:
* @param opts conversion options
* @return a filtered output stream, or NULL if not supported
*/
virtual shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()) = 0;
virtual shared_ptr <utility::charsetFilteredOutputStream>
getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
) = 0;
private:
static shared_ptr <charsetConverter> createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts);
static shared_ptr <charsetConverter> createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
);
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -24,14 +24,13 @@
#include "vmime/charsetConverterOptions.hpp"
namespace vmime
{
namespace vmime {
charsetConverterOptions::charsetConverterOptions()
: silentlyReplaceInvalidSequences(true),
invalidSequence("?")
{
invalidSequence("?") {
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -28,15 +28,13 @@
#include "vmime/base.hpp"
namespace vmime
{
namespace vmime {
/** Options for charset conversion.
*/
class VMIME_EXPORT charsetConverterOptions : public object {
class VMIME_EXPORT charsetConverterOptions : public object
{
public:
charsetConverterOptions();

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,8 +34,8 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
extern "C"
{
extern "C" {
#ifndef VMIME_BUILDING_DOC
#include <iconv.h>
@ -45,8 +45,8 @@ extern "C"
// second parameter may or may not be 'const'). This relies on the compiler
// for choosing the right type.
class ICONV_IN_TYPE
{
class ICONV_IN_TYPE {
public:
ICONV_IN_TYPE(const char** ptr) : m_ptr(ptr) { }
@ -62,8 +62,8 @@ extern "C"
const char** m_ptr;
};
class ICONV_OUT_TYPE
{
class ICONV_OUT_TYPE {
public:
ICONV_OUT_TYPE(char** ptr) : m_ptr(ptr) { }
@ -85,9 +85,12 @@ extern "C"
// Output replacement char when an invalid sequence is encountered
template <typename OUTPUT_CLASS, typename ICONV_DESC>
void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd,
const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions())
{
void outputInvalidChar(
OUTPUT_CLASS& out,
ICONV_DESC cd,
const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions()
) {
const char* invalidCharIn = opts.invalidSequence.c_str();
vmime::size_t invalidCharInLen = opts.invalidSequence.length();
@ -96,36 +99,43 @@ void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd,
vmime::size_t invalidCharOutLen = 16;
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);
}
}
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
return make_shared <charsetConverter_iconv>(source, dest, opts);
}
charsetConverter_iconv::charsetConverter_iconv
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_desc(NULL), m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_iconv::charsetConverter_iconv(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
)
: m_desc(NULL),
m_source(source),
m_dest(dest),
m_options(opts) {
// Get an iconv descriptor
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;
*p= cd;
@ -134,10 +144,10 @@ charsetConverter_iconv::charsetConverter_iconv
}
charsetConverter_iconv::~charsetConverter_iconv()
{
if (m_desc != NULL)
{
charsetConverter_iconv::~charsetConverter_iconv() {
if (m_desc) {
// Close iconv handle
iconv_close(*static_cast <iconv_t*>(m_desc));
@ -147,14 +157,19 @@ charsetConverter_iconv::~charsetConverter_iconv()
}
void charsetConverter_iconv::convert
(utility::inputStream& in, utility::outputStream& out, status* st)
{
if (st)
new (st) status();
void charsetConverter_iconv::convert(
utility::inputStream& in,
utility::outputStream& out,
status* st
) {
if (m_desc == NULL)
if (st) {
new (st) status();
}
if (!m_desc) {
throw exceptions::charset_conv_error("Cannot initialize converter.");
}
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
@ -165,8 +180,8 @@ void charsetConverter_iconv::convert
bool prevIsInvalid = false;
bool breakAfterNext = false;
while (true)
{
while (true) {
// Fullfill the buffer
size_t inLength = static_cast <size_t>(in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos);
size_t outLength = sizeof(outBuffer);
@ -177,23 +192,23 @@ void charsetConverter_iconv::convert
// Convert input bytes
if (iconv(cd, ICONV_IN_TYPE(&inPtr), ptrLength,
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
{
if (st && inPtr)
{
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
if (st && inPtr) {
st->inputBytesRead += (inPtr - inBuffer);
st->outputBytesWritten += (outPtr - outBuffer);
}
// Illegal input sequence or input sequence has no equivalent
// sequence in the destination charset.
if (prevIsInvalid)
{
if (prevIsInvalid) {
// Write successfully converted bytes
out.write(outBuffer, sizeof(outBuffer) - outLength);
if (!m_options.silentlyReplaceInvalidSequences)
if (!m_options.silentlyReplaceInvalidSequences) {
throw exceptions::illegal_byte_sequence_for_charset();
}
// Output a special character to indicate we don't known how to
// 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
std::copy(const_cast <byte_t*>(inPtr + 1), inBuffer + sizeof(inBuffer), inBuffer);
inPos = inLength - 1;
}
else
{
} else {
// Write successfully converted bytes
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);
inPos = inLength;
if (errno != E2BIG)
if (errno != E2BIG) {
prevIsInvalid = true;
}
}
else
{
} else {
// Write successfully converted bytes
out.write(outBuffer, sizeof(outBuffer) - outLength);
if (st && inPtr)
{
if (st && inPtr) {
st->inputBytesRead += (inPtr - inBuffer);
st->outputBytesWritten += (outPtr - outBuffer);
}
@ -231,20 +246,23 @@ void charsetConverter_iconv::convert
prevIsInvalid = false;
}
if (breakAfterNext)
if (breakAfterNext) {
break;
}
// 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;
}
}
}
void charsetConverter_iconv::convert(const string& in, string& out, status* st)
{
if (st)
void charsetConverter_iconv::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
out.clear();
@ -258,9 +276,11 @@ void charsetConverter_iconv::convert(const string& in, string& out, status* st)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_iconv::getFilteredOutputStream
(utility::outputStream& os, const charsetConverterOptions& opts)
{
charsetConverter_iconv::getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts
) {
return make_shared <utility::charsetFilteredOutputStream_iconv>(m_source, m_dest, &os, opts);
}
@ -271,17 +291,23 @@ shared_ptr <utility::charsetFilteredOutputStream>
namespace utility {
charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts)
: m_desc(NULL), m_sourceCharset(source), m_destCharset(dest),
m_stream(*os), m_unconvCount(0), m_options(opts)
{
charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv(
const charset& source,
const charset& dest, outputStream* os,
const charsetConverterOptions& opts
)
: m_desc(NULL),
m_sourceCharset(source),
m_destCharset(dest),
m_stream(*os),
m_unconvCount(0),
m_options(opts) {
// Get an iconv descriptor
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;
*p= cd;
@ -290,10 +316,10 @@ charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv
}
charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv()
{
if (m_desc != NULL)
{
charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv() {
if (m_desc) {
// Close iconv handle
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;
}
void charsetFilteredOutputStream_iconv::writeImpl
(const byte_t* const data, const size_t count)
{
if (m_desc == NULL)
void charsetFilteredOutputStream_iconv::writeImpl(
const byte_t* const data,
const size_t count
) {
if (!m_desc) {
throw exceptions::charset_conv_error("Cannot initialize converter.");
}
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
// chunk to see if it can now be converted.
while (m_unconvCount != 0 || curDataLen != 0)
{
if (m_unconvCount != 0)
{
while (m_unconvCount != 0 || curDataLen != 0) {
if (m_unconvCount != 0) {
// Check if an incomplete input sequence is larger than the
// input buffer size: should not happen except if something
// in the input sequence is invalid. If so, output a special
// character and skip one byte in the invalid sequence.
if (m_unconvCount >= sizeof(m_unconvBuffer))
{
if (!m_options.silentlyReplaceInvalidSequences)
if (m_unconvCount >= sizeof(m_unconvBuffer)) {
if (!m_options.silentlyReplaceInvalidSequences) {
throw exceptions::illegal_byte_sequence_for_charset();
}
outputInvalidChar(m_stream, cd);
std::copy(m_unconvBuffer + 1,
m_unconvBuffer + m_unconvCount, m_unconvBuffer);
std::copy(
m_unconvBuffer + 1,
m_unconvBuffer + m_unconvCount, m_unconvBuffer
);
m_unconvCount--;
}
@ -365,16 +397,18 @@ void charsetFilteredOutputStream_iconv::writeImpl
const size_t inLength0 = 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;
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
// Shift unconverted bytes
std::copy(m_unconvBuffer + inputConverted,
m_unconvBuffer + m_unconvCount, m_unconvBuffer);
std::copy(
m_unconvBuffer + inputConverted,
m_unconvBuffer + m_unconvCount, m_unconvBuffer
);
m_unconvCount -= inputConverted;
@ -388,8 +422,9 @@ void charsetFilteredOutputStream_iconv::writeImpl
m_unconvCount = 0;
}
if (curDataLen == 0)
if (curDataLen == 0) {
return; // no more data
}
// Now, convert the current data buffer
const byte_t* inPtr = curData;
@ -400,8 +435,8 @@ void charsetFilteredOutputStream_iconv::writeImpl
const size_t inLength0 = 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
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
// that the next iteration fill it
if (curDataLen != 0)
{
if (curDataLen != 0) {
m_unconvCount = 1;
m_unconvBuffer[0] = *curData;
curData++;
curDataLen--;
}
}
else
{
} else {
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
@ -433,18 +468,19 @@ void charsetFilteredOutputStream_iconv::writeImpl
}
void charsetFilteredOutputStream_iconv::flush()
{
if (m_desc == NULL)
void charsetFilteredOutputStream_iconv::flush() {
if (!m_desc) {
throw exceptions::charset_conv_error("Cannot initialize converter.");
}
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
size_t offset = 0;
// Process unconverted bytes
while (m_unconvCount != 0)
{
while (m_unconvCount != 0) {
// Try a conversion
const byte_t* inPtr = m_unconvBuffer + offset;
size_t inLength = m_unconvCount;
@ -453,32 +489,34 @@ void charsetFilteredOutputStream_iconv::flush()
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;
// Skip a "blocking" character
if (inputConverted == 0)
{
if (!m_options.silentlyReplaceInvalidSequences)
if (inputConverted == 0) {
if (!m_options.silentlyReplaceInvalidSequences) {
throw exceptions::illegal_byte_sequence_for_charset();
}
outputInvalidChar(m_stream, cd);
offset++;
m_unconvCount--;
}
else
{
} else {
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
offset += inputConverted;
m_unconvCount -= inputConverted;
}
}
else
{
} else {
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,15 +34,13 @@
#include "vmime/charsetConverter.hpp"
namespace vmime
{
namespace vmime {
/** A generic charset converter which uses iconv library.
*/
class charsetConverter_iconv : public charsetConverter {
class charsetConverter_iconv : public charsetConverter
{
public:
/** Construct and initialize an iconv charset converter.
@ -51,17 +49,21 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_iconv(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_iconv(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetConverter_iconv();
void convert(const string& in, string& out, status* st = NULL);
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions());
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
private:
@ -77,8 +79,8 @@ private:
namespace utility {
class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream
{
class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream {
public:
/** Construct a new filter for the specified output stream.
@ -88,9 +90,11 @@ public:
* @param os stream into which write filtered data
* @param opts conversion options
*/
charsetFilteredOutputStream_iconv
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetFilteredOutputStream_iconv(
const charset& source,
const charset& dest, outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetFilteredOutputStream_iconv();

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,8 +34,8 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
extern "C"
{
extern "C" {
#ifndef VMIME_BUILDING_DOC
#include <unicode/ucnv.h>
@ -48,59 +48,75 @@ extern "C"
#include <unicode/unistr.h>
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
return make_shared <charsetConverter_icu>(source, dest, opts);
}
charsetConverter_icu::charsetConverter_icu
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_from(NULL), m_to(NULL), m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_icu::charsetConverter_icu(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
)
: m_from(NULL),
m_to(NULL),
m_source(source),
m_dest(dest),
m_options(opts) {
UErrorCode err = U_ZERO_ERROR;
m_from = ucnv_open(source.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"Cannot initialize ICU converter for source charset '" + source.getName()
+ "' (error code: " + u_errorName(err) + "."
);
}
m_to = ucnv_open(dest.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"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_to) ucnv_close(m_to);
}
void charsetConverter_icu::convert
(utility::inputStream& in, utility::outputStream& out, status* st)
{
void charsetConverter_icu::convert(
utility::inputStream& in,
utility::outputStream& out,
status* st
) {
UErrorCode err = U_ZERO_ERROR;
ucnv_reset(m_from);
ucnv_reset(m_to);
if (st)
if (st) {
new (st) status();
}
// From buffers
byte_t cpInBuffer[16]; // stream data put here
@ -113,34 +129,39 @@ void charsetConverter_icu::convert
std::vector <char> cpOutBuffer(cpOutBufferSz);
// 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
icu::UnicodeString substString(m_options.invalidSequence.c_str());
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.");
}
else
{
} else {
// Tell ICU top stop (and return an error) on illegal byte sequences
ucnv_setToUCallBack
(m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setToUCallBack(
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.");
}
ucnv_setFromUCallBack
(m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setFromUCallBack(
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.");
}
}
// Input data available
while (!in.eof())
{
while (!in.eof()) {
// Read input data into buffer
size_t inLength = in.read(cpInBuffer, sizeof(cpInBuffer));
@ -153,30 +174,36 @@ void charsetConverter_icu::convert
UErrorCode toErr;
// Loop until all source has been processed
do
{
do {
// Set up target pointers
UChar* target = &uOutBuffer[0];
UChar* targetLimit = &target[0] + outSize;
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]));
}
if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr)) {
if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr))
{
if (toErr == U_INVALID_CHAR_FOUND ||
toErr == U_TRUNCATED_CHAR_FOUND ||
toErr == U_ILLEGAL_CHAR_FOUND)
{
toErr == U_ILLEGAL_CHAR_FOUND) {
// Error will be thrown later (*)
}
else
{
throw exceptions::charset_conv_error("[ICU] Error converting to Unicode from " + m_source.getName());
} else {
throw exceptions::charset_conv_error(
"[ICU] Error converting to Unicode from " + m_source.getName()
);
}
}
@ -187,19 +214,21 @@ void charsetConverter_icu::convert
UErrorCode fromErr;
// Loop until converted chars are fully written
do
{
do {
char* cpTarget = &cpOutBuffer[0];
const char* cpTargetLimit = &cpOutBuffer[0] + cpOutBufferSz;
fromErr = U_ZERO_ERROR;
// Write converted bytes (Unicode) to destination codepage
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
&uSource, uSourceLimit, NULL, flush, &fromErr);
ucnv_fromUnicode(
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
char errBytes[16];
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 (toErr == U_INVALID_CHAR_FOUND ||
toErr == U_TRUNCATED_CHAR_FOUND ||
toErr == U_ILLEGAL_CHAR_FOUND)
{
toErr == U_ILLEGAL_CHAR_FOUND) {
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 ||
fromErr == U_TRUNCATED_CHAR_FOUND ||
fromErr == U_ILLEGAL_CHAR_FOUND)
{
fromErr == U_ILLEGAL_CHAR_FOUND) {
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error("[ICU] Error converting from Unicode to " + m_dest.getName());
} else {
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)
{
if (st)
void charsetConverter_icu::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
out.clear();
@ -260,9 +292,11 @@ void charsetConverter_icu::convert(const string& in, string& out, status* st)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_icu::getFilteredOutputStream
(utility::outputStream& os, const charsetConverterOptions& opts)
{
charsetConverter_icu::getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts
) {
return make_shared <utility::charsetFilteredOutputStream_icu>(m_source, m_dest, &os, opts);
}
@ -273,75 +307,94 @@ shared_ptr <utility::charsetFilteredOutputStream>
namespace utility {
charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts)
: m_from(NULL), m_to(NULL), m_sourceCharset(source),
m_destCharset(dest), m_stream(*os), m_options(opts)
{
charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu(
const charset& source,
const charset& dest,
outputStream* os,
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;
m_from = ucnv_open(source.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"Cannot initialize ICU converter for source charset '" + source.getName()
+ "' (error code: " + u_errorName(err) + "."
);
}
m_to = ucnv_open(dest.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"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
if (m_options.silentlyReplaceInvalidSequences)
{
if (m_options.silentlyReplaceInvalidSequences) {
// Set replacement chars for when converting from Unicode to codepage
icu::UnicodeString substString(m_options.invalidSequence.c_str());
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
if (U_FAILURE(err))
if (U_FAILURE(err)) {
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
ucnv_setToUCallBack
(m_to, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setToUCallBack(
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.");
}
ucnv_setFromUCallBack
(m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setFromUCallBack(
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.");
}
}
}
charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu()
{
charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu() {
if (m_from) ucnv_close(m_from);
if (m_to) ucnv_close(m_to);
}
outputStream& charsetFilteredOutputStream_icu::getNextOutputStream()
{
outputStream& charsetFilteredOutputStream_icu::getNextOutputStream() {
return m_stream;
}
void charsetFilteredOutputStream_icu::writeImpl
(const byte_t* const data, const size_t count)
{
if (m_from == NULL || m_to == NULL)
void charsetFilteredOutputStream_icu::writeImpl(
const byte_t* const data,
const size_t count
) {
if (!m_from || !m_to) {
throw exceptions::charset_conv_error("Cannot initialize converters.");
}
// Allocate buffer for Unicode chars
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* uniSourceLimit = uniSource + count;
do
{
do {
// Convert from source charset to Unicode
UChar* uniTarget = &uniBuffer[0];
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
toErr = U_ZERO_ERROR;
ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit,
&uniSource, uniSourceLimit, NULL, /* flush */ FALSE, &toErr);
ucnv_toUnicode(
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 ||
toErr == U_TRUNCATED_CHAR_FOUND ||
toErr == U_ILLEGAL_CHAR_FOUND)
{
toErr == U_ILLEGAL_CHAR_FOUND) {
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error
("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'.");
} else {
throw exceptions::charset_conv_error(
"[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."
);
}
}
@ -391,28 +447,31 @@ void charsetFilteredOutputStream_icu::writeImpl
const UChar* cpSource = &uniBuffer[0];
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
do
{
do {
char* cpTarget = &cpBuffer[0];
char* cpTargetLimit = &cpBuffer[0] + cpSize;
fromErr = U_ZERO_ERROR;
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
&cpSource, cpSourceLimit, NULL, /* flush */ FALSE, &fromErr);
ucnv_fromUnicode(
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 ||
fromErr == U_TRUNCATED_CHAR_FOUND ||
fromErr == U_ILLEGAL_CHAR_FOUND)
{
fromErr == U_ILLEGAL_CHAR_FOUND) {
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error
("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'.");
} else {
throw exceptions::charset_conv_error(
"[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."
);
}
}
@ -427,10 +486,11 @@ void charsetFilteredOutputStream_icu::writeImpl
}
void charsetFilteredOutputStream_icu::flush()
{
if (m_from == NULL || m_to == NULL)
void charsetFilteredOutputStream_icu::flush() {
if (!m_from || !m_to) {
throw exceptions::charset_conv_error("Cannot initialize converters.");
}
// Allocate buffer for Unicode chars
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* uniSourceLimit = 0;
do
{
do {
// Convert from source charset to Unicode
UChar* uniTarget = &uniBuffer[0];
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
toErr = U_ZERO_ERROR;
ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit,
&uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr);
ucnv_toUnicode(
m_from, &uniTarget, uniTargetLimit,
&uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr
);
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR)
{
throw exceptions::charset_conv_error
("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'.");
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) {
throw exceptions::charset_conv_error(
"[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."
);
}
const size_t uniLength = uniTarget - &uniBuffer[0];
@ -471,20 +534,23 @@ void charsetFilteredOutputStream_icu::flush()
const UChar* cpSource = &uniBuffer[0];
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
do
{
do {
char* cpTarget = &cpBuffer[0];
char* cpTargetLimit = &cpBuffer[0] + cpSize;
fromErr = U_ZERO_ERROR;
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
&cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr);
ucnv_fromUnicode(
m_to, &cpTarget, cpTargetLimit,
&cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr
);
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
{
throw exceptions::charset_conv_error
("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'.");
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) {
throw exceptions::charset_conv_error(
"[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."
);
}
const size_t cpLength = cpTarget - &cpBuffer[0];

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -37,15 +37,13 @@
struct UConverter;
namespace vmime
{
namespace vmime {
/** A generic charset converter which uses ICU library.
*/
class charsetConverter_icu : public charsetConverter {
class charsetConverter_icu : public charsetConverter
{
public:
/** Construct and initialize an ICU charset converter.
@ -54,17 +52,21 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_icu(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_icu(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetConverter_icu();
void convert(const string& in, string& out, status* st = NULL);
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions());
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
private:
@ -81,8 +83,8 @@ private:
namespace utility {
class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream
{
class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream {
public:
/** Construct a new filter for the specified output stream.
@ -92,9 +94,12 @@ public:
* @param os stream into which write filtered data
* @param opts conversion options
*/
charsetFilteredOutputStream_icu
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetFilteredOutputStream_icu(
const charset& source,
const charset& dest,
outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetFilteredOutputStream_icu();

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -30,8 +30,7 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
extern "C"
{
extern "C" {
#include "contrib/punycode/punycode.h"
#include "contrib/punycode/punycode.c"
@ -41,26 +40,31 @@ extern "C"
#include "contrib/utf8/utf8.h"
namespace vmime
{
namespace vmime {
charsetConverter_idna::charsetConverter_idna
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_idna::charsetConverter_idna(
const charset& source,
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)
{
if (st)
void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStream& out, status* st) {
if (st) {
new (st) status();
}
// IDNA should be used for short strings, so it does not matter if we
// 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)
{
if (st)
void charsetConverter_idna::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
out.clear();
if (m_dest == "idna")
{
if (utility::stringUtils::is7bit(in))
{
if (st)
{
if (m_dest == "idna") {
if (utility::stringUtils::is7bit(in)) {
if (st) {
st->inputBytesRead = 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;
unichars.reserve(inUTF8.length());
while (ch < end)
{
while (ch < end) {
const utf8::uint32_t uc = utf8::unchecked::next(ch);
unichars.push_back(uc);
}
if (st)
if (st) {
st->inputBytesRead = in.length();
}
punycode_uint inputLen = static_cast <punycode_uint>(unichars.size());
std::vector <char> output(inUTF8.length() * 2);
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
const punycode_status status = punycode_encode
(inputLen, &unichars[0], /* case_flags */ NULL, &outputLen, &output[0]);
const punycode_status status = punycode_encode(
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);
if (st)
if (st) {
st->outputBytesWritten = out.length();
}
else
{
} else {
// TODO
}
}
else if (m_source == "idna")
{
if (in.length() < 5 || in.substr(0, 4) != "xn--")
{
if (st)
{
} else if (m_source == "idna") {
if (in.length() < 5 || in.substr(0, 4) != "xn--") {
if (st) {
st->inputBytesRead = 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);
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
const punycode_status status = punycode_decode
(inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL);
const punycode_status status = punycode_decode(
inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL
);
if (st)
if (st) {
st->inputBytesRead = in.length();
}
if (status == punycode_success) {
if (status == punycode_success)
{
std::vector <char> outUTF8Bytes(outputLen * 4);
char* p = &outUTF8Bytes[0];
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);
}
string outUTF8(&outUTF8Bytes[0], p);
charset::convert(outUTF8, out, vmime::charsets::UTF_8, m_dest);
if (st)
if (st) {
st->outputBytesWritten = out.length();
}
else
{
} else {
// TODO
}
}
@ -187,9 +195,12 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_idna::getFilteredOutputStream
(utility::outputStream& /* os */, const charsetConverterOptions& /* opts */)
{
charsetConverter_idna::getFilteredOutputStream(
utility::outputStream& /* os */,
const charsetConverterOptions& /* opts */
) {
// Not supported
return null;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -28,15 +28,13 @@
#include "vmime/charsetConverter.hpp"
namespace vmime
{
namespace vmime {
/** A charset converter which can convert to and from Punycode (for IDNA).
*/
class charsetConverter_idna : public charsetConverter {
class charsetConverter_idna : public charsetConverter
{
public:
/** Construct and initialize an IDNA charset converter.
@ -45,17 +43,21 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_idna(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_idna(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetConverter_idna();
void convert(const string& in, string& out, status* st = NULL);
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions());
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
private:

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -49,37 +49,46 @@
#define CP_UNICODE 1200
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
return make_shared <charsetConverter_win>(source, dest, opts);
}
charsetConverter_win::charsetConverter_win
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_win::charsetConverter_win(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
)
: m_source(source),
m_dest(dest),
m_options(opts) {
}
void charsetConverter_win::convert
(utility::inputStream& in, utility::outputStream& out, status* st)
{
if (st)
void charsetConverter_win::convert(
utility::inputStream& in,
utility::outputStream& out,
status* st
) {
if (st) {
new (st) status();
}
byte_t buffer[32768];
string inStr, outStr;
while (!in.eof())
{
while (!in.eof()) {
const size_t len = in.read(buffer, sizeof(buffer));
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)
{
if (st)
void charsetConverter_win::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
const int sourceCodePage = getCodePage(m_source.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;
size_t unicodeLen = 0;
if (sourceCodePage == CP_UNICODE)
{
if (sourceCodePage == CP_UNICODE) {
unicodePtr = reinterpret_cast <const WCHAR*>(in.c_str());
unicodeLen = in.length() / 2;
}
else
{
const size_t bufferSize = MultiByteToWideChar
(sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
NULL, 0) * sizeof(WCHAR); // in wide characters
} else {
const size_t bufferSize = MultiByteToWideChar(
sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()), NULL, 0
) * sizeof(WCHAR); // in wide characters
unicodeBuffer.resize(bufferSize);
DWORD flags = 0;
if (!m_options.silentlyReplaceInvalidSequences)
if (!m_options.silentlyReplaceInvalidSequences) {
flags |= MB_ERR_INVALID_CHARS;
}
unicodePtr = reinterpret_cast <const WCHAR*>(&unicodeBuffer[0]);
unicodeLen = MultiByteToWideChar
(sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
reinterpret_cast <WCHAR*>(&unicodeBuffer[0]), static_cast <int>(bufferSize));
unicodeLen = MultiByteToWideChar(
sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
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();
}
else
{
throw exceptions::charset_conv_error("MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName());
} else {
throw exceptions::charset_conv_error(
"MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName()
);
}
}
}
// Convert from Unicode to destination charset
if (destCodePage == CP_UNICODE)
{
if (destCodePage == CP_UNICODE) {
out.assign(reinterpret_cast <const char*>(unicodePtr), unicodeLen * 2);
}
else
{
const size_t bufferSize = WideCharToMultiByte
(destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
NULL, 0, 0, NULL); // in multibyte characters
} else {
const size_t bufferSize = WideCharToMultiByte(
destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
NULL, 0, 0, NULL
); // in multibyte characters
std::vector <char> buffer;
buffer.resize(bufferSize);
const size_t len = WideCharToMultiByte
(destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
&buffer[0], static_cast <int>(bufferSize), 0, NULL);
const size_t len = WideCharToMultiByte(
destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
&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();
}
else
{
throw exceptions::charset_conv_error("WideCharToMultiByte() failed when converting from Unicode to " + m_source.getName());
} else {
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
int charsetConverter_win::getCodePage(const char* name)
{
if (_stricmp(name, charsets::UTF_16) == 0) // wchar_t is UTF-16 on Windows
int charsetConverter_win::getCodePage(const char* name) {
if (_stricmp(name, charsets::UTF_16) == 0) { // wchar_t is UTF-16 on Windows
return CP_UNICODE;
}
// "cp1252" --> return 1252
if ((name[0] == 'c' || name[0] == 'C') &&
(name[1] == 'p' || name[1] == 'P'))
{
(name[1] == 'p' || name[1] == 'P')) {
return atoi(name + 2);
}
@ -192,9 +211,11 @@ int charsetConverter_win::getCodePage(const char* name)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_win::getFilteredOutputStream
(utility::outputStream& /* os */, const charsetConverterOptions& /* opts */)
{
charsetConverter_win::getFilteredOutputStream(
utility::outputStream& /* os */,
const charsetConverterOptions& /* opts */
) {
// TODO: implement me!
return null;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,8 +34,7 @@
#include "vmime/charsetConverter.hpp"
namespace vmime
{
namespace vmime {
/** 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.
*/
class charsetConverter_win : public charsetConverter {
class charsetConverter_win : public charsetConverter
{
public:
/** Construct and initialize a Windows charset converter.
@ -60,14 +58,19 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_win(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_win(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
void convert(const string& in, string& out, status* st);
void convert(utility::inputStream& in, utility::outputStream& out, status* st);
shared_ptr <utility::charsetFilteredOutputStream>
getFilteredOutputStream(utility::outputStream& os, const charsetConverterOptions& opts);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts
);
private:

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -31,48 +31,54 @@
#include <sstream>
namespace vmime
{
namespace vmime {
component::component()
: m_parsedOffset(0), m_parsedLength(0)
{
: m_parsedOffset(0), m_parsedLength(0) {
}
component::~component()
{
component::~component() {
}
void component::parse
(shared_ptr <utility::inputStream> inputStream, const size_t length)
{
void component::parse(
const shared_ptr <utility::inputStream>& inputStream,
const size_t length
) {
parse(inputStream, 0, length, NULL);
}
void component::parse
(shared_ptr <utility::inputStream> inputStream, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition) {
parse(parsingContext::getDefaultContext(), inputStream, position, end, newPosition);
}
void component::parse
(const parsingContext& ctx,
shared_ptr <utility::inputStream> inputStream, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const parsingContext& ctx,
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_parsedOffset = m_parsedLength = 0;
shared_ptr <utility::seekableInputStream> seekableStream =
dynamicCast <utility::seekableInputStream>(inputStream);
if (seekableStream == NULL || end == 0)
{
if (!seekableStream || end == 0) {
// Read the whole stream into a buffer
std::ostringstream oss;
utility::outputStreamAdapter ossAdapter(oss);
@ -81,9 +87,9 @@ void component::parse
const string buffer = oss.str();
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
}
else
{
} else {
shared_ptr <utility::parserInputStreamAdapter> parser =
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;
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;
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
}
void component::parse
(const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_parsedOffset = m_parsedLength = 0;
parseImpl(parsingContext::getDefaultContext(), buffer, position, end, newPosition);
}
void component::parse
(const parsingContext& ctx,
const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end, size_t* newPosition
) {
m_parsedOffset = m_parsedLength = 0;
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
if (m_parsedLength != 0)
if (m_parsedLength != 0) {
m_parsedOffset += offset;
}
// Offset parsed bounds of our children
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);
}
}
void component::parseImpl
(const parsingContext& ctx, shared_ptr <utility::parserInputStreamAdapter> parser,
const size_t position, const size_t end, size_t* newPosition)
{
void component::parseImpl(
const parsingContext& ctx,
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:
// actually, we extract the substring and use the "parse from string" implementation
const string buffer = parser->extract(position, end);
parseImpl(ctx, buffer, 0, buffer.length(), newPosition);
// Recursivey offset parsed bounds on children
if (position != 0)
if (position != 0) {
offsetParsedBounds(position);
}
if (newPosition != NULL)
if (newPosition) {
*newPosition += position;
}
}
void component::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition) {
// This is the default implementation for parsing from a string:
// actually, we encapsulate the string buffer in an input stream, then use
// the "parse from input stream" implementation
@ -178,9 +200,11 @@ void component::parseImpl
}
const string component::generate
(const size_t maxLineLength, const size_t curLinePos) const
{
const string component::generate(
const size_t maxLineLength,
const size_t curLinePos
) const {
std::ostringstream oss;
utility::outputStreamAdapter adapter(oss);
@ -189,56 +213,63 @@ const string component::generate
generateImpl(ctx, adapter, curLinePos, NULL);
return (oss.str());
return oss.str();
}
void component::generate
(utility::outputStream& os, const size_t curLinePos, size_t* newLinePos) const
{
generateImpl(generationContext::getDefaultContext(),
os, curLinePos, newLinePos);
void component::generate(
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
generateImpl(generationContext::getDefaultContext(), os, curLinePos, newLinePos);
}
void component::generate
(const generationContext& ctx, utility::outputStream& outputStream,
const size_t curLinePos, size_t* newLinePos) const
{
void component::generate(
const generationContext& ctx,
utility::outputStream& outputStream,
const size_t curLinePos,
size_t* newLinePos
) const {
generateImpl(ctx, outputStream, curLinePos, newLinePos);
}
size_t component::getParsedOffset() const
{
return (m_parsedOffset);
size_t component::getParsedOffset() const {
return m_parsedOffset;
}
size_t component::getParsedLength() const
{
return (m_parsedLength);
size_t component::getParsedLength() const {
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_parsedLength = end - start;
}
size_t component::getGeneratedSize(const generationContext& ctx)
{
size_t component::getGeneratedSize(const generationContext& ctx) {
std::vector <shared_ptr <component> > children = getChildComponents();
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);
}
return totalSize;
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,16 +34,14 @@
#include "vmime/parsingContext.hpp"
namespace vmime
{
namespace vmime {
/** This abstract class is the base class for all the components of a message.
* It defines methods for parsing and generating a component.
*/
class VMIME_EXPORT component : public object {
class VMIME_EXPORT component : public object
{
public:
component();
@ -70,7 +68,7 @@ public:
* @param inputStream stream from which to read data
* @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
* parsing context.
@ -80,11 +78,12 @@ public:
* @param end end position in the input buffer
* @param newPosition will receive the new position in the input buffer
*/
void parse
(const string& buffer,
void parse(
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
/** Parse RFC-822/MIME data for this component.
*
@ -94,12 +93,13 @@ public:
* @param end end position in the input buffer
* @param newPosition will receive the new position in the input buffer
*/
void parse
(const parsingContext& ctx,
void parse(
const parsingContext& ctx,
const string& buffer,
const size_t position,
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,
* 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 newPosition will receive the new position in the input stream
*/
void parse
(shared_ptr <utility::inputStream> inputStream,
void parse(
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
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,
* 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 newPosition will receive the new position in the input stream
*/
void parse
(const parsingContext& ctx,
shared_ptr <utility::inputStream> inputStream,
void parse(
const parsingContext& ctx,
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
/** Generate RFC-2822/MIME data for this component.
*
@ -142,9 +144,10 @@ public:
* @param curLinePos length of the current line in the output buffer
* @return generated data
*/
virtual const string generate
(const size_t maxLineLength = lineLengthLimits::infinite,
const size_t curLinePos = 0) const;
virtual const string generate(
const size_t maxLineLength = lineLengthLimits::infinite,
const size_t curLinePos = 0
) const;
/** 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 newLinePos will receive the new line position (length of the last line written)
*/
virtual void generate
(utility::outputStream& outputStream,
virtual void generate(
utility::outputStream& outputStream,
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.
*
@ -164,11 +168,12 @@ public:
* @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)
*/
virtual void generate
(const generationContext& ctx,
virtual void generate(
const generationContext& ctx,
utility::outputStream& outputStream,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
/** Clone this component.
*
@ -222,25 +227,28 @@ protected:
void setParsedBounds(const size_t start, const size_t end);
// AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class
virtual void parseImpl
(const parsingContext& ctx,
shared_ptr <utility::parserInputStreamAdapter> parser,
virtual void parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
virtual void parseImpl
(const parsingContext& ctx,
virtual void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
virtual void generateImpl
(const generationContext& ctx,
virtual void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const = 0;
size_t* newLinePos = NULL
) const = 0;
private:

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -24,13 +24,12 @@
#include "vmime/constants.hpp"
namespace vmime
{
namespace vmime {
// Media Types
namespace mediaTypes
{
namespace mediaTypes {
// Types
const char* const TEXT = "text";
const char* const MULTIPART = "multipart";
@ -72,8 +71,8 @@ namespace mediaTypes
// Encoding types
namespace encodingTypes
{
namespace encodingTypes {
const char* const SEVEN_BIT = "7bit";
const char* const EIGHT_BIT = "8bit";
const char* const BASE64 = "base64";
@ -84,16 +83,16 @@ namespace encodingTypes
// Content disposition types
namespace contentDispositionTypes
{
namespace contentDispositionTypes {
const char* const INLINE = "inline";
const char* const ATTACHMENT = "attachment";
}
// Charsets
namespace charsets
{
namespace charsets {
const char* const ISO8859_1 = "iso-8859-1";
const char* const ISO8859_2 = "iso-8859-2";
const char* const ISO8859_3 = "iso-8859-3";
@ -159,8 +158,8 @@ namespace charsets
// Fields
namespace fields
{
namespace fields {
const char* const RECEIVED = "Received";
const char* const FROM = "From";
const char* const SENDER = "Sender";
@ -204,32 +203,32 @@ namespace fields
// Constants for disposition action modes (RFC-3978).
namespace dispositionActionModes
{
namespace dispositionActionModes {
const char* const MANUAL = "manual";
const char* const AUTOMATIC = "automatic";
}
// Constants for disposition sending modes (RFC-3798).
namespace dispositionSendingModes
{
namespace dispositionSendingModes {
const char* const SENT_MANUALLY = "MDN-sent-manually";
const char* const SENT_AUTOMATICALLY ="MDN-sent-automatically";
}
// Constants for disposition types (RFC-3798).
namespace dispositionTypes
{
namespace dispositionTypes {
const char* const DISPLAYED = "displayed";
const char* const DELETED = "deleted";
}
// Constants for disposition modifiers (RFC-3798).
namespace dispositionModifiers
{
namespace dispositionModifiers {
const char* const ERROR = "error";
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -37,11 +37,11 @@
#endif
namespace vmime
{
namespace vmime {
/** Constants for media types. */
namespace mediaTypes
{
namespace mediaTypes {
// Types
extern VMIME_EXPORT const char* const TEXT;
extern VMIME_EXPORT const char* const MULTIPART;
@ -83,8 +83,8 @@ namespace vmime
/** Constants for encoding types. */
namespace encodingTypes
{
namespace encodingTypes {
extern VMIME_EXPORT const char* const SEVEN_BIT;
extern VMIME_EXPORT const char* const EIGHT_BIT;
extern VMIME_EXPORT const char* const BASE64;
@ -95,16 +95,16 @@ namespace vmime
/** Constants for content disposition types (RFC-2183). */
namespace contentDispositionTypes
{
namespace contentDispositionTypes {
extern VMIME_EXPORT const char* const INLINE;
extern VMIME_EXPORT const char* const ATTACHMENT;
}
/** Constants for charsets. */
namespace charsets
{
namespace charsets {
extern VMIME_EXPORT const char* const ISO8859_1;
extern VMIME_EXPORT const char* const ISO8859_2;
extern VMIME_EXPORT const char* const ISO8859_3;
@ -169,8 +169,8 @@ namespace vmime
}
/** Constants for standard field names. */
namespace fields
{
namespace fields {
extern VMIME_EXPORT const char* const RECEIVED;
extern VMIME_EXPORT const char* const FROM;
extern VMIME_EXPORT const char* const SENDER;
@ -213,8 +213,8 @@ namespace vmime
}
/** Constants for disposition action modes (RFC-3978). */
namespace dispositionActionModes
{
namespace dispositionActionModes {
/** User implicitely displayed or deleted the message (filter or
* any other automatic action). */
extern VMIME_EXPORT const char* const AUTOMATIC;
@ -224,8 +224,8 @@ namespace vmime
}
/** Constants for disposition sending modes (RFC-3798). */
namespace dispositionSendingModes
{
namespace dispositionSendingModes {
/** The MDN was sent because the MUA had previously been configured
* to do so automatically. */
extern VMIME_EXPORT const char* const SENT_AUTOMATICALLY;
@ -235,8 +235,8 @@ namespace vmime
}
/** Constants for disposition types (RFC-3798). */
namespace dispositionTypes
{
namespace dispositionTypes {
/** Message has been displayed to the user. */
extern VMIME_EXPORT const char* const DISPLAYED;
/** Message has been deleted without being displayed. */
@ -246,8 +246,8 @@ namespace vmime
}
/** Constants for disposition modifiers (RFC-3798). */
namespace dispositionModifiers
{
namespace dispositionModifiers {
extern VMIME_EXPORT const char* const ERROR;
}
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -25,107 +25,118 @@
#include "vmime/utility/stringUtils.hpp"
namespace vmime
{
namespace vmime {
contentDisposition::contentDisposition()
: m_name(contentDispositionTypes::INLINE)
{
: m_name(contentDispositionTypes::INLINE) {
}
contentDisposition::contentDisposition(const string& name)
: m_name(utility::stringUtils::toLower(name))
{
: m_name(utility::stringUtils::toLower(name)) {
}
contentDisposition::contentDisposition(const contentDisposition& type)
: headerFieldValue(), m_name(type.m_name)
{
: headerFieldValue(), m_name(type.m_name) {
}
void contentDisposition::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
m_name = utility::stringUtils::trim(utility::stringUtils::toLower
(string(buffer.begin() + position, buffer.begin() + end)));
void contentDisposition::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_name = utility::stringUtils::trim(
utility::stringUtils::toLower(
string(buffer.begin() + position, buffer.begin() + end)
)
);
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void contentDisposition::generateImpl
(const generationContext& /* ctx */, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void contentDisposition::generateImpl(
const generationContext& /* ctx */,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
os << m_name;
if (newLinePos)
if (newLinePos) {
*newLinePos = curLinePos + m_name.length();
}
}
contentDisposition& contentDisposition::operator=(const string& name)
{
contentDisposition& contentDisposition::operator=(const string& name) {
m_name = utility::stringUtils::toLower(name);
return (*this);
return *this;
}
bool contentDisposition::operator==(const contentDisposition& value) const
{
return (utility::stringUtils::toLower(m_name) == value.m_name);
bool contentDisposition::operator==(const contentDisposition& value) const {
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);
}
shared_ptr <component> contentDisposition::clone() const
{
shared_ptr <component> contentDisposition::clone() const {
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);
m_name = d.m_name;
}
contentDisposition& contentDisposition::operator=(const contentDisposition& other)
{
contentDisposition& contentDisposition::operator=(const contentDisposition& other) {
copyFrom(other);
return (*this);
return *this;
}
const string& contentDisposition::getName() const
{
return (m_name);
const string& contentDisposition::getName() const {
return m_name;
}
void contentDisposition::setName(const string& name)
{
void contentDisposition::setName(const string& 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> >();
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/headerFieldValue.hpp"
namespace vmime
{
namespace vmime {
/** Content disposition (basic type).
*/
class VMIME_EXPORT contentDisposition : public headerFieldValue {
class VMIME_EXPORT contentDisposition : public headerFieldValue
{
public:
contentDisposition();
@ -78,18 +76,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -25,132 +25,136 @@
#include "vmime/exception.hpp"
namespace vmime
{
namespace vmime {
contentDispositionField::contentDispositionField()
{
contentDispositionField::contentDispositionField() {
}
contentDispositionField::contentDispositionField(contentDispositionField&)
: parameterizedHeaderField()
{
: parameterizedHeaderField() {
}
bool contentDispositionField::hasCreationDate() const
{
bool contentDispositionField::hasCreationDate() const {
return hasParameter("creation-date");
}
const datetime contentDispositionField::getCreationDate() const
{
const datetime contentDispositionField::getCreationDate() const {
shared_ptr <parameter> param = findParameter("creation-date");
if (param)
if (param) {
return param->getValueAs <datetime>();
else
} else {
return datetime::now();
}
}
void contentDispositionField::setCreationDate(const datetime& creationDate)
{
void contentDispositionField::setCreationDate(const datetime& creationDate) {
getParameter("creation-date")->setValue(creationDate);
}
bool contentDispositionField::hasModificationDate() const
{
bool contentDispositionField::hasModificationDate() const {
return hasParameter("modification-date");
}
const datetime contentDispositionField::getModificationDate() const
{
const datetime contentDispositionField::getModificationDate() const {
shared_ptr <parameter> param = findParameter("modification-date");
if (param)
if (param) {
return param->getValueAs <datetime>();
else
} else {
return datetime::now();
}
}
void contentDispositionField::setModificationDate(const datetime& modificationDate)
{
void contentDispositionField::setModificationDate(const datetime& modificationDate) {
getParameter("modification-date")->setValue(modificationDate);
}
bool contentDispositionField::hasReadDate() const
{
bool contentDispositionField::hasReadDate() const {
return hasParameter("read-date");
}
const datetime contentDispositionField::getReadDate() const
{
const datetime contentDispositionField::getReadDate() const {
shared_ptr <parameter> param = findParameter("read-date");
if (param)
if (param) {
return param->getValueAs <datetime>();
else
} else {
return datetime::now();
}
}
void contentDispositionField::setReadDate(const datetime& readDate)
{
void contentDispositionField::setReadDate(const datetime& readDate) {
getParameter("read-date")->setValue(readDate);
}
bool contentDispositionField::hasFilename() const
{
bool contentDispositionField::hasFilename() const {
return hasParameter("filename");
}
const word contentDispositionField::getFilename() const
{
const word contentDispositionField::getFilename() const {
shared_ptr <parameter> param = findParameter("filename");
if (param)
if (param) {
return param->getValue();
else
} else {
return word();
}
}
void contentDispositionField::setFilename(const word& filename)
{
void contentDispositionField::setFilename(const word& filename) {
getParameter("filename")->setValue(filename);
}
bool contentDispositionField::hasSize() const
{
bool contentDispositionField::hasSize() const {
return hasParameter("size");
}
const string contentDispositionField::getSize() const
{
const string contentDispositionField::getSize() const {
shared_ptr <parameter> param = findParameter("size");
if (param)
if (param) {
return param->getValue().getBuffer();
else
} else {
return "";
}
}
void contentDispositionField::setSize(const string& size)
{
void contentDispositionField::setSize(const string& size) {
getParameter("size")->setValue(word(size, vmime::charsets::US_ASCII));
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -32,15 +32,13 @@
#include "vmime/word.hpp"
namespace vmime
{
namespace vmime {
/** Describes presentation information, as per RFC-2183.
*/
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField {
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField
{
friend class headerFieldFactory;
protected:

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -24,16 +24,15 @@
#include "vmime/contentHandler.hpp"
namespace vmime
{
namespace vmime {
// No encoding = "binary" encoding
const encoding contentHandler::NO_ENCODING(encodingTypes::BINARY);
contentHandler::~contentHandler()
{
contentHandler::~contentHandler() {
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -34,12 +34,11 @@
#include "vmime/mediaType.hpp"
namespace vmime
{
namespace vmime {
class VMIME_EXPORT contentHandler : public object
{
class VMIME_EXPORT contentHandler : public object {
public:
/** Used to specify that enclosed data is not encoded. */
@ -63,7 +62,11 @@ public:
* @param enc encoding 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
* will be decoded before being written into the stream.
@ -74,7 +77,10 @@ public:
* @param progress progress listener, or NULL if you do not
* 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
* 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
* 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
* length was specified when setting data of this object, or if the

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -25,89 +25,90 @@
#include "vmime/exception.hpp"
namespace vmime
{
namespace vmime {
contentTypeField::contentTypeField()
{
contentTypeField::contentTypeField() {
}
contentTypeField::contentTypeField(contentTypeField&)
: parameterizedHeaderField()
{
: parameterizedHeaderField() {
}
bool contentTypeField::hasBoundary() const
{
bool contentTypeField::hasBoundary() const {
return hasParameter("boundary");
}
const string contentTypeField::getBoundary() const
{
const string contentTypeField::getBoundary() const {
shared_ptr <parameter> param = findParameter("boundary");
if (param)
if (param) {
return param->getValue().getBuffer();
else
} else {
return "";
}
}
void contentTypeField::setBoundary(const string& boundary)
{
void contentTypeField::setBoundary(const string& boundary) {
getParameter("boundary")->setValue(word(boundary, vmime::charsets::US_ASCII));
}
bool contentTypeField::hasCharset() const
{
bool contentTypeField::hasCharset() const {
return hasParameter("charset");
}
const charset contentTypeField::getCharset() const
{
const charset contentTypeField::getCharset() const {
shared_ptr <parameter> param = findParameter("charset");
if (param)
if (param) {
return param->getValueAs <charset>();
else
} else {
return charset();
}
}
void contentTypeField::setCharset(const charset& ch)
{
void contentTypeField::setCharset(const charset& ch) {
getParameter("charset")->setValue(ch);
}
bool contentTypeField::hasReportType() const
{
bool contentTypeField::hasReportType() const {
return hasParameter("report-type");
}
const string contentTypeField::getReportType() const
{
const string contentTypeField::getReportType() const {
shared_ptr <parameter> param = findParameter("report-type");
if (param)
if (param) {
return param->getValue().getBuffer();
else
} else {
return "";
}
}
void contentTypeField::setReportType(const string& reportType)
{
void contentTypeField::setReportType(const string& reportType) {
getParameter("report-type")->setValue(word(reportType, vmime::charsets::US_ASCII));
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -31,12 +31,11 @@
#include "vmime/charset.hpp"
namespace vmime
{
namespace vmime {
class VMIME_EXPORT contentTypeField : public parameterizedHeaderField
{
class VMIME_EXPORT contentTypeField : public parameterizedHeaderField {
friend class headerFieldFactory;
protected:

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -24,61 +24,60 @@
#include "vmime/context.hpp"
namespace vmime
{
namespace vmime {
context::context()
: m_internationalizedEmail(false)
{
: m_internationalizedEmail(false) {
}
context::context(const context& ctx)
: 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;
}
void context::setInternationalizedEmailSupport(const bool support)
{
void context::setInternationalizedEmailSupport(const bool support) {
m_internationalizedEmail = support;
}
const charsetConverterOptions& context::getCharsetConversionOptions() const
{
const charsetConverterOptions& context::getCharsetConversionOptions() const {
return m_charsetConvOptions;
}
void context::setCharsetConversionOptions(const charsetConverterOptions& opts)
{
void context::setCharsetConversionOptions(const charsetConverterOptions& opts) {
m_charsetConvOptions = opts;
}
context& context::operator=(const context& ctx)
{
context& context::operator=(const context& ctx) {
copyFrom(ctx);
return *this;
}
void context::copyFrom(const context& ctx)
{
void context::copyFrom(const context& ctx) {
m_internationalizedEmail = ctx.m_internationalizedEmail;
m_charsetConvOptions = ctx.m_charsetConvOptions;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/charsetConverterOptions.hpp"
namespace vmime
{
namespace vmime {
/** Holds configuration parameters used either for parsing or generating messages.
*/
class VMIME_EXPORT context : public object {
class VMIME_EXPORT context : public object
{
public:
virtual ~context();
@ -74,8 +72,8 @@ public:
/** Switches between contexts temporarily.
*/
template <typename CTX_CLASS>
class switcher
{
class switcher {
public:
/** Switches to the specified context.
@ -85,15 +83,15 @@ public:
* @param newCtx new context
*/
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);
}
/** Restores back saved context.
*/
~switcher()
{
~switcher() {
CTX_CLASS::getDefaultContext().copyFrom(m_oldCtxData);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -31,21 +31,31 @@
#include <ctime>
namespace vmime
{
namespace vmime {
/** Date and time (basic type).
*/
class VMIME_EXPORT datetime : public headerFieldValue {
class VMIME_EXPORT datetime : public headerFieldValue
{
public:
// Constructors
datetime();
datetime(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 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 string& date);
datetime(const time_t t, const int zone = GMT);
@ -54,8 +64,8 @@ public:
~datetime();
// Some time zones (in minutes)
enum TimeZones
{
enum TimeZones {
GMT_12 = -720, // GMT-12h
GMT_11 = -660, // GMT-11h
GMT_10 = -600, // GMT-10h
@ -124,8 +134,8 @@ public:
};
// Months list
enum Months
{
enum Months {
// Long
JANUARY = 1,
FEBRUARY = 2,
@ -155,8 +165,8 @@ public:
};
// Days of week list
enum DaysOfWeek
{
enum DaysOfWeek {
// Long
SUNDAY = 0,
MONDAY = 1,
@ -242,18 +252,20 @@ public:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -28,57 +28,75 @@
#include "vmime/encoding.hpp"
namespace vmime
{
namespace vmime {
defaultAttachment::defaultAttachment()
{
defaultAttachment::defaultAttachment() {
}
defaultAttachment::defaultAttachment(shared_ptr <const contentHandler> data,
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(
const shared_ptr <const contentHandler>& data,
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,
const mediaType& type, 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 shared_ptr <const contentHandler>& data,
const mediaType& type,
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)
: 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_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_desc = attach.m_desc;
m_name = attach.m_name;
m_data = vmime::clone(attach.m_data);
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
shared_ptr <bodyPart> part = make_shared <bodyPart>();
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
part->getHeader()->ContentType()->setValue(m_type);
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;
}
const text defaultAttachment::getDescription() const
{
const text defaultAttachment::getDescription() const {
return m_desc;
}
const word defaultAttachment::getName() const
{
const word defaultAttachment::getName() const {
return m_name;
}
const shared_ptr <const contentHandler> defaultAttachment::getData() const
{
const shared_ptr <const contentHandler> defaultAttachment::getData() const {
return m_data;
}
const encoding defaultAttachment::getEncoding() const
{
const encoding defaultAttachment::getEncoding() const {
return m_encoding;
}
shared_ptr <const object> defaultAttachment::getPart() const
{
shared_ptr <const object> defaultAttachment::getPart() const {
return null;
}
shared_ptr <const header> defaultAttachment::getHeader() const
{
shared_ptr <const header> defaultAttachment::getHeader() const {
return null;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/encoding.hpp"
namespace vmime
{
namespace vmime {
/** Default implementation for attachments.
*/
class VMIME_EXPORT defaultAttachment : public attachment {
class VMIME_EXPORT defaultAttachment : public attachment
{
protected:
// For use in derived classes.
@ -45,8 +43,21 @@ protected:
public:
defaultAttachment(shared_ptr <const contentHandler> data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD);
defaultAttachment(shared_ptr <const contentHandler> data, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD);
defaultAttachment(
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();
@ -74,11 +85,11 @@ protected:
private:
// 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:
virtual void generatePart(shared_ptr <bodyPart> part) const;
virtual void generatePart(const shared_ptr <bodyPart>& part) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -27,25 +27,30 @@
#include "vmime/utility/stringUtils.hpp"
namespace vmime
{
namespace vmime {
disposition::disposition()
{
disposition::disposition() {
}
disposition::disposition(const string& actionMode, const string& sendingMode,
const string& type, const string& modifier)
: m_actionMode(actionMode), m_sendingMode(sendingMode), m_type(type)
{
disposition::disposition(
const string& actionMode,
const string& sendingMode,
const string& type,
const string& modifier
)
: m_actionMode(actionMode),
m_sendingMode(sendingMode),
m_type(type) {
m_modifiers.push_back(modifier);
}
shared_ptr <component> disposition::clone() const
{
shared_ptr <component> disposition::clone() const {
shared_ptr <disposition> disp = make_shared <disposition>();
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());
return (disp);
return disp;
}
void disposition::copyFrom(const component& other)
{
void disposition::copyFrom(const component& other) {
const disposition& disp = dynamic_cast <const disposition&>(other);
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);
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> >();
}
void disposition::setActionMode(const string& mode)
{
void disposition::setActionMode(const string& mode) {
m_actionMode = mode;
}
const string& disposition::getActionMode() const
{
return (m_actionMode);
const string& disposition::getActionMode() const {
return m_actionMode;
}
void disposition::setSendingMode(const string& mode)
{
void disposition::setSendingMode(const string& mode) {
m_sendingMode = mode;
}
const string& disposition::getSendingMode() const
{
return (m_sendingMode);
const string& disposition::getSendingMode() const {
return m_sendingMode;
}
void disposition::setType(const string& type)
{
void disposition::setType(const string& type) {
m_type = type;
}
const string& disposition::getType() const
{
return (m_type);
const string& disposition::getType() const {
return m_type;
}
void disposition::addModifier(const string& modifier)
{
if (!hasModifier(modifier))
void disposition::addModifier(const string& modifier) {
if (!hasModifier(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);
for (std::vector <string>::iterator it = m_modifiers.begin() ;
it != m_modifiers.end() ; ++it)
{
if (*it == modifierLC)
{
it != m_modifiers.end() ; ++it) {
if (*it == modifierLC) {
m_modifiers.erase(it);
break;
}
@ -144,37 +149,42 @@ void disposition::removeModifier(const string& modifier)
}
void disposition::removeAllModifiers()
{
void disposition::removeAllModifiers() {
m_modifiers.clear();
}
bool disposition::hasModifier(const string& modifier) const
{
bool disposition::hasModifier(const string& modifier) const {
const string modifierLC = utility::stringUtils::toLower(modifier);
for (std::vector <string>::const_iterator it = m_modifiers.begin() ;
it != m_modifiers.end() ; ++it)
{
if (*it == modifierLC)
return (true);
it != m_modifiers.end() ; ++it) {
if (*it == modifierLC) {
return true;
}
}
return (false);
return false;
}
const std::vector <string> disposition::getModifierList() const
{
return (m_modifiers);
const std::vector <string> disposition::getModifierList() const {
return m_modifiers;
}
void disposition::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void disposition::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
// disposition-mode ";" disposition-type
// [ "/" disposition-modifier *( "," disposition-modifier ) ]
//
@ -182,105 +192,116 @@ void disposition::parseImpl
size_t pos = position;
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
// -- disposition-mode
const size_t modeStart = pos;
size_t modeEnd = pos;
while (pos < end && buffer[pos] != ';')
{
while (pos < end && buffer[pos] != ';') {
++modeEnd;
++pos;
}
while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1]))
while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1])) {
--modeEnd;
}
const string mode = string(buffer.begin() + modeStart, buffer.begin() + modeEnd);
const size_t slash = mode.find('/');
if (slash != string::npos)
{
if (slash != string::npos) {
m_actionMode = string(mode.begin(), mode.begin() + slash);
m_sendingMode = string(mode.begin() + slash + 1, mode.end());
}
else
{
} else {
m_actionMode = mode;
m_sendingMode.clear();
}
if (pos < end)
{
if (pos < end) {
// Skip ';'
++pos;
}
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
// -- disposition-type
const size_t typeStart = pos;
size_t typeEnd = pos;
while (pos < end && buffer[pos] != '/')
{
while (pos < end && buffer[pos] != '/') {
++typeEnd;
++pos;
}
while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1]))
while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1])) {
--typeEnd;
}
m_type = string(buffer.begin() + typeStart, buffer.begin() + typeEnd);
m_modifiers.clear();
if (pos < end) // modifiers follow
{
if (pos < end) { // modifiers follow
// Skip '/'
++pos;
while (pos < end)
{
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end) {
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
const size_t modifierStart = pos;
size_t modifierEnd = pos;
while (pos < end && buffer[pos] != ',')
{
while (pos < end && buffer[pos] != ',') {
++modifierEnd;
++pos;
}
while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1]))
while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1])) {
--modifierEnd;
}
if (modifierEnd > modifierStart)
{
m_modifiers.push_back(string(buffer.begin() + modifierStart,
buffer.begin() + modifierEnd));
if (modifierEnd > modifierStart) {
m_modifiers.push_back(
string(
buffer.begin() + modifierStart,
buffer.begin() + modifierEnd
)
);
}
// Skip ','
if (pos < end)
if (pos < end) {
++pos;
}
}
}
if (newPosition)
if (newPosition) {
*newPosition = pos;
}
}
void disposition::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void disposition::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
size_t pos = curLinePos;
const string actionMode = (m_actionMode.empty() ? "automatic-action" : m_actionMode);
@ -289,8 +310,7 @@ void disposition::generateImpl
os << actionMode << "/" << sendingMode << ";";
pos += actionMode.length() + 1 + sendingMode.length() + 1;
if (pos > ctx.getMaxLineLength())
{
if (pos > ctx.getMaxLineLength()) {
os << NEW_LINE_SEQUENCE;
pos = NEW_LINE_SEQUENCE_LENGTH;
}
@ -300,18 +320,19 @@ void disposition::generateImpl
os << type;
pos += type.length();
if (m_modifiers.size() >= 1)
{
for (std::vector <string>::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i)
{
if (m_modifiers.size() >= 1) {
for (std::vector <string>::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i) {
const string mod = utility::stringUtils::trim(m_modifiers[i]);
if (!mod.empty())
{
if (n == 0)
if (!mod.empty()) {
if (n == 0) {
os << "/";
else
} else {
os << ",";
}
os << mod;
pos += 1 + mod.length();
@ -321,9 +342,10 @@ void disposition::generateImpl
}
}
if (newLinePos)
if (newLinePos) {
*newLinePos = pos;
}
}
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -31,19 +31,22 @@
#include <vector>
namespace vmime
{
namespace vmime {
/** Disposition - from RFC-3798 (basic type).
*/
class VMIME_EXPORT disposition : public headerFieldValue {
class VMIME_EXPORT disposition : public headerFieldValue
{
public:
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;
@ -137,18 +140,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
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

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -31,8 +31,7 @@
#include "vmime/utility/stringUtils.hpp"
namespace vmime
{
namespace vmime {
/** Decode an IDNA-encoded domain name ("xn--5rtw95l.xn--wgv71a")
@ -41,48 +40,52 @@ namespace vmime
* @param idnaDomain domain name encoded with IDNA
* @return decoded domain name in UTF-8
*/
static const string domainNameFromIDNA(const string& idnaDomain)
{
static const string domainNameFromIDNA(const string& idnaDomain) {
std::ostringstream domainName;
size_t p = 0;
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);
if (encodedPart.length() > 4 &&
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
encodedPart[2] == '-' && encodedPart[3] == '-')
{
encodedPart[2] == '-' && encodedPart[3] == '-') {
string decodedPart;
charset::convert(encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8);
charset::convert(
encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8
);
domainName << decodedPart << '.';
}
else
{
} else {
domainName << encodedPart << '.'; // not encoded
}
}
if (p < idnaDomain.length())
{
if (p < idnaDomain.length()) {
const string encodedPart(idnaDomain.begin() + p, idnaDomain.end());
if (encodedPart.length() > 4 &&
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
encodedPart[2] == '-' && encodedPart[3] == '-')
{
encodedPart[2] == '-' && encodedPart[3] == '-') {
string decodedPart;
charset::convert(encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8);
charset::convert(
encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8
);
domainName << decodedPart;
}
else
{
} else {
domainName << encodedPart; // not encoded
}
}
@ -97,26 +100,30 @@ static const string domainNameFromIDNA(const string& idnaDomain)
* @param domainName domain name in UTF-8
* @return domain name encoded with IDNA
*/
static const string domainNameToIDNA(const string& domainName)
{
static const string domainNameToIDNA(const string& domainName) {
std::ostringstream idnaDomain;
size_t p = 0;
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;
charset::convert(string(domainName.begin() + p, domainName.begin() + n),
idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA);
charset::convert(
string(domainName.begin() + p, domainName.begin() + n), idnaPart,
vmime::charsets::UTF_8, vmime::charsets::IDNA
);
idnaDomain << idnaPart << '.';
}
if (p < domainName.length())
{
if (p < domainName.length()) {
string idnaPart;
charset::convert(string(domainName.begin() + p, domainName.end()),
idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA);
charset::convert(
string(domainName.begin() + p, domainName.end()), idnaPart,
vmime::charsets::UTF_8, vmime::charsets::IDNA
);
idnaDomain << idnaPart;
}
@ -127,52 +134,60 @@ static const string domainNameToIDNA(const string& domainName)
emailAddress::emailAddress()
{
emailAddress::emailAddress() {
}
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);
}
emailAddress::emailAddress(const char* email)
{
emailAddress::emailAddress(const char* email) {
parse(email);
}
emailAddress::emailAddress(const string& localName, const string& domainName)
: component(), m_localName(word(localName, vmime::charsets::UTF_8)),
m_domainName(word(domainName, vmime::charsets::UTF_8))
{
: component(),
m_localName(word(localName, vmime::charsets::UTF_8)),
m_domainName(word(domainName, vmime::charsets::UTF_8)) {
}
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
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void emailAddress::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
const char* const pend = buffer.data() + end;
const char* const pstart = buffer.data() + position;
const char* p = pstart;
enum ParserStates
{
enum ParserStates {
State_Before,
State_LocalPartStart,
State_LocalPartMiddle,
@ -199,45 +214,47 @@ void emailAddress::parseImpl
int commentLevel = 0;
bool localPartIsRFC2047 = false;
while (p < pend && !stop)
{
while (p < pend && !stop) {
const char c = *p;
if ((localPart.str().length() + domainPart.str().length()) >= 256)
{
if ((localPart.str().length() + domainPart.str().length()) >= 256) {
state = State_Error;
break;
}
switch (state)
{
switch (state) {
case State_Before:
if (parserHelpers::isSpace(c))
if (parserHelpers::isSpace(c)) {
++p;
else
} else {
state = State_LocalPartStart;
}
break;
case State_LocalPartStart:
if (c == '"')
{
if (c == '"') {
state = State_LocalPartQuoted;
++p;
}
else if (c == '=')
{
} else if (c == '=') {
state = State_LocalPartRFC2047Start;
++p;
}
else if (c == '(')
{
} else if (c == '(') {
state = State_LocalPartComment;
++commentLevel;
++p;
}
else
{
} else {
state = State_LocalPartMiddle;
localPart << c;
++p;
@ -247,33 +264,32 @@ void emailAddress::parseImpl
case State_LocalPartComment:
if (escapeNext)
{
if (escapeNext) {
escapeNext = false;
++p;
}
else if (c == '\\')
{
} else if (c == '\\') {
escapeNext = true;
++p;
}
else if (c == '(')
{
} else if (c == '(') {
++commentLevel;
++p;
}
else if (c == ')')
{
if (--commentLevel == 0)
{
} else if (c == ')') {
if (--commentLevel == 0) {
// End of comment
state = State_LocalPartMiddle;
}
++p;
}
else
{
} else {
// Comment continues
++p;
}
@ -282,34 +298,34 @@ void emailAddress::parseImpl
case State_LocalPartQuoted:
if (escapeNext)
{
if (escapeNext) {
escapeNext = false;
if (c == '"' || c == '\\')
{
if (c == '"' || c == '\\') {
localPart << c;
++p;
}
else
{
} else {
// This char cannot be escaped
state = State_Error;
}
}
else if (c == '"')
{
} else if (c == '"') {
// End of quoted string
state = State_LocalPartMiddle;
++p;
}
else if (c == '\\')
{
} else if (c == '\\') {
escapeNext = true;
++p;
}
else
{
} else {
localPart << c;
++p;
}
@ -318,15 +334,15 @@ void emailAddress::parseImpl
case State_LocalPartRFC2047Start:
if (c == '?')
{
if (c == '?') {
state = State_LocalPartRFC2047Middle;
localPart << "=?";
localPartIsRFC2047 = true;
++p;
}
else
{
} else {
state = State_LocalPartMiddle;
localPart << '=';
localPart << c;
@ -337,39 +353,39 @@ void emailAddress::parseImpl
case State_LocalPartMiddle:
if (c == '.')
{
if (c == '.') {
prevIsDot = true;
localPart << c;
++p;
}
else if (c == '"' && prevIsDot)
{
} else if (c == '"' && prevIsDot) {
prevIsDot = false;
state = State_LocalPartQuoted;
++p;
}
else if (c == '(')
{
} else if (c == '(') {
// By allowing comments anywhere in the local part,
// we are more permissive than RFC-2822
state = State_LocalPartComment;
++commentLevel;
++p;
}
else if (c == '@')
{
} else if (c == '@') {
atFound = true;
state = State_DomainPartStart;
++p;
}
else if (parserHelpers::isSpace(c))
{
} else if (parserHelpers::isSpace(c)) {
// Allow not specifying domain part
state = State_End;
}
else
{
} else {
prevIsDot = false;
localPart << c;
++p;
@ -379,13 +395,13 @@ void emailAddress::parseImpl
case State_LocalPartRFC2047Middle:
if (c == '?')
{
if (c == '?') {
state = State_LocalPartRFC2047MiddleQM;
++p;
}
else
{
} else {
localPart << c;
++p;
}
@ -394,15 +410,15 @@ void emailAddress::parseImpl
case State_LocalPartRFC2047MiddleQM:
if (c == '=')
{
if (c == '=') {
// End of RFC-2047 encoded word
state = State_LocalPartRFC2047End;
localPart << "?=";
++p;
}
else
{
} else {
state = State_LocalPartRFC2047Middle;
localPart << '?';
localPart << c;
@ -413,14 +429,14 @@ void emailAddress::parseImpl
case State_LocalPartRFC2047End:
if (c == '@')
{
if (c == '@') {
atFound = true;
state = State_DomainPartStart;
++p;
}
else
{
} else {
state = State_End;
}
@ -428,14 +444,14 @@ void emailAddress::parseImpl
case State_DomainPartStart:
if (c == '(')
{
if (c == '(') {
state = State_DomainPartComment;
++commentLevel;
++p;
}
else
{
} else {
state = State_DomainPartMiddle;
domainPart << c;
++p;
@ -445,20 +461,20 @@ void emailAddress::parseImpl
case State_DomainPartMiddle:
if (parserHelpers::isSpace(c))
{
if (parserHelpers::isSpace(c)) {
state = State_End;
}
else if (c == '(')
{
} else if (c == '(') {
// By allowing comments anywhere in the domain part,
// we are more permissive than RFC-2822
state = State_DomainPartComment;
++commentLevel;
++p;
}
else
{
} else {
domainPart << c;
++p;
}
@ -467,33 +483,33 @@ void emailAddress::parseImpl
case State_DomainPartComment:
if (escapeNext)
{
if (escapeNext) {
escapeNext = false;
++p;
}
else if (c == '\\')
{
} else if (c == '\\') {
escapeNext = true;
++p;
}
else if (c == '(')
{
} else if (c == '(') {
++commentLevel;
++p;
}
else if (c == ')')
{
if (--commentLevel == 0)
{
} else if (c == ')') {
if (--commentLevel == 0) {
// End of comment
state = State_DomainPartMiddle;
}
++p;
}
else
{
} else {
// Comment continues
++p;
}
@ -508,50 +524,57 @@ void emailAddress::parseImpl
}
}
if (p == pend && state != State_Error)
{
if (state == State_DomainPartMiddle)
if (p == pend && state != State_Error) {
if (state == State_DomainPartMiddle) {
state = State_End;
else if (state == State_LocalPartMiddle)
} else if (state == State_LocalPartMiddle) {
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_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());
else
} else {
m_localName = word(localPart.str(), vmime::charsets::UTF_8);
}
m_domainName = word(domainNameFromIDNA(domainPart.str()), vmime::charsets::UTF_8);
}
setParsedBounds(position, p - pend);
if (newPosition)
if (newPosition) {
*newPosition = p - pend;
}
}
void emailAddress::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void emailAddress::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
string localPart, domainPart;
if (ctx.getInternationalizedEmailSupport() &&
(!utility::stringUtils::is7bit(m_localName.getBuffer()) ||
!utility::stringUtils::is7bit(m_domainName.getBuffer())))
{
!utility::stringUtils::is7bit(m_domainName.getBuffer()))) {
// Local part
string localPartUTF8(m_localName.getConvertedText(vmime::charsets::UTF_8));
word localPartWord(localPartUTF8, vmime::charsets::UTF_8);
@ -561,9 +584,9 @@ void emailAddress::generateImpl
// Domain part
domainPart = m_domainName.getConvertedText(vmime::charsets::UTF_8);
}
else
{
} else {
// Local part
vmime::utility::outputStreamStringAdapter os(localPart);
m_localName.generate(ctx, os, 0, NULL, text::QUOTE_IF_NEEDED, NULL);
@ -576,8 +599,8 @@ void emailAddress::generateImpl
<< "@"
<< domainPart;
if (newLinePos)
{
if (newLinePos) {
*newLinePos = curLinePos
+ localPart.length()
+ 1 // @
@ -586,21 +609,21 @@ void emailAddress::generateImpl
}
bool emailAddress::operator==(const class emailAddress& eml) const
{
return (m_localName == eml.m_localName &&
m_domainName == eml.m_domainName);
bool emailAddress::operator==(const class emailAddress& eml) const {
return m_localName == eml.m_localName &&
m_domainName == eml.m_domainName;
}
bool emailAddress::operator!=(const class emailAddress& eml) const
{
bool emailAddress::operator!=(const class emailAddress& eml) const {
return !(*this == eml);
}
void emailAddress::copyFrom(const component& other)
{
void emailAddress::copyFrom(const component& other) {
const emailAddress& source = dynamic_cast <const emailAddress&>(other);
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);
return (*this);
return *this;
}
shared_ptr <component>emailAddress::clone() const
{
shared_ptr <component>emailAddress::clone() const {
return make_shared <emailAddress>(*this);
}
const word& emailAddress::getLocalName() const
{
const word& emailAddress::getLocalName() const {
return m_localName;
}
void emailAddress::setLocalName(const word& localName)
{
void emailAddress::setLocalName(const word& localName) {
m_localName = localName;
}
const word& emailAddress::getDomainName() const
{
const word& emailAddress::getDomainName() const {
return m_domainName;
}
void emailAddress::setDomainName(const word& domainName)
{
void emailAddress::setDomainName(const word& 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> >();
}
bool emailAddress::isEmpty() const
{
bool emailAddress::isEmpty() const {
return m_localName.isEmpty();
}
const string emailAddress::toString() const
{
const string emailAddress::toString() const {
std::ostringstream 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;
txt.appendWord(make_shared <vmime::word>(m_localName));
txt.appendWord(make_shared <vmime::word>("@", vmime::charsets::US_ASCII));

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/text.hpp"
namespace vmime
{
namespace vmime {
/** An email address: local name and domain name (basic type).
*/
class VMIME_EXPORT emailAddress : public component {
class VMIME_EXPORT emailAddress : public component
{
public:
emailAddress();
@ -114,18 +112,20 @@ public:
using component::generate;
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -24,92 +24,101 @@
#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>();
}
void emptyContentHandler::generate(utility::outputStream& /* os */, const vmime::encoding& /* enc */,
const size_t /* maxLineLength */) const
{
void emptyContentHandler::generate(
utility::outputStream& /* os */,
const vmime::encoding& /* enc */,
const size_t /* maxLineLength */
) const {
// Nothing to do.
}
void emptyContentHandler::extract(utility::outputStream& /* os */,
void emptyContentHandler::extract(
utility::outputStream& /* os */,
utility::progressListener* progress) const
{
if (progress)
if (progress) {
progress->start(0);
}
// Nothing to do.
if (progress)
if (progress) {
progress->stop(0);
}
}
void emptyContentHandler::extractRaw(utility::outputStream& /* os */,
utility::progressListener* progress) const
{
if (progress)
void emptyContentHandler::extractRaw(
utility::outputStream& /* os */,
utility::progressListener* progress
) const {
if (progress) {
progress->start(0);
}
// Nothing to do.
if (progress)
if (progress) {
progress->stop(0);
}
size_t emptyContentHandler::getLength() const
{
return (0);
}
bool emptyContentHandler::isEmpty() const
{
return (true);
size_t emptyContentHandler::getLength() const {
return 0;
}
bool emptyContentHandler::isEncoded() const
{
return (false);
}
bool emptyContentHandler::isEmpty() const {
const vmime::encoding& emptyContentHandler::getEncoding() const
{
return (NO_ENCODING);
}
bool emptyContentHandler::isBuffered() const
{
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;
}
const mediaType emptyContentHandler::getContentTypeHint() const
{
const mediaType emptyContentHandler::getContentTypeHint() const {
return m_contentType;
}

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -28,22 +28,32 @@
#include "vmime/contentHandler.hpp"
namespace vmime
{
namespace vmime {
class VMIME_EXPORT emptyContentHandler : public contentHandler
{
class VMIME_EXPORT emptyContentHandler : public contentHandler {
public:
emptyContentHandler();
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 extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const;
void extract(
utility::outputStream& os,
utility::progressListener* progress = NULL
) const;
void extractRaw(
utility::outputStream& os,
utility::progressListener* progress = NULL
) const;
size_t getLength() const;

View File

@ -1,6 +1,6 @@
//
// 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
// modify it under the terms of the GNU General Public License as
@ -30,118 +30,140 @@
#include <algorithm>
namespace vmime
{
namespace vmime {
encoding::encoding()
: m_name(encodingTypes::SEVEN_BIT),
m_usage(USAGE_UNKNOWN)
{
m_usage(USAGE_UNKNOWN) {
}
encoding::encoding(const string& name)
: m_name(utility::stringUtils::toLower(name)),
m_usage(USAGE_UNKNOWN)
{
m_usage(USAGE_UNKNOWN) {
}
encoding::encoding(const string& name, const EncodingUsage usage)
: m_name(utility::stringUtils::toLower(name)),
m_usage(usage)
{
m_usage(usage) {
}
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
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void encoding::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_usage = USAGE_UNKNOWN;
m_name = utility::stringUtils::toLower(utility::stringUtils::trim
(utility::stringUtils::unquote(utility::stringUtils::trim
(string(buffer.begin() + position, buffer.begin() + end)))));
m_name = utility::stringUtils::toLower(
utility::stringUtils::trim(
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"
}
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
void encoding::generateImpl
(const generationContext& /* ctx */, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
os << m_name;
if (newLinePos)
*newLinePos = curLinePos + m_name.length();
}
shared_ptr <utility::encoder::encoder> encoding::getEncoder() const
{
void encoding::generateImpl(
const generationContext& /* ctx */,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
os << m_name;
if (newLinePos) {
*newLinePos = curLinePos + m_name.length();
}
}
shared_ptr <utility::encoder::encoder> encoding::getEncoder() const {
shared_ptr <utility::encoder::encoder> encoder =
utility::encoder::encoderFactory::getInstance()->create(generate());
// 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;
}
return encoder;
}
encoding& encoding::operator=(const encoding& other)
{
encoding& encoding::operator=(const encoding& other) {
copyFrom(other);
return (*this);
}
encoding& encoding::operator=(const string& name)
{
encoding& encoding::operator=(const string& name) {
m_name = utility::stringUtils::toLower(name);
m_usage = USAGE_UNKNOWN;
return (*this);
return *this;
}
bool encoding::operator==(const encoding& value) const
{
return (utility::stringUtils::toLower(m_name) == value.m_name);
bool encoding::operator==(const encoding& value) const {
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);
}
const encoding encoding::decideImpl
(const string::const_iterator begin, const string::const_iterator end)
{
const encoding encoding::decideImpl(
const string::const_iterator begin,
const string::const_iterator end
) {
const string::difference_type length = end - begin;
const string::difference_type count = std::count_if
(begin, end, std::bind2nd(std::less<unsigned char>(), 127));
const string::difference_type count = std::count_if(
begin, end,
std::bind2nd(std::less<unsigned char>(), 127)
);
// 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
// "lineLengthLimits::convenient" characters (7-bit requires that)
string::const_iterator p = begin;
@ -149,49 +171,51 @@ const encoding encoding::decideImpl
const size_t maxLen = lineLengthLimits::convenient;
size_t len = 0;
for ( ; p != end && len <= maxLen ; )
{
if (*p == '\n')
{
for ( ; p != end && len <= maxLen ; ) {
if (*p == '\n') {
len = 0;
++p;
// May or may not need to be encoded, we don't take
// any risk (avoid problems with SMTP)
if (p != end && *p == '.')
if (p != end && *p == '.') {
len = maxLen + 1;
}
else
{
} else {
++len;
++p;
}
}
if (len > maxLen)
return (encoding(encodingTypes::QUOTED_PRINTABLE));
else
return (encoding(encodingTypes::SEVEN_BIT));
if (len > maxLen) {
return encoding(encodingTypes::QUOTED_PRINTABLE);
} else {
return encoding(encodingTypes::SEVEN_BIT);
}
// Less than 20% non US-ASCII --> Quoted-Printable
else if ((length - count) <= length / 5)
{
return (encoding(encodingTypes::QUOTED_PRINTABLE));
}
} else if ((length - count) <= length / 5) {
return encoding(encodingTypes::QUOTED_PRINTABLE);
// Otherwise --> Base64
else
{
return (encoding(encodingTypes::BASE64));
} else {
return encoding(encodingTypes::BASE64);
}
}
bool encoding::shouldReencode() const
{
bool encoding::shouldReencode() const {
if (m_name == encodingTypes::BASE64 ||
m_name == encodingTypes::QUOTED_PRINTABLE ||
m_name == encodingTypes::UUENCODE)
{
m_name == encodingTypes::UUENCODE) {
return false;
}
@ -199,18 +223,21 @@ bool encoding::shouldReencode() const
}
const encoding encoding::decide
(shared_ptr <const contentHandler> data, const EncodingUsage usage)
{
const encoding encoding::decide(
const shared_ptr <const contentHandler>& data,
const EncodingUsage usage
) {
// 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();
}
encoding enc;
if (usage == USAGE_TEXT && data->isBuffered() &&
data->getLength() > 0 && data->getLength() < 32768)
{
data->getLength() > 0 && data->getLength() < 32768) {
// Extract data into temporary buffer
string buffer;
utility::outputStreamStringAdapter os(buffer);
@ -219,9 +246,9 @@ const encoding encoding::decide
os.flush();
enc = decideImpl(buffer.begin(), buffer.end());
}
else
{
} else {
enc = encoding(encodingTypes::BASE64);
}
@ -231,19 +258,23 @@ const encoding encoding::decide
}
const encoding encoding::decide(shared_ptr <const contentHandler> data,
const charset& chset, const EncodingUsage usage)
{
// Do not re-encode data if it is already encoded
if (data->isEncoded() && !data->getEncoding().shouldReencode())
return data->getEncoding();
const encoding encoding::decide(
const shared_ptr <const contentHandler>& data,
const charset& chset,
const EncodingUsage usage
) {
// 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;
if (chset.getRecommendedEncoding(recEncoding))
{
if (chset.getRecommendedEncoding(recEncoding)) {
recEncoding.setUsage(usage);
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);
}
void encoding::copyFrom(const component& other)
{
void encoding::copyFrom(const component& other) {
const encoding& e = dynamic_cast <const encoding&>(other);
m_name = e.m_name;
}
const string& encoding::getName() const
{
return (m_name);
const string& encoding::getName() const {
return m_name;
}
void encoding::setName(const string& name)
{
void encoding::setName(const string& name) {
m_name = name;
}
encoding::EncodingUsage encoding::getUsage() const
{
encoding::EncodingUsage encoding::getUsage() const {
return m_usage;
}
void encoding::setUsage(const EncodingUsage usage)
{
void encoding::setUsage(const EncodingUsage 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> >();
}

Some files were not shown because too many files have changed in this diff Show More