removed Var iterators, fixed SOO alignment

- removed unnecessary using directives in Data library
- removed iterator pointers from Var (reduce size, always return copy)
- added Alignment header (adapted from LLVM infrastructure)
- added alignment guards to SOO implementations
This commit is contained in:
Aleksandar Fabijanic 2013-05-29 23:36:28 -05:00
parent 51fdec593e
commit e5eaffb790
19 changed files with 502 additions and 140 deletions

View File

@ -68,6 +68,8 @@ Release 1.5.2 (2013-06-xx)
- added JSON conversion to Dynamic Struct and Array
- added VarIterator
- modified behavior of empty Var (empty == empty)
- added Alignment.h header for C++03 alignment needs
Release 1.5.1 (2013-01-11)
==========================

View File

@ -222,7 +222,6 @@ inline void swap(LOB<T>& b1, LOB<T>& b2)
namespace std
{
using std::swap;
template<>
inline void swap<Poco::Data::BLOB>(Poco::Data::BLOB& b1,
Poco::Data::BLOB& b2)

View File

@ -159,7 +159,6 @@ inline bool RowIterator::operator != (const RowIterator& other) const
namespace std
{
using std::swap;
template<>
inline void swap<Poco::Data::RowIterator>(Poco::Data::RowIterator& s1,
Poco::Data::RowIterator& s2)

View File

@ -503,7 +503,6 @@ inline void swap(Session& s1, Session& s2)
namespace std
{
using std::swap;
template<>
inline void swap<Poco::Data::Session>(Poco::Data::Session& s1,
Poco::Data::Session& s2)

View File

@ -820,7 +820,6 @@ inline void swap(Statement& s1, Statement& s2)
namespace std
{
using std::swap;
template<>
inline void swap<Poco::Data::Statement>(Poco::Data::Statement& s1,
Poco::Data::Statement& s2)

View File

@ -983,6 +983,7 @@
<ClCompile Include="src\HashStatistic.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\Poco\Alignment.h" />
<ClInclude Include="include\Poco\Any.h" />
<ClInclude Include="include\Poco\Array.h" />
<ClInclude Include="include\Poco\Ascii.h" />

View File

@ -1883,6 +1883,9 @@
<ClInclude Include="include\Poco\Optional.h">
<Filter>Core\Header Files</Filter>
</ClInclude>
<ClInclude Include="include\Poco\Alignment.h">
<Filter>Core\Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="src\pocomsg.rc">

View File

@ -0,0 +1,230 @@
//
// Alignment.h
//
// $Id: //poco/svn/Foundation/include/Poco/Alignment.h#2 $
//
// Library: Foundation
// Package: Dynamic
// Module: Alignment
//
// Definition of the Alignment class.
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Adapted for POCO from LLVM Compiler Infrastructure code:
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source License
//
//===----------------------------------------------------------------------===//
//
// This file defines the AlignOf function that computes alignments for
// arbitrary types.
//
//===----------------------------------------------------------------------===//
#ifndef Foundation_AlignOf_INCLUDED
#define Foundation_AlignOf_INCLUDED
namespace Poco {
template <typename T>
struct AlignmentCalcImpl
{
char x;
T t;
private:
AlignmentCalcImpl() {} // Never instantiate.
};
template <typename T>
struct AlignOf
/// A templated class that contains an enum value representing
/// the alignment of the template argument. For example,
/// AlignOf<int>::Alignment represents the alignment of type "int". The
/// alignment calculated is the minimum alignment, and not necessarily
/// the "desired" alignment returned by GCC's __alignof__ (for example). Note
/// that because the alignment is an enum value, it can be used as a
/// compile-time constant (e.g., for template instantiation).
{
enum
{
Alignment = static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T))
};
enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
};
template <typename T>
inline unsigned alignOf()
/// A templated function that returns the minimum alignment of
/// of a type. This provides no extra functionality beyond the AlignOf
/// class besides some cosmetic cleanliness. Example usage:
/// alignOf<int>() returns the alignment of an int.
{
return AlignOf<T>::Alignment;
}
template <size_t Alignment> struct AlignedCharArrayImpl;
/// Helper for building an aligned character array type.
///
/// This template is used to explicitly build up a collection of aligned
/// character types. We have to build these up using a macro and explicit
/// specialization to cope with old versions of MSVC and GCC where only an
/// integer literal can be used to specify an alignment constraint. Once built
/// up here, we can then begin to indirect between these using normal C++
/// template parameters.
// MSVC requires special handling here.
#ifndef _MSC_VER
#if __has_feature(cxx_alignas)
#define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
template <> struct AlignedCharArrayImpl<x> \
{ \
char alignas(x) aligned; \
}
#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
#define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
template <> struct AlignedCharArrayImpl<x> \
{ \
char aligned __attribute__((aligned(x))); \
}
#else
# error No supported align as directive.
#endif
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
#undef POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
#else // _MSC_VER
// We provide special variations of this template for the most common
// alignments because __declspec(align(...)) doesn't actually work when it is
// a member of a by-value function argument in MSVC, even if the alignment
// request is something reasonably like 8-byte or 16-byte.
template <> struct AlignedCharArrayImpl<1> { char aligned; };
template <> struct AlignedCharArrayImpl<2> { short aligned; };
template <> struct AlignedCharArrayImpl<4> { int aligned; };
template <> struct AlignedCharArrayImpl<8> { double aligned; };
#define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
template <> struct AlignedCharArrayImpl<x> { \
__declspec(align(x)) char aligned; \
}
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
// Any larger and MSVC complains.
#undef POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
#endif // _MSC_VER
template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char>
union AlignedCharArrayUnion
/// This union template exposes a suitably aligned and sized character
/// array member which can hold elements of any of up to four types.
///
/// These types may be arrays, structs, or any other types. The goal is to
/// produce a union type containing a character array which, when used, forms
/// storage suitable to placement new any of these types over. Support for more
/// than four types can be added at the cost of more boiler plate.
{
private:
class AlignerImpl
{
T1 t1;
T2 t2;
T3 t3;
T4 t4;
AlignerImpl(); // Never defined or instantiated.
};
union SizerImpl
{
char arr1[sizeof(T1)];
char arr2[sizeof(T2)];
char arr3[sizeof(T3)];
char arr4[sizeof(T4)];
};
public:
char buffer[sizeof(SizerImpl)];
/// The character array buffer for use by clients.
///
/// No other member of this union should be referenced. They exist purely to
/// constrain the layout of this character array.
private:
Poco::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment> _nonceMember;
};
} // namespace Poco
#endif // Foundation_AlignOf_INCLUDED

View File

@ -40,10 +40,13 @@
#include "Poco/Exception.h"
#include "Poco/MetaProgramming.h"
#include "Poco/Alignment.h"
#include <algorithm>
#include <typeinfo>
#include <cstring>
#ifdef POCO_ENABLE_CPP11
#include <type_traits>
#endif
namespace Poco {
@ -64,7 +67,7 @@ template <class> class VarHolderImpl;
template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE>
union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
/// object optimization).
/// object optimization, when enabled).
///
/// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
/// it will be placement-new-allocated into the local buffer
@ -86,23 +89,23 @@ public:
void erase()
{
std::memset(holder, 0, sizeof(Placeholder));
std::memset(holder.h, 0, sizeof(Placeholder));
}
bool isLocal() const
{
return holder[SizeV] != 0;
return holder.h[SizeV] != 0;
}
void setLocal(bool local) const
{
holder[SizeV] = local ? 1 : 0;
holder.h[SizeV] = local ? 1 : 0;
}
PlaceholderT* content() const
{
if(isLocal())
return reinterpret_cast<PlaceholderT*>(holder);
return reinterpret_cast<PlaceholderT*>(holder.h);
else
return pHolder;
}
@ -114,7 +117,14 @@ private:
PlaceholderT* pHolder;
#ifndef POCO_NO_SOO
mutable unsigned char holder[SizeV + 1];
#ifndef POCO_ENABLE_CPP11
#error "Any SOO can only be enabled with C++11 support"
#endif
mutable union
{
std::aligned_storage<SizeV + 1> a;
unsigned char h[SizeV + 1];
} holder;
#endif
friend class Any;
@ -130,7 +140,7 @@ private:
template <typename PlaceholderT>
union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
/// object optimization).
/// object optimization, when enabled).
///
/// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
/// it will be placement-new-allocated into the local buffer
@ -275,7 +285,7 @@ public:
/// Returns true if the Any is empty.
{
char buf[POCO_SMALL_OBJECT_SIZE] = { 0 };
return 0 == std::memcmp(_valueHolder.holder, buf, POCO_SMALL_OBJECT_SIZE);
return 0 == std::memcmp(_valueHolder.holder.h, buf, POCO_SMALL_OBJECT_SIZE);
}
const std::type_info & type() const
@ -318,7 +328,7 @@ private:
{
if ((sizeof(Holder<ValueType>) <= POCO_SMALL_OBJECT_SIZE))
{
new ((ValueHolder*) pPlaceholder->holder) Holder(_held);
new ((ValueHolder*) pPlaceholder->holder.h) Holder(_held);
pPlaceholder->setLocal(true);
}
else
@ -344,7 +354,7 @@ private:
{
if (sizeof(Holder<ValueType>) <= Placeholder<ValueType>::Size::value)
{
new (reinterpret_cast<ValueHolder*>(_valueHolder.holder)) Holder<ValueType>(value);
new (reinterpret_cast<ValueHolder*>(_valueHolder.holder.h)) Holder<ValueType>(value);
_valueHolder.setLocal(true);
}
else

View File

@ -100,11 +100,17 @@
// candidates) will be auto-allocated on the stack in
// cases when value holder fits into POCO_SMALL_OBJECT_SIZE
// (see below).
//
// !!! NOTE: Any/Dynamic::Var SOO may NOT work reliably
// !!! without C++11 (std::aligned_storage in particular)
//
#define POCO_NO_SOO
// Small object size in bytes. When assigned to Any or Var,
// objects longer than this value will be alocated on the heap.
// objects larger than this value will be alocated on the heap,
// while those smaller will be placement new-ed into an
// internal buffer.
#if !defined(POCO_SMALL_OBJECT_SIZE) && !defined(POCO_NO_SOO)
#define POCO_SMALL_OBJECT_SIZE 32
#endif

View File

@ -110,14 +110,10 @@ public:
Var(const T& val)
/// Creates the Var from the given value.
#ifdef POCO_NO_SOO
: _pHolder(new VarHolderImpl<T>(val)),
_pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
: _pHolder(new VarHolderImpl<T>(val))
{
}
#else
: _pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
{
construct(val);
}
@ -135,10 +131,10 @@ public:
void swap(Var& other);
/// Swaps the content of the this Var with the other Var.
ConstIterator& begin() const;
ConstIterator begin() const;
/// Returns the const Var iterator.
ConstIterator& end() const;
ConstIterator end() const;
/// Returns the const Var iterator.
Iterator begin();
@ -629,7 +625,7 @@ private:
{
if (sizeof(VarHolderImpl<ValueType>) <= Placeholder<ValueType>::Size::value)
{
new (reinterpret_cast<VarHolder*>(_placeholder.holder)) VarHolderImpl<ValueType>(value);
new (reinterpret_cast<VarHolder*>(_placeholder.holder.h)) VarHolderImpl<ValueType>(value);
_placeholder.setLocal(true);
}
else
@ -644,7 +640,7 @@ private:
std::string val(value);
if (sizeof(VarHolderImpl<std::string>) <= Placeholder<std::string>::Size::value)
{
new (reinterpret_cast<VarHolder*>(_placeholder.holder)) VarHolderImpl<std::string>(val);
new (reinterpret_cast<VarHolder*>(_placeholder.holder.h)) VarHolderImpl<std::string>(val);
_placeholder.setLocal(true);
}
else
@ -676,9 +672,6 @@ private:
Placeholder<VarHolder> _placeholder;
#endif // POCO_NO_SOO
Iterator* _pBegin;
Iterator* _pEnd;
};
@ -732,30 +725,28 @@ inline const std::type_info& Var::type() const
}
inline Var::ConstIterator& Var::begin() const
inline Var::ConstIterator Var::begin() const
{
if (isEmpty()) _pBegin->setPosition(Iterator::POSITION_END);
else if (*_pBegin == *_pEnd) _pBegin->setPosition(0);
if (isEmpty()) return ConstIterator(const_cast<Var*>(this), true);
return *_pBegin;
return ConstIterator(const_cast<Var*>(this), false);
}
inline Var::ConstIterator& Var::end() const
inline Var::ConstIterator Var::end() const
{
return *_pEnd;
return ConstIterator(const_cast<Var*>(this), true);
}
inline Var::Iterator Var::begin()
{
if (isEmpty()) _pBegin->setPosition(Iterator::POSITION_END);
else if (*_pBegin == *_pEnd) _pBegin->setPosition(0);
if (isEmpty()) return Iterator(const_cast<Var*>(this), true);
return *_pBegin;
return Iterator(const_cast<Var*>(this), false);
}
inline Var::Iterator Var::end()
{
return *_pEnd;
return Iterator(this, true);
}

View File

@ -286,9 +286,9 @@ protected:
poco_check_ptr (pVarHolder);
if ((sizeof(VarHolderImpl<T>) <= Placeholder<T>::Size::value))
{
new ((VarHolder*) pVarHolder->holder) VarHolderImpl<T>(val);
new ((VarHolder*) pVarHolder->holder.h) VarHolderImpl<T>(val);
pVarHolder->setLocal(true);
return (VarHolder*) pVarHolder->holder;
return (VarHolder*) pVarHolder->holder.h;
}
else
{

View File

@ -47,26 +47,20 @@ namespace Poco {
namespace Dynamic {
Var::Var() :
Var::Var()
#ifdef POCO_NO_SOO
_pHolder(0),
: _pHolder(0)
#endif
_pBegin(new Iterator(this, true)),
_pEnd(new Iterator(this, true))
{
}
Var::Var(const char* pVal)
#ifdef POCO_NO_SOO
: _pHolder(new VarHolderImpl<std::string>(pVal)),
_pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
: _pHolder(new VarHolderImpl<std::string>(pVal))
{
}
#else
: _pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
{
construct(std::string(pVal));
}
@ -75,14 +69,10 @@ Var::Var(const char* pVal)
Var::Var(const Var& other)
#ifdef POCO_NO_SOO
: _pHolder(other._pHolder ? other._pHolder->clone() : 0),
_pBegin(new Iterator(*other._pBegin)),
_pEnd(new Iterator(*other._pEnd))
: _pHolder(other._pHolder ? other._pHolder->clone() : 0)
{
}
#else
: _pBegin(new Iterator(*other._pBegin)),
_pEnd(new Iterator(*other._pEnd))
{
if ((this != &other) && !other.isEmpty())
construct(other);

View File

@ -44,6 +44,11 @@
#include "Poco/Net/SocketDefs.h"
#include "Poco/Net/IPAddressImpl.h"
#include <vector>
#ifdef POCO_ENABLE_CPP11
#include <type_traits>
#else
#include "Poco/Alignment.h"
#endif
namespace Poco {
@ -387,9 +392,23 @@ private:
typedef Impl* Ptr;
Ptr pImpl() const;
void destruct();
char _memory[sizeof(Poco::Net::Impl::IPv6AddressImpl)];
char* storage();
#ifdef POCO_ENABLE_CPP11
static const unsigned sz = sizeof(Poco::Net::Impl::IPv6AddressImpl);
union
{
std::aligned_storage<sz> a;
char buffer[sz];
}
#else // !POCO_ENABLE_CPP11
AlignedCharArrayUnion <Poco::Net::Impl::IPv6AddressImpl,
Poco::Net::Impl::IPv4AddressImpl>
#endif // POCO_ENABLE_CPP11
_memory;
};
@ -401,7 +420,13 @@ inline void IPAddress::destruct()
inline IPAddress::Ptr IPAddress::pImpl() const
{
return reinterpret_cast<Ptr>(const_cast<char *>(_memory));
return reinterpret_cast<Ptr>(const_cast<char *>(_memory.buffer));
}
inline char* IPAddress::storage()
{
return _memory.buffer;
}

View File

@ -153,9 +153,23 @@ private:
typedef Impl* Ptr;
Ptr pImpl() const;
void destruct();
char _memory[sizeof(Poco::Net::Impl::IPv6SocketAddressImpl)];
char* storage();
#ifdef POCO_ENABLE_CPP11
static const unsigned sz = sizeof(Poco::Net::Impl::IPv6SocketAddressImpl);
union
{
std::aligned_storage<sz> a;
char buffer[sz];
}
#else // !POCO_ENABLE_CPP11
AlignedCharArrayUnion <Poco::Net::Impl::IPv6SocketAddressImpl,
Poco::Net::Impl::IPv4SocketAddressImpl>
#endif // POCO_ENABLE_CPP11
_memory;
};
@ -172,7 +186,13 @@ inline void SocketAddress::destruct()
inline SocketAddress::Ptr SocketAddress::pImpl() const
{
return reinterpret_cast<Ptr>(const_cast<char *>(_memory));
return reinterpret_cast<Ptr>(const_cast<char *>(_memory.buffer));
}
inline char* SocketAddress::storage()
{
return _memory.buffer;
}

View File

@ -64,26 +64,26 @@ namespace Net {
IPAddress::IPAddress()
{
new (_memory) IPv4AddressImpl();
new (storage()) IPv4AddressImpl();
}
IPAddress::IPAddress(const IPAddress& addr)
{
if (addr.family() == IPv4)
new (_memory) IPv4AddressImpl(addr.addr());
new (storage()) IPv4AddressImpl(addr.addr());
else
new (_memory) IPv6AddressImpl(addr.addr());
new (storage()) IPv6AddressImpl(addr.addr());
}
IPAddress::IPAddress(Family family)
{
if (family == IPv4)
new (_memory) IPv4AddressImpl();
new (storage()) IPv4AddressImpl();
#if defined(POCO_HAVE_IPv6)
else if (family == IPv6)
new (_memory) IPv6AddressImpl();
new (storage()) IPv6AddressImpl();
#endif
else
throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -95,14 +95,14 @@ IPAddress::IPAddress(const std::string& addr)
IPv4AddressImpl empty4 = IPv4AddressImpl();
if (addr.empty() || trim(addr) == "0.0.0.0")
{
new (_memory) IPv4AddressImpl(empty4.addr());
new (storage()) IPv4AddressImpl(empty4.addr());
return;
}
IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr));
if (addr4 != empty4)
{
new (_memory) IPv4AddressImpl(addr4.addr());
new (storage()) IPv4AddressImpl(addr4.addr());
return;
}
@ -110,14 +110,14 @@ IPAddress::IPAddress(const std::string& addr)
IPv6AddressImpl empty6 = IPv6AddressImpl();
if (addr.empty() || trim(addr) == "::")
{
new (_memory) IPv6AddressImpl(empty6.addr());
new (storage()) IPv6AddressImpl(empty6.addr());
return;
}
IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr));
if (addr6 != IPv6AddressImpl())
{
new (_memory) IPv6AddressImpl(addr6.addr());
new (storage()) IPv6AddressImpl(addr6.addr());
return;
}
#endif
@ -131,14 +131,14 @@ IPAddress::IPAddress(const std::string& addr, Family family)
if (family == IPv4)
{
IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr));
new (_memory) IPv4AddressImpl(addr4.addr());
new (storage()) IPv4AddressImpl(addr4.addr());
return;
}
#if defined(POCO_HAVE_IPv6)
else if (family == IPv6)
{
IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr));
new (_memory) IPv6AddressImpl(addr6.addr());
new (storage()) IPv6AddressImpl(addr6.addr());
return;
}
#endif
@ -149,10 +149,10 @@ IPAddress::IPAddress(const std::string& addr, Family family)
IPAddress::IPAddress(const void* addr, poco_socklen_t length)
{
if (length == sizeof(struct in_addr))
new (_memory) IPv4AddressImpl(addr);
new (storage()) IPv4AddressImpl(addr);
#if defined(POCO_HAVE_IPv6)
else if (length == sizeof(struct in6_addr))
new (_memory) IPv6AddressImpl(addr);
new (storage()) IPv6AddressImpl(addr);
#endif
else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");
}
@ -161,10 +161,10 @@ IPAddress::IPAddress(const void* addr, poco_socklen_t length)
IPAddress::IPAddress(const void* addr, poco_socklen_t length, Poco::UInt32 scope)
{
if (length == sizeof(struct in_addr))
new (_memory) IPv4AddressImpl(addr);
new (storage()) IPv4AddressImpl(addr);
#if defined(POCO_HAVE_IPv6)
else if (length == sizeof(struct in6_addr))
new (_memory) IPv6AddressImpl(addr, scope);
new (storage()) IPv6AddressImpl(addr, scope);
#endif
else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");
}
@ -175,13 +175,13 @@ IPAddress::IPAddress(unsigned prefix, Family family)
if (family == IPv4)
{
if (prefix <= 32)
new (_memory) IPv4AddressImpl(prefix);
new (storage()) IPv4AddressImpl(prefix);
}
#if defined(POCO_HAVE_IPv6)
else if (family == IPv6)
{
if (prefix <= 128)
new (_memory) IPv6AddressImpl(prefix);
new (storage()) IPv6AddressImpl(prefix);
}
#endif
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -194,10 +194,10 @@ IPAddress::IPAddress(const SOCKET_ADDRESS& socket_address)
{
ADDRESS_FAMILY family = socket_address.lpSockaddr->sa_family;
if (family == AF_INET)
new (_memory) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(socket_address.lpSockaddr)->sin_addr);
new (storage()) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(socket_address.lpSockaddr)->sin_addr);
#if defined(POCO_HAVE_IPv6)
else if (family == AF_INET6)
new (_memory) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(socket_address.lpSockaddr)->sin6_addr,
new (storage()) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(socket_address.lpSockaddr)->sin6_addr,
reinterpret_cast<const struct sockaddr_in6*>(socket_address.lpSockaddr)->sin6_scope_id);
#endif
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -209,10 +209,10 @@ IPAddress::IPAddress(const struct sockaddr& sockaddr)
{
unsigned short family = sockaddr.sa_family;
if (family == AF_INET)
new (_memory) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(&sockaddr)->sin_addr);
new (storage()) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(&sockaddr)->sin_addr);
#if defined(POCO_HAVE_IPv6)
else if (family == AF_INET6)
new (_memory) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(&sockaddr)->sin6_addr,
new (storage()) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(&sockaddr)->sin6_addr,
reinterpret_cast<const struct sockaddr_in6*>(&sockaddr)->sin6_scope_id);
#endif
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -231,9 +231,9 @@ IPAddress& IPAddress::operator = (const IPAddress& addr)
{
destruct();
if (addr.family() == IPAddress::IPv4)
new (_memory) IPv4AddressImpl(addr.addr());
new (storage()) IPv4AddressImpl(addr.addr());
else
new (_memory) IPv6AddressImpl(addr.addr());
new (storage()) IPv6AddressImpl(addr.addr());
}
return *this;
}
@ -546,14 +546,14 @@ bool IPAddress::tryParse(const std::string& addr, IPAddress& result)
if (impl4 != IPv4AddressImpl())
{
new (result._memory) IPv4AddressImpl(impl4.addr());
new (result.storage()) IPv4AddressImpl(impl4.addr());
return true;
}
#if defined(POCO_HAVE_IPv6)
IPv6AddressImpl impl6(IPv6AddressImpl::parse(addr));
if (impl6 != IPv6AddressImpl())
{
new (result._memory) IPv6AddressImpl(impl6.addr());
new (result.storage()) IPv6AddressImpl(impl6.addr());
return true;
}
#endif

