ndnboost: Include boost::iostreams for internal use.
diff --git a/include/ndnboost/detail/bitmask.hpp b/include/ndnboost/detail/bitmask.hpp
new file mode 100644
index 0000000..e5dce4a
--- /dev/null
+++ b/include/ndnboost/detail/bitmask.hpp
@@ -0,0 +1,47 @@
+// ndnboost/detail/bitmask.hpp ------------------------------------------------//
+
+// Copyright Beman Dawes 2006
+
+// Distributed under the Boost Software License, Version 1.0
+// http://www.boost.org/LICENSE_1_0.txt
+
+// Usage: enum foo { a=1, b=2, c=4 };
+// NDNBOOST_BITMASK( foo );
+//
+// void f( foo arg );
+// ...
+// f( a | c );
+
+#ifndef NDNBOOST_BITMASK_HPP
+#define NDNBOOST_BITMASK_HPP
+
+#include <ndnboost/cstdint.hpp>
+
+#define NDNBOOST_BITMASK(Bitmask) \
+ \
+ inline Bitmask operator| (Bitmask x , Bitmask y ) \
+ { return static_cast<Bitmask>( static_cast<ndnboost::int_least32_t>(x) \
+ | static_cast<ndnboost::int_least32_t>(y)); } \
+ \
+ inline Bitmask operator& (Bitmask x , Bitmask y ) \
+ { return static_cast<Bitmask>( static_cast<ndnboost::int_least32_t>(x) \
+ & static_cast<ndnboost::int_least32_t>(y)); } \
+ \
+ inline Bitmask operator^ (Bitmask x , Bitmask y ) \
+ { return static_cast<Bitmask>( static_cast<ndnboost::int_least32_t>(x) \
+ ^ static_cast<ndnboost::int_least32_t>(y)); } \
+ \
+ inline Bitmask operator~ (Bitmask x ) \
+ { return static_cast<Bitmask>(~static_cast<ndnboost::int_least32_t>(x)); } \
+ \
+ inline Bitmask & operator&=(Bitmask & x , Bitmask y) \
+ { x = x & y ; return x ; } \
+ \
+ inline Bitmask & operator|=(Bitmask & x , Bitmask y) \
+ { x = x | y ; return x ; } \
+ \
+ inline Bitmask & operator^=(Bitmask & x , Bitmask y) \
+ { x = x ^ y ; return x ; }
+
+#endif // NDNBOOST_BITMASK_HPP
+
diff --git a/include/ndnboost/detail/scoped_enum_emulation.hpp b/include/ndnboost/detail/scoped_enum_emulation.hpp
new file mode 100644
index 0000000..cd2f599
--- /dev/null
+++ b/include/ndnboost/detail/scoped_enum_emulation.hpp
@@ -0,0 +1,337 @@
+// scoped_enum_emulation.hpp ---------------------------------------------------------//
+
+// Copyright Beman Dawes, 2009
+// Copyright (C) 2011-2012 Vicente J. Botet Escriba
+// Copyright (C) 2012 Anthony Williams
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+/*
+[section:scoped_enums Scoped Enums]
+
+Generates C++0x scoped enums if the feature is present, otherwise emulates C++0x
+scoped enums with C++03 namespaces and enums. The Boost.Config NDNBOOST_NO_CXX11_SCOPED_ENUMS
+macro is used to detect feature support.
+
+See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf for a
+description of the scoped enum feature. Note that the committee changed the name
+from strongly typed enum to scoped enum.
+
+Some of the enumerations defined in the standard library are scoped enums.
+
+ enum class future_errc
+ {
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+ };
+
+On compilers that don't support them, the library provides two emulations:
+
+[heading Strict]
+
+* Able to specify the underlying type.
+* explicit conversion to/from underlying type.
+* The wrapper is not a C++03 enum type.
+
+The user can declare declare these types as
+
+ NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc)
+ {
+ broken_promise,
+ future_already_retrieved,
+ promise_already_satisfied,
+ no_state
+ }
+ NDNBOOST_SCOPED_ENUM_DECLARE_END(future_errc)
+
+These macros allows to use 'future_errc' in almost all the cases as an scoped enum.
+
+ future_errc err = future_errc::no_state;
+
+There are however some limitations:
+
+* The type is not a C++ enum, so 'is_enum<future_errc>' will be false_type.
+* The emulated scoped enum can not be used in switch nor in template arguments. For these cases the user needs to use some macros.
+
+Instead of
+
+ switch (ev)
+ {
+ case future_errc::broken_promise:
+ // ...
+
+use
+
+ switch (ndnboost::native_value(ev))
+ {
+ case future_errc::broken_promise:
+
+And instead of
+
+ #ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+ template <>
+ struct NDNBOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type { };
+ #endif
+
+use
+
+ #ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+ template <>
+ struct NDNBOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type > : public true_type { };
+ #endif
+
+
+Sample usage:
+
+ NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(algae, char) { green, red, cyan }; NDNBOOST_SCOPED_ENUM_DECLARE_END(algae)
+ ...
+ algae sample( algae::red );
+ void foo( algae color );
+ ...
+ sample = algae::green;
+ foo( algae::cyan );
+
+ Light
+ Caution: only the syntax is emulated; the semantics are not emulated and
+ the syntax emulation doesn't include being able to specify the underlying
+ representation type.
+
+ The literal scoped emulation is via struct rather than namespace to allow use within classes.
+ Thanks to Andrey Semashev for pointing that out.
+ However the type is an real C++03 enum and so convertible implicitly to an int.
+
+ Sample usage:
+
+ NDNBOOST_SCOPED_ENUM_START(algae) { green, red, cyan }; NDNBOOST_SCOPED_ENUM_END
+ ...
+ NDNBOOST_SCOPED_ENUM(algae) sample( algae::red );
+ void foo( NDNBOOST_SCOPED_ENUM(algae) color );
+ ...
+ sample = algae::green;
+ foo( algae::cyan );
+
+ Helpful comments and suggestions were also made by Kjell Elster, Phil Endecott,
+ Joel Falcou, Mathias Gaunard, Felipe Magno de Almeida, Matt Calabrese, Vicente
+ Botet, and Daniel James.
+
+[endsect]
+*/
+
+
+#ifndef NDNBOOST_SCOPED_ENUM_EMULATION_HPP
+#define NDNBOOST_SCOPED_ENUM_EMULATION_HPP
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+namespace ndnboost
+{
+
+#ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+ /**
+ * Meta-function to get the underlying type of a scoped enum.
+ *
+ * Requires EnumType must be an enum type or the emulation of a scoped enum
+ */
+ template <typename EnumType>
+ struct underlying_type
+ {
+ /**
+ * The member typedef type names the underlying type of EnumType. It is EnumType::underlying_type when the EnumType is an emulated scoped enum,
+ * std::underlying_type<EnumType>::type when the standard library std::underlying_type is provided.
+ *
+ * The user will need to specialize it when the compiler supports scoped enums but don't provides std::underlying_type.
+ */
+ typedef typename EnumType::underlying_type type;
+ };
+
+ /**
+ * Meta-function to get the native enum type associated to an enum class or its emulation.
+ */
+ template <typename EnumType>
+ struct native_type
+ {
+ /**
+ * The member typedef type names the native enum type associated to the scoped enum,
+ * which is it self if the compiler supports scoped enums or EnumType::enum_type if it is an emulated scoped enum.
+ */
+ typedef typename EnumType::enum_type type;
+ };
+
+ /**
+ * Casts a scoped enum to its underlying type.
+ *
+ * This function is useful when working with scoped enum classes, which doens't implicitly convert to the underlying type.
+ * @param v A scoped enum.
+ * @returns The underlying type.
+ * @throws No-throws.
+ */
+ template <typename UnderlyingType, typename EnumType>
+ UnderlyingType underlying_cast(EnumType v)
+ {
+ return v.get_underlying_value_();
+ }
+
+ /**
+ * Casts a scoped enum to its native enum type.
+ *
+ * This function is useful to make programs portable when the scoped enum emulation can not be use where native enums can.
+ *
+ * EnumType the scoped enum type
+ *
+ * @param v A scoped enum.
+ * @returns The native enum value.
+ * @throws No-throws.
+ */
+ template <typename EnumType>
+ inline
+ typename EnumType::enum_type native_value(EnumType e)
+ {
+ return e.native_value_();
+ }
+
+#else // NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+ template <typename EnumType>
+ struct underlying_type
+ {
+ //typedef typename std::underlying_type<EnumType>::type type;
+ };
+
+ template <typename EnumType>
+ struct native_type
+ {
+ typedef EnumType type;
+ };
+
+ template <typename UnderlyingType, typename EnumType>
+ UnderlyingType underlying_cast(EnumType v)
+ {
+ return static_cast<UnderlyingType>(v);
+ }
+
+ template <typename EnumType>
+ inline
+ EnumType native_value(EnumType e)
+ {
+ return e;
+ }
+
+#endif
+}
+
+
+#ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+#ifndef NDNBOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
+ explicit operator underlying_type() const { return get_underlying_value_(); }
+
+#else
+
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR
+
+#endif
+
+/**
+ * Start a declaration of a scoped enum.
+ *
+ * @param EnumType The new scoped enum.
+ * @param UnderlyingType The underlying type.
+ */
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType, UnderlyingType) \
+ struct EnumType { \
+ typedef UnderlyingType underlying_type; \
+ EnumType() NDNBOOST_NOEXCEPT {} \
+ explicit EnumType(underlying_type v) : v_(v) {} \
+ underlying_type get_underlying_value_() const { return v_; } \
+ NDNBOOST_SCOPED_ENUM_UT_DECLARE_CONVERSION_OPERATOR \
+ private: \
+ underlying_type v_; \
+ typedef EnumType self_type; \
+ public: \
+ enum enum_type
+
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END2() \
+ enum_type get_native_value_() const NDNBOOST_NOEXCEPT { return enum_type(v_); } \
+ operator enum_type() const NDNBOOST_NOEXCEPT { return get_native_value_(); } \
+ friend bool operator ==(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)==enum_type(rhs.v_); } \
+ friend bool operator ==(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)==rhs; } \
+ friend bool operator ==(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs==enum_type(rhs.v_); } \
+ friend bool operator !=(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)!=enum_type(rhs.v_); } \
+ friend bool operator !=(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)!=rhs; } \
+ friend bool operator !=(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs!=enum_type(rhs.v_); } \
+ friend bool operator <(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<enum_type(rhs.v_); } \
+ friend bool operator <(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<rhs; } \
+ friend bool operator <(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs<enum_type(rhs.v_); } \
+ friend bool operator <=(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<=enum_type(rhs.v_); } \
+ friend bool operator <=(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)<=rhs; } \
+ friend bool operator <=(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs<=enum_type(rhs.v_); } \
+ friend bool operator >(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>enum_type(rhs.v_); } \
+ friend bool operator >(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>rhs; } \
+ friend bool operator >(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs>enum_type(rhs.v_); } \
+ friend bool operator >=(self_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>=enum_type(rhs.v_); } \
+ friend bool operator >=(self_type lhs, enum_type rhs) NDNBOOST_NOEXCEPT { return enum_type(lhs.v_)>=rhs; } \
+ friend bool operator >=(enum_type lhs, self_type rhs) NDNBOOST_NOEXCEPT { return lhs>=enum_type(rhs.v_); } \
+ };
+
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END(EnumType) \
+ ; \
+ EnumType(enum_type v) NDNBOOST_NOEXCEPT : v_(v) {} \
+ NDNBOOST_SCOPED_ENUM_DECLARE_END2()
+
+/**
+ * Starts a declaration of a scoped enum with the default int underlying type.
+ *
+ * @param EnumType The new scoped enum.
+ */
+#define NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) \
+ NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,int)
+
+/**
+ * Name of the native enum type.
+ *
+ * @param NT The new scoped enum.
+ */
+#define NDNBOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType::enum_type
+/**
+ * Forward declares an scoped enum.
+ *
+ * @param NT The scoped enum.
+ */
+#define NDNBOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) struct EnumType
+
+#else // NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+#define NDNBOOST_SCOPED_ENUM_UT_DECLARE_BEGIN(EnumType,UnderlyingType) enum class EnumType:UnderlyingType
+#define NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(EnumType) enum class EnumType
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END2()
+#define NDNBOOST_SCOPED_ENUM_DECLARE_END(EnumType) ;
+
+#define NDNBOOST_SCOPED_ENUM_NATIVE(EnumType) EnumType
+#define NDNBOOST_SCOPED_ENUM_FORWARD_DECLARE(EnumType) enum class EnumType
+
+#endif // NDNBOOST_NO_CXX11_SCOPED_ENUMS
+
+#define NDNBOOST_SCOPED_ENUM_START(name) NDNBOOST_SCOPED_ENUM_DECLARE_BEGIN(name)
+#define NDNBOOST_SCOPED_ENUM_END NDNBOOST_SCOPED_ENUM_DECLARE_END2()
+#define NDNBOOST_SCOPED_ENUM(name) NDNBOOST_SCOPED_ENUM_NATIVE(name)
+
+//#ifdef NDNBOOST_NO_CXX11_SCOPED_ENUMS
+//
+//# define NDNBOOST_SCOPED_ENUM_START(name) struct name { enum enum_type
+//# define NDNBOOST_SCOPED_ENUM_END };
+//# define NDNBOOST_SCOPED_ENUM(name) name::enum_type
+//
+//#else
+//
+//# define NDNBOOST_SCOPED_ENUM_START(name) enum class name
+//# define NDNBOOST_SCOPED_ENUM_END
+//# define NDNBOOST_SCOPED_ENUM(name) name
+//
+//#endif
+#endif // NDNBOOST_SCOPED_ENUM_EMULATION_HPP
diff --git a/include/ndnboost/detail/utf8_codecvt_facet.hpp b/include/ndnboost/detail/utf8_codecvt_facet.hpp
new file mode 100644
index 0000000..37d9133
--- /dev/null
+++ b/include/ndnboost/detail/utf8_codecvt_facet.hpp
@@ -0,0 +1,190 @@
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
+// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef NDNBOOST_UTF8_CODECVT_FACET_HPP
+#define NDNBOOST_UTF8_CODECVT_FACET_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// utf8_codecvt_facet.hpp
+
+// This header defines class utf8_codecvt_facet, derived fro
+// std::codecvt<wchar_t, char>, which can be used to convert utf8 data in
+// files into wchar_t strings in the application.
+//
+// The header is NOT STANDALONE, and is not to be included by the USER.
+// There are at least two libraries which want to use this functionality, and
+// we want to avoid code duplication. It would be possible to create utf8
+// library, but:
+// - this requires review process first
+// - in the case, when linking the a library which uses utf8
+// (say 'program_options'), user should also link to the utf8 library.
+// This seems inconvenient, and asking a user to link to an unrevieved
+// library is strange.
+// Until the above points are fixed, a library which wants to use utf8 must:
+// - include this header from one of it's headers or sources
+// - include the corresponding .cpp file from one of the sources
+// - before including either file, the library must define
+// - NDNBOOST_UTF8_BEGIN_NAMESPACE to the namespace declaration that must be used
+// - NDNBOOST_UTF8_END_NAMESPACE to the code to close the previous namespace
+// - declaration.
+// - NDNBOOST_UTF8_DECL -- to the code which must be used for all 'exportable'
+// symbols.
+//
+// For example, program_options library might contain:
+// #define NDNBOOST_UTF8_BEGIN_NAMESPACE <backslash character>
+// namespace ndnboost { namespace program_options {
+// #define NDNBOOST_UTF8_END_NAMESPACE }}
+// #define NDNBOOST_UTF8_DECL NDNBOOST_PROGRAM_OPTIONS_DECL
+// #include "../../detail/utf8/utf8_codecvt.cpp"
+//
+// Essentially, each library will have its own copy of utf8 code, in
+// different namespaces.
+
+// Note:(Robert Ramey). I have made the following alterations in the original
+// code.
+// a) Rendered utf8_codecvt<wchar_t, char> with using templates
+// b) Move longer functions outside class definition to prevent inlining
+// and make code smaller
+// c) added on a derived class to permit translation to/from current
+// locale to utf8
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+// archives stored as text - note these ar templated on the basic
+// stream templates to accommodate wide (and other?) kind of characters
+//
+// note the fact that on libraries without wide characters, ostream is
+// is not a specialization of basic_ostream which in fact is not defined
+// in such cases. So we can't use basic_ostream<OStream::char_type> but rather
+// use two template parameters
+//
+// utf8_codecvt_facet
+// This is an implementation of a std::codecvt facet for translating
+// from UTF-8 externally to UCS-4. Note that this is not tied to
+// any specific types in order to allow customization on platforms
+// where wchar_t is not big enough.
+//
+// NOTES: The current implementation jumps through some unpleasant hoops in
+// order to deal with signed character types. As a std::codecvt_base::result,
+// it is necessary for the ExternType to be convertible to unsigned char.
+// I chose not to tie the extern_type explicitly to char. But if any combination
+// of types other than <wchar_t,char_t> is used, then std::codecvt must be
+// specialized on those types for this to work.
+
+#include <locale>
+#include <cwchar> // for mbstate_t
+#include <cstddef> // for std::size_t
+
+#include <ndnboost/config.hpp>
+#include <ndnboost/detail/workaround.hpp>
+
+#if defined(NDNBOOST_NO_STDC_NAMESPACE)
+namespace std {
+ using ::mbstate_t;
+ using ::size_t;
+}
+#endif
+
+#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__)
+ #define NDNBOOST_CODECVT_DO_LENGTH_CONST const
+#else
+ #define NDNBOOST_CODECVT_DO_LENGTH_CONST
+#endif
+
+// maximum lenght of a multibyte string
+#define MB_LENGTH_MAX 8
+
+NDNBOOST_UTF8_BEGIN_NAMESPACE
+
+struct NDNBOOST_UTF8_DECL utf8_codecvt_facet :
+ public std::codecvt<wchar_t, char, std::mbstate_t>
+{
+public:
+ explicit utf8_codecvt_facet(std::size_t no_locale_manage=0)
+ : std::codecvt<wchar_t, char, std::mbstate_t>(no_locale_manage)
+ {}
+protected:
+ virtual std::codecvt_base::result do_in(
+ std::mbstate_t& state,
+ const char * from,
+ const char * from_end,
+ const char * & from_next,
+ wchar_t * to,
+ wchar_t * to_end,
+ wchar_t*& to_next
+ ) const;
+
+ virtual std::codecvt_base::result do_out(
+ std::mbstate_t & state, const wchar_t * from,
+ const wchar_t * from_end, const wchar_t* & from_next,
+ char * to, char * to_end, char * & to_next
+ ) const;
+
+ bool invalid_continuing_octet(unsigned char octet_1) const {
+ return (octet_1 < 0x80|| 0xbf< octet_1);
+ }
+
+ bool invalid_leading_octet(unsigned char octet_1) const {
+ return (0x7f < octet_1 && octet_1 < 0xc0) ||
+ (octet_1 > 0xfd);
+ }
+
+ // continuing octets = octets except for the leading octet
+ static unsigned int get_cont_octet_count(unsigned char lead_octet) {
+ return get_octet_count(lead_octet) - 1;
+ }
+
+ static unsigned int get_octet_count(unsigned char lead_octet);
+
+ // How many "continuing octets" will be needed for this word
+ // == total octets - 1.
+ int get_cont_octet_out_count(wchar_t word) const ;
+
+ virtual bool do_always_noconv() const throw() { return false; }
+
+ // UTF-8 isn't really stateful since we rewind on partial conversions
+ virtual std::codecvt_base::result do_unshift(
+ std::mbstate_t&,
+ char * from,
+ char * /*to*/,
+ char * & next
+ ) const
+ {
+ next = from;
+ return ok;
+ }
+
+ virtual int do_encoding() const throw() {
+ const int variable_byte_external_encoding=0;
+ return variable_byte_external_encoding;
+ }
+
+ // How many char objects can I process to get <= max_limit
+ // wchar_t objects?
+ virtual int do_length(
+ NDNBOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &,
+ const char * from,
+ const char * from_end,
+ std::size_t max_limit
+#if NDNBOOST_WORKAROUND(__IBMCPP__, NDNBOOST_TESTED_AT(600))
+ ) const throw();
+#else
+ ) const;
+#endif
+
+ // Largest possible value do_length(state,from,from_end,1) could return.
+ virtual int do_max_length() const throw () {
+ return 6; // largest UTF-8 encoding of a UCS-4 character
+ }
+};
+
+NDNBOOST_UTF8_END_NAMESPACE
+
+#endif // NDNBOOST_UTF8_CODECVT_FACET_HPP
diff --git a/include/ndnboost/detail/utf8_codecvt_facet.ipp b/include/ndnboost/detail/utf8_codecvt_facet.ipp
new file mode 100644
index 0000000..00e893d
--- /dev/null
+++ b/include/ndnboost/detail/utf8_codecvt_facet.ipp
@@ -0,0 +1,285 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// utf8_codecvt_facet.ipp
+
+// Copyright (c) 2001 Ronald Garcia, Indiana University (garcia@osl.iu.edu)
+// Andrew Lumsdaine, Indiana University (lums@osl.iu.edu).
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Please see the comments in <ndnboost/detail/utf8_codecvt_facet.hpp> to
+// learn how this file should be used.
+
+#include <ndnboost/detail/utf8_codecvt_facet.hpp>
+
+#include <cstdlib> // for multi-byte converson routines
+#include <cassert>
+
+#include <ndnboost/limits.hpp>
+#include <ndnboost/config.hpp>
+
+// If we don't have wstring, then Unicode support
+// is not available anyway, so we don't need to even
+// compiler this file. This also fixes the problem
+// with mingw, which can compile this file, but will
+// generate link error when building DLL.
+#ifndef NDNBOOST_NO_STD_WSTRING
+
+NDNBOOST_UTF8_BEGIN_NAMESPACE
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// implementation for wchar_t
+
+// Translate incoming UTF-8 into UCS-4
+std::codecvt_base::result utf8_codecvt_facet::do_in(
+ std::mbstate_t& /*state*/,
+ const char * from,
+ const char * from_end,
+ const char * & from_next,
+ wchar_t * to,
+ wchar_t * to_end,
+ wchar_t * & to_next
+) const {
+ // Basic algorithm: The first octet determines how many
+ // octets total make up the UCS-4 character. The remaining
+ // "continuing octets" all begin with "10". To convert, subtract
+ // the amount that specifies the number of octets from the first
+ // octet. Subtract 0x80 (1000 0000) from each continuing octet,
+ // then mash the whole lot together. Note that each continuing
+ // octet only uses 6 bits as unique values, so only shift by
+ // multiples of 6 to combine.
+ while (from != from_end && to != to_end) {
+
+ // Error checking on the first octet
+ if (invalid_leading_octet(*from)){
+ from_next = from;
+ to_next = to;
+ return std::codecvt_base::error;
+ }
+
+ // The first octet is adjusted by a value dependent upon
+ // the number of "continuing octets" encoding the character
+ const int cont_octet_count = get_cont_octet_count(*from);
+ const wchar_t octet1_modifier_table[] = {
+ 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
+ };
+
+ // The unsigned char conversion is necessary in case char is
+ // signed (I learned this the hard way)
+ wchar_t ucs_result =
+ (unsigned char)(*from++) - octet1_modifier_table[cont_octet_count];
+
+ // Invariants :
+ // 1) At the start of the loop, 'i' continuing characters have been
+ // processed
+ // 2) *from points to the next continuing character to be processed.
+ int i = 0;
+ while(i != cont_octet_count && from != from_end) {
+
+ // Error checking on continuing characters
+ if (invalid_continuing_octet(*from)) {
+ from_next = from;
+ to_next = to;
+ return std::codecvt_base::error;
+ }
+
+ ucs_result *= (1 << 6);
+
+ // each continuing character has an extra (10xxxxxx)b attached to
+ // it that must be removed.
+ ucs_result += (unsigned char)(*from++) - 0x80;
+ ++i;
+ }
+
+ // If the buffer ends with an incomplete unicode character...
+ if (from == from_end && i != cont_octet_count) {
+ // rewind "from" to before the current character translation
+ from_next = from - (i+1);
+ to_next = to;
+ return std::codecvt_base::partial;
+ }
+ *to++ = ucs_result;
+ }
+ from_next = from;
+ to_next = to;
+
+ // Were we done converting or did we run out of destination space?
+ if(from == from_end) return std::codecvt_base::ok;
+ else return std::codecvt_base::partial;
+}
+
+std::codecvt_base::result utf8_codecvt_facet::do_out(
+ std::mbstate_t& /*state*/,
+ const wchar_t * from,
+ const wchar_t * from_end,
+ const wchar_t * & from_next,
+ char * to,
+ char * to_end,
+ char * & to_next
+) const
+{
+ // RG - consider merging this table with the other one
+ const wchar_t octet1_modifier_table[] = {
+ 0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc
+ };
+
+ wchar_t max_wchar = (std::numeric_limits<wchar_t>::max)();
+ while (from != from_end && to != to_end) {
+
+ // Check for invalid UCS-4 character
+ if (*from > max_wchar) {
+ from_next = from;
+ to_next = to;
+ return std::codecvt_base::error;
+ }
+
+ int cont_octet_count = get_cont_octet_out_count(*from);
+
+ // RG - comment this formula better
+ int shift_exponent = (cont_octet_count) * 6;
+
+ // Process the first character
+ *to++ = static_cast<char>(octet1_modifier_table[cont_octet_count] +
+ (unsigned char)(*from / (1 << shift_exponent)));
+
+ // Process the continuation characters
+ // Invariants: At the start of the loop:
+ // 1) 'i' continuing octets have been generated
+ // 2) '*to' points to the next location to place an octet
+ // 3) shift_exponent is 6 more than needed for the next octet
+ int i = 0;
+ while (i != cont_octet_count && to != to_end) {
+ shift_exponent -= 6;
+ *to++ = static_cast<char>(0x80 + ((*from / (1 << shift_exponent)) % (1 << 6)));
+ ++i;
+ }
+ // If we filled up the out buffer before encoding the character
+ if(to == to_end && i != cont_octet_count) {
+ from_next = from;
+ to_next = to - (i+1);
+ return std::codecvt_base::partial;
+ }
+ ++from;
+ }
+ from_next = from;
+ to_next = to;
+ // Were we done or did we run out of destination space
+ if(from == from_end) return std::codecvt_base::ok;
+ else return std::codecvt_base::partial;
+}
+
+// How many char objects can I process to get <= max_limit
+// wchar_t objects?
+int utf8_codecvt_facet::do_length(
+ NDNBOOST_CODECVT_DO_LENGTH_CONST std::mbstate_t &,
+ const char * from,
+ const char * from_end,
+ std::size_t max_limit
+#if NDNBOOST_WORKAROUND(__IBMCPP__, NDNBOOST_TESTED_AT(600))
+) const throw()
+#else
+) const
+#endif
+{
+ // RG - this code is confusing! I need a better way to express it.
+ // and test cases.
+
+ // Invariants:
+ // 1) last_octet_count has the size of the last measured character
+ // 2) char_count holds the number of characters shown to fit
+ // within the bounds so far (no greater than max_limit)
+ // 3) from_next points to the octet 'last_octet_count' before the
+ // last measured character.
+ int last_octet_count=0;
+ std::size_t char_count = 0;
+ const char* from_next = from;
+ // Use "<" because the buffer may represent incomplete characters
+ while (from_next+last_octet_count <= from_end && char_count <= max_limit) {
+ from_next += last_octet_count;
+ last_octet_count = (get_octet_count(*from_next));
+ ++char_count;
+ }
+ return static_cast<int>(from_next-from_end);
+}
+
+unsigned int utf8_codecvt_facet::get_octet_count(
+ unsigned char lead_octet
+){
+ // if the 0-bit (MSB) is 0, then 1 character
+ if (lead_octet <= 0x7f) return 1;
+
+ // Otherwise the count number of consecutive 1 bits starting at MSB
+// assert(0xc0 <= lead_octet && lead_octet <= 0xfd);
+
+ if (0xc0 <= lead_octet && lead_octet <= 0xdf) return 2;
+ else if (0xe0 <= lead_octet && lead_octet <= 0xef) return 3;
+ else if (0xf0 <= lead_octet && lead_octet <= 0xf7) return 4;
+ else if (0xf8 <= lead_octet && lead_octet <= 0xfb) return 5;
+ else return 6;
+}
+NDNBOOST_UTF8_END_NAMESPACE
+
+namespace {
+template<std::size_t s>
+int get_cont_octet_out_count_impl(wchar_t word){
+ if (word < 0x80) {
+ return 0;
+ }
+ if (word < 0x800) {
+ return 1;
+ }
+ return 2;
+}
+
+template<>
+int get_cont_octet_out_count_impl<4>(wchar_t word){
+ if (word < 0x80) {
+ return 0;
+ }
+ if (word < 0x800) {
+ return 1;
+ }
+
+ // Note that the following code will generate warnings on some platforms
+ // where wchar_t is defined as UCS2. The warnings are superfluous as the
+ // specialization is never instantitiated with such compilers, but this
+ // can cause problems if warnings are being treated as errors, so we guard
+ // against that. Including <ndnboost/detail/utf8_codecvt_facet.hpp> as we do
+ // should be enough to get WCHAR_MAX defined.
+#if !defined(WCHAR_MAX)
+# error WCHAR_MAX not defined!
+#endif
+ // cope with VC++ 7.1 or earlier having invalid WCHAR_MAX
+#if defined(_MSC_VER) && _MSC_VER <= 1310 // 7.1 or earlier
+ return 2;
+#elif WCHAR_MAX > 0x10000
+
+ if (word < 0x10000) {
+ return 2;
+ }
+ if (word < 0x200000) {
+ return 3;
+ }
+ if (word < 0x4000000) {
+ return 4;
+ }
+ return 5;
+
+#else
+ return 2;
+#endif
+}
+
+} // namespace anonymous
+
+NDNBOOST_UTF8_BEGIN_NAMESPACE
+// How many "continuing octets" will be needed for this word
+// == total octets - 1.
+int utf8_codecvt_facet::get_cont_octet_out_count(
+ wchar_t word
+) const {
+ return get_cont_octet_out_count_impl<sizeof(wchar_t)>(word);
+}
+NDNBOOST_UTF8_END_NAMESPACE
+
+#endif