View File

@ -75,7 +75,7 @@ struct AFLT
SocketAddress::SocketAddress()
{
new (_memory) IPv4SocketAddressImpl;
new (storage()) IPv4SocketAddressImpl;
}
@ -135,19 +135,19 @@ SocketAddress::SocketAddress(const std::string& hostAndPort)
SocketAddress::SocketAddress(const SocketAddress& socketAddress)
{
if (socketAddress.family() == IPAddress::IPv4)
new (_memory) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
new (storage()) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
else
new (_memory) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
new (storage()) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
}
SocketAddress::SocketAddress(const struct sockaddr* sockAddr, poco_socklen_t length)
{
if (length == sizeof(struct sockaddr_in))
new (_memory) IPv4SocketAddressImpl(reinterpret_cast<const struct sockaddr_in*>(sockAddr));
new (storage()) IPv4SocketAddressImpl(reinterpret_cast<const struct sockaddr_in*>(sockAddr));
#if defined(POCO_HAVE_IPv6)
else if (length == sizeof(struct sockaddr_in6))
new (_memory) IPv6SocketAddressImpl(reinterpret_cast<const struct sockaddr_in6*>(sockAddr));
new (storage()) IPv6SocketAddressImpl(reinterpret_cast<const struct sockaddr_in6*>(sockAddr));
#endif
else throw Poco::InvalidArgumentException("Invalid address length passed to SocketAddress()");
}
@ -175,9 +175,9 @@ SocketAddress& SocketAddress::operator = (const SocketAddress& socketAddress)
{
destruct();
if (socketAddress.family() == IPAddress::IPv4)
new (_memory) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
new (storage()) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
else
new (_memory) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
new (storage()) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
}
return *this;
}
@ -232,10 +232,10 @@ std::string SocketAddress::toString() const
void SocketAddress::init(const IPAddress& hostAddress, Poco::UInt16 portNumber)
{
if (hostAddress.family() == IPAddress::IPv4)
new (_memory) IPv4SocketAddressImpl(hostAddress.addr(), htons(portNumber));
new (storage()) IPv4SocketAddressImpl(hostAddress.addr(), htons(portNumber));
#if defined(POCO_HAVE_IPv6)
else if (hostAddress.family() == IPAddress::IPv6)
new (_memory) IPv6SocketAddressImpl(hostAddress.addr(), htons(portNumber), hostAddress.scope());
new (storage()) IPv6SocketAddressImpl(hostAddress.addr(), htons(portNumber), hostAddress.scope());
#endif
else throw Poco::NotImplementedException("unsupported IP address family");
}

View File

@ -184,20 +184,20 @@ following copyrighted material, the use of which is hereby acknowledged.
!!!SQlite 3.7.14
The original author of SQLite has dedicated the code to the
public domain (http://www.sqlite.org/copyright.html).
Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
original SQLite code, either in source code form or as a compiled binary,
for any purpose, commercial or non-commercial, and by any means.
The original author of SQLite has dedicated the code to the
public domain (http://www.sqlite.org/copyright.html).
Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
original SQLite code, either in source code form or as a compiled binary,
for any purpose, commercial or non-commercial, and by any means.
----
!!!double-conversion
Copyright 2010 the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Copyright 2010 the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
@ -209,40 +209,85 @@ met:
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----
!!!JSON_parser
Copyright (c) 2005 JSON.org
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
----
!!!Code from the LLVM Compiler Infrastructure
University of Illinois/NCSA
Open Source License
Copyright (c) 2007-2012 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.

View File

@ -251,5 +251,48 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
</pre></p>
<h3>Code from the LLVM Compiler Infrastructure</h3>
<p><pre>University of Illinois/NCSA
Open Source License
Copyright (c) 2007-2012 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
</pre></p>
</body>
</html>