Shitload of warnings here as well.

On 01/04/14 14:01, Felipe Magno de Almeida wrote:
> cedric pushed a commit to branch master.
>
> http://git.enlightenment.org/core/efl.git/commit/?id=ab3eb4b2d350d017eab6683202663244e11aa518
>
> commit ab3eb4b2d350d017eab6683202663244e11aa518
> Author: Felipe Magno de Almeida <fel...@expertisesolutions.com.br>
> Date:   Tue Apr 1 19:08:07 2014 +0900
>
>      eet-cxx: add implementation for eet C++.
>
>      Usage example:
>
>        struct type
>        {
>          int foo;
>          float bar;
>        };
>
>        type t0;
>
>        auto descriptor = make_descriptor("type", &type::ofo, &type::bar);
>
>        eet_data_write(file, descriptor.native_handle(), "type", &t0, false);
>
>        std::unique_ptr<type> p = read_by_ptr(file, "type", descriptor);
>        type t = read(file, "type", descriptor);
>
>      @feature
>
>      Reviewers: cedric, smohanty
>
>      Reviewed By: cedric
>
>      CC: savio, cedric
>
>      Differential Revision: https://phab.enlightenment.org/D659
>
>      Signed-off-by: Cedric BAIL <cedric.b...@free.fr>
> ---
>   configure.ac                                  |   1 +
>   pc/.gitignore                                 |   1 +
>   pc/eet-cxx.pc.in                              |  12 ++
>   src/Makefile.am                               |   1 +
>   src/Makefile_Eet_Cxx.am                       |  42 +++++
>   src/bindings/eet_cxx/Eet.hh                   | 214 ++++++++++++++++++++++++
>   src/bindings/eet_cxx/eet_composite.hh         |  49 ++++++
>   src/bindings/eet_cxx/eet_fold.hh              |  32 ++++
>   src/bindings/eet_cxx/eet_register.hh          | 132 +++++++++++++++
>   src/bindings/eet_cxx/eet_tuple.hh             |  39 +++++
>   src/bindings/eet_cxx/eet_type.hh              |  78 +++++++++
>   src/lib/eet/Eet.h                             |  37 +++++
>   src/lib/eet/eet_data.c                        |  38 +++++
>   src/tests/eet_cxx/eet_cxx_suite.cc            | 104 ++++++++++++
>   src/tests/eet_cxx/eet_cxx_test_descriptors.cc | 231 
> ++++++++++++++++++++++++++
>   15 files changed, 1011 insertions(+)
>
> diff --git a/configure.ac b/configure.ac
> index 4001d29..3642b96 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -4100,6 +4100,7 @@ pc/escape.pc
>   pc/eina.pc
>   pc/eina-cxx.pc
>   pc/eet.pc
> +pc/eet-cxx.pc
>   pc/eo.pc
>   pc/eolian.pc
>   pc/evas-fb.pc
> diff --git a/pc/.gitignore b/pc/.gitignore
> index 658f6cf..ae42f58 100644
> --- a/pc/.gitignore
> +++ b/pc/.gitignore
> @@ -26,6 +26,7 @@
>   /efreet.pc
>   /eina.pc
>   /eina-cxx.pc
> +/eet-cxx.pc
>   /eio.pc
>   /eldbus.pc
>   /embryo.pc
> diff --git a/pc/eet-cxx.pc.in b/pc/eet-cxx.pc.in
> new file mode 100644
> index 0000000..2412c48
> --- /dev/null
> +++ b/pc/eet-cxx.pc.in
> @@ -0,0 +1,12 @@
> +prefix=@prefix@
> +exec_prefix=@exec_prefix@
> +libdir=@libdir@
> +includedir=@includedir@
> +
> +Name: Eet C++
> +Description: C++ API for the eet library
> +Version: @VERSION@
> +Requires.private: @requirements_pc_eet@
> +Libs: -L${libdir} -leet
> +Libs.private: @requirements_libs_eet@
> +Cflags: -I${includedir}/efl-@VMAJ@ -I${includedir}/eet-@VMAJ@ 
> -I${includedir}/efl-@VMAJ@ -I${includedir}/eet_cxx-@VMAJ@ 
> -I${includedir}/eet_cxx-@VMAJ@/eet_cxx
> diff --git a/src/Makefile.am b/src/Makefile.am
> index e277678..f9c2497 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -32,6 +32,7 @@ include Makefile_Escape.am
>   include Makefile_Eina.am
>   include Makefile_Eo.am
>   include Makefile_Eet.am
> +include Makefile_Eet_Cxx.am
>   include Makefile_Eolian.am
>   include Makefile_Evas.am
>   include Makefile_Ecore.am
> diff --git a/src/Makefile_Eet_Cxx.am b/src/Makefile_Eet_Cxx.am
> new file mode 100644
> index 0000000..b2381aa
> --- /dev/null
> +++ b/src/Makefile_Eet_Cxx.am
> @@ -0,0 +1,42 @@
> +
> +### Library
> +
> +installed_eetcxxmainheadersdir = $(includedir)/eet_cxx-@VMAJ@
> +dist_installed_eetcxxmainheaders_DATA = bindings/eet_cxx/Eet.hh
> +
> +installed_eetcxxheadersdir = $(includedir)/eet_cxx-@VMAJ@/eet_cxx
> +dist_installed_eetcxxheaders_DATA = \
> +bindings/eet_cxx/eet_composite.hh \
> +bindings/eet_cxx/eet_fold.hh \
> +bindings/eet_cxx/eet_register.hh \
> +bindings/eet_cxx/eet_tuple.hh \
> +bindings/eet_cxx/eet_type.hh
> +
> +### Unit tests
> +
> +if EFL_ENABLE_TESTS
> +if HAVE_CXX11
> +
> +check_PROGRAMS += tests/eet_cxx/eet_cxx_suite
> +TESTS += tests/eet_cxx/eet_cxx_suite
> +
> +tests_eet_cxx_eet_cxx_suite_SOURCES = \
> +tests/eet_cxx/eet_cxx_suite.cc \
> +tests/eet_cxx/eet_cxx_test_descriptors.cc
> +
> +tests_eet_cxx_eet_cxx_suite_CPPFLAGS =       \
> +-I$(top_builddir)/src/lib/efl \
> +-I$(top_builddir)/src/bindings/eina_cxx \
> +-I$(top_builddir)/src/bindings/eet_cxx \
> +-I$(top_srcdir)/src/bindings/eina_cxx \
> +-I$(top_srcdir)/src/bindings/eet_cxx \
> +-DTESTS_WD=\"`pwd`\" \
> +-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/eet_cxx\" \
> +-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/eet_cxx\" \
> +@CHECK_CFLAGS@ \
> +@EET_CFLAGS@
> +tests_eet_cxx_eet_cxx_suite_LDADD = @CHECK_LIBS@ @USE_EET_LIBS@
> +tests_eet_cxx_eet_cxx_suite_DEPENDENCIES = @USE_EET_INTERNAL_LIBS@
> +
> +endif
> +endif
> diff --git a/src/bindings/eet_cxx/Eet.hh b/src/bindings/eet_cxx/Eet.hh
> new file mode 100644
> index 0000000..f725c68
> --- /dev/null
> +++ b/src/bindings/eet_cxx/Eet.hh
> @@ -0,0 +1,214 @@
> +#ifndef EET_HH_
> +#define EET_HH_
> +
> +#include <Eet.h>
> +
> +#include <eet_type.hh>
> +#include <eet_fold.hh>
> +#include <eet_register.hh>
> +
> +#include <type_traits>
> +#include <cassert>
> +#include <stdexcept>
> +
> +#include <iostream>
> +#include <array>
> +
> +namespace efl { namespace eet { namespace _detail {
> +
> +template <typename T>
> +void* _allocate( ::size_t size )
> +{
> +  assert(size == sizeof(T));
> +  (void)size;
> +  return new T();
> +}
> +
> +template <typename T>
> +void _deallocate( void* p )
> +{
> +  delete static_cast<T*>(p);
> +}
> +
> +template <typename T, typename... Args>
> +struct descriptor_type
> +{
> +  struct push_back
> +  {
> +    template <typename A, typename B>
> +    struct apply : _mpl::push_back<A, typename _detail::member_type<typename 
> B::member_type>::type> {};
> +  };
> +
> +  typedef typename _mpl::fold< std::tuple<Args...>, push_back
> +    , descriptor<T> >::type type;
> +};
> +
> +}
> +
> +#define EET_CXX_MEMBER(C, I) ::efl::eet::type(#I, &C::I)
> +
> +template <typename F>
> +_detail::member_info<F, void> type(const char* name, F f)
> +{
> +  typedef typename _detail::member_type<F>::type member_type;
> +  static_assert(is_eet_primitive<member_type>::value, "");
> +  static_assert(std::is_member_pointer<F>::value, "");
> +  return _detail::member_info<F, void>{name, f};
> +}
> +
> +template <typename F, typename U, typename... Args>
> +_detail::member_info<F, U, Args...> type(const char* name, F f, 
> descriptor<U, Args...> const& descriptor)
> +{
> +  typedef typename _detail::member_type<F>::type member_type;
> +  static_assert(!is_eet_primitive<member_type>::value, "");
> +  static_assert(std::is_member_pointer<F>::value, "");
> +  return _detail::member_info<F, U, Args...>{name, f, &descriptor};
> +}
> +
> +struct eet_init
> +{
> +  eet_init()
> +  {
> +    ::eet_init();
> +  }
> +  ~eet_init()
> +  {
> +    ::eet_shutdown();
> +  }
> +};
> +
> +template <typename T, typename... Args>
> +struct descriptor
> +{
> +  typedef T object_type;
> +
> +  descriptor() : _descriptor(nullptr) {}
> +  descriptor( ::Eet_Data_Descriptor* descriptor
> +              , std::array<_detail::member_desc_info, sizeof...(Args)> 
> member_info)
> +    : _descriptor(descriptor), _member_info(member_info)
> +  {
> +  }
> +  descriptor(descriptor&& other)
> +    : _descriptor(other._descriptor)
> +  {
> +    other._descriptor = 0;
> +  }
> +  descriptor& operator=(descriptor&& other)
> +  {
> +    if(_descriptor)
> +      eet_data_descriptor_free(_descriptor);
> +    _descriptor = other._descriptor;
> +    other._descriptor = 0;
> +    return *this;
> +  }
> +  ~descriptor()
> +  {
> +    if(_descriptor)
> +      eet_data_descriptor_free(_descriptor);
> +  }
> +  typedef ::Eet_Data_Descriptor const* const_native_handle_type;
> +  typedef ::Eet_Data_Descriptor* native_handle_type;
> +  const_native_handle_type native_handle() const
> +  {
> +    return _descriptor;
> +  }
> +  native_handle_type native_handle()
> +  {
> +    return _descriptor;
> +  }
> +  typedef std::integral_constant<std::size_t, sizeof...(Args)> members;
> +
> +  std::array<_detail::member_desc_info, sizeof...(Args)> get_member_info() 
> const { return _member_info; }
> +private:
> +  ::Eet_Data_Descriptor* _descriptor;
> +  typedef descriptor<T, Args...> _self_type;
> +  descriptor(descriptor const&) = delete;
> +  descriptor& operator=(descriptor const&) = delete;
> +  std::array<_detail::member_desc_info, sizeof...(Args)> _member_info;
> +};
> +
> +template <typename T, typename... Args>
> +std::unique_ptr<T> read_by_ptr(Eet_File* file, const char* name, 
> descriptor<T, Args...> const& d)
> +{
> +  void* p = eet_data_read(file, const_cast<descriptor<T, 
> Args...>&>(d).native_handle(), name);
> +  return std::unique_ptr<T>(static_cast<T*>(p));
> +}
> +
> +template <typename T, typename... Args>
> +T read(Eet_File* file, const char* name, descriptor<T, Args...> const& d)
> +{
> +  typename std::aligned_storage<sizeof(T), alignof(T)>::type buffer;
> +  void * p =
> +    ::eet_data_read_cipher_buffer
> +    (file
> +     , const_cast<descriptor<T, Args...>&>(d).native_handle()
> +     , name, 0
> +     , static_cast<char*>(static_cast<void*>(&buffer))
> +     , sizeof(buffer));
> +  if(p)
> +    {
> +      assert(p == &buffer);
> +      return *static_cast<T*>(p);
> +    }
> +  else
> +    throw std::runtime_error("");
> +}
> +
> +namespace _detail {
> +
> +template <typename O>
> +inline void _item_fill(O*, ::Eet_Data_Descriptor*, member_desc_info*) {}
> +
> +template <typename O, typename F, typename D, typename... Args, typename... 
> FArgs>
> +inline void _item_fill(O* obj, ::Eet_Data_Descriptor* cls, member_desc_info* 
> offset
> +                       , _detail::member_info<F, D, Args...> arg0, FArgs... 
> args)
> +{
> +  static_assert(std::is_member_object_pointer<F>::value, "");
> +  offset->offset = static_cast<char*>( static_cast<void*>( &(obj ->* 
> arg0.member) ))
> +    - static_cast<char*>( static_cast<void*>( obj ) );
> +  offset->name = arg0.name;
> +  _detail::_item_fill(obj, cls, ++offset, args...);
> +}
> +
> +}
> +
> +template <typename F, typename D, typename... OArgs, typename... Args>
> +typename _detail::descriptor_type
> +<typename _detail::object_type<F>::type
> + , _detail::member_info<F, D, OArgs...>, Args...
> +>::type make_descriptor(const char* name, _detail::member_info<F, D, 
> OArgs...> a0, Args... args)
> +{
> +  typedef F member_pointer;
> +  static_assert(std::is_member_object_pointer<member_pointer>::value, "");
> +  typedef typename _detail::object_type<member_pointer>::type object_type;
> +
> +  typedef typename _detail::descriptor_type
> +    <object_type, _detail::member_info<F, D, OArgs...>, Args...>::type 
> descriptor_type;
> +
> +  ::Eet_Data_Descriptor_Class cls
> +  {
> +      EET_DATA_DESCRIPTOR_CLASS_VERSION
> +    , name
> +    , sizeof(object_type)
> +    , {
> +        & _detail::_allocate<object_type>
> +      , & _detail::_deallocate<object_type>
> +      }
> +  };
> +  ::Eet_Data_Descriptor* native_handle = 
> eet_data_descriptor_stream_new(&cls);
> +  if(!native_handle)
> +    throw std::runtime_error("");
> +
> +  typename std::aligned_storage<sizeof(object_type), 
> alignof(object_type)>::type buffer;
> +  object_type* p = static_cast<object_type*>(static_cast<void*>(&buffer));
> +
> +  std::array<_detail::member_desc_info, sizeof...(Args)+1> offsets;
> +  _detail::_item_fill(p, native_handle, &offsets[0], a0, args...);
> +  _detail::descriptor_type_register(native_handle, &offsets[0], a0, args...);
> +
> +  return descriptor_type(native_handle, offsets);
> +}
> +
> +} }
> +
> +#endif
> diff --git a/src/bindings/eet_cxx/eet_composite.hh 
> b/src/bindings/eet_cxx/eet_composite.hh
> new file mode 100644
> index 0000000..2c8f6be
> --- /dev/null
> +++ b/src/bindings/eet_cxx/eet_composite.hh
> @@ -0,0 +1,49 @@
> +#ifndef EFL_EET_COMPOSITE_HH_
> +#define EFL_EET_COMPOSITE_HH_
> +
> +namespace efl { namespace eet {
> +
> +template <typename, typename...> struct descriptor;
> +
> +namespace _detail {
> +
> +struct member_desc_info
> +{
> +  const char* name;
> +  std::size_t offset;
> +};
> +
> +template <std::size_t E, typename U, typename... Types>
> +void descriptor_register_composite_member( ::Eet_Data_Descriptor*, int
> +                                           , eet::descriptor<U, 
> Types...>const*
> +                                           , 
> std::integral_constant<std::size_t, E>)
> +{
> +}
> +
> +template <std::size_t E, typename U, typename... Types, std::size_t I>
> +void descriptor_register_composite_member( ::Eet_Data_Descriptor* cls, int 
> offset_base
> +                                           , eet::descriptor<U, 
> Types...>const* descriptor
> +                                           , 
> std::integral_constant<std::size_t, I>
> +                                           , typename std::enable_if<E != 
> I>::type* = 0)
> +{
> +  typedef typename std::tuple_element<I, std::tuple<Types...> >::type 
> member_type;
> +  eet_data_descriptor_element_add(cls, descriptor->get_member_info()[I].name
> +                                  , _eet_type<member_type>::value, 
> EET_G_UNKNOWN
> +                                  , offset_base + 
> descriptor->get_member_info()[I].offset
> +                                  , 0, nullptr, nullptr);
> +
> +  _detail::descriptor_register_composite_member<E>
> +    (cls, offset_base, descriptor, std::integral_constant<std::size_t, 
> I+1>());
> +}
> +
> +template <typename U, typename...Types>
> +void descriptor_type_register_composite( ::Eet_Data_Descriptor* cls, 
> member_desc_info info
> +                                         , eet::descriptor<U, 
> Types...>const* descriptor)
> +{
> +  _detail::descriptor_register_composite_member<eet::descriptor<U, 
> Types...>::members::value>
> +    (cls, info.offset, descriptor, std::integral_constant<std::size_t, 
> 0u>());
> +}
> +
> +} } }
> +
> +#endif
> diff --git a/src/bindings/eet_cxx/eet_fold.hh 
> b/src/bindings/eet_cxx/eet_fold.hh
> new file mode 100644
> index 0000000..7ff19ae
> --- /dev/null
> +++ b/src/bindings/eet_cxx/eet_fold.hh
> @@ -0,0 +1,32 @@
> +#ifndef EFL_EET_FOLD_HH_
> +#define EFL_EET_FOLD_HH_
> +
> +#include <eet_tuple.hh>
> +
> +namespace efl { namespace eet {
> +
> +namespace _mpl {
> +
> +template <typename T, typename F, typename A0, bool B = std::is_same<T, 
> std::tuple<> >::value>
> +struct fold_impl
> +{
> +  typedef typename F::template apply<A0, typename std::tuple_element<0, 
> T>::type>::type result;
> +  typedef typename fold_impl<typename pop_front<T>::type
> +                             , F, result
> +                             >::type
> +  type;
> +};
> +
> +template <typename T, typename F, typename A0>
> +struct fold_impl<T, F, A0, true>
> +{
> +  typedef A0 type;
> +};
> +
> +template <typename T, typename F, typename A0>
> +struct fold : fold_impl<T, F, A0>
> +{};
> +
> +} } }
> +
> +#endif
> diff --git a/src/bindings/eet_cxx/eet_register.hh 
> b/src/bindings/eet_cxx/eet_register.hh
> new file mode 100644
> index 0000000..e2a5142
> --- /dev/null
> +++ b/src/bindings/eet_cxx/eet_register.hh
> @@ -0,0 +1,132 @@
> +#ifndef EFL_EET_REGISTER_HH_
> +#define EFL_EET_REGISTER_HH_
> +
> +#include <eet_type.hh>
> +#include <eet_composite.hh>
> +
> +namespace efl { namespace eet {
> +
> +template <typename, typename...> struct descriptor;
> +
> +namespace _detail {
> +
> +template <typename T>
> +struct member_type;
> +
> +template <typename T, typename U>
> +struct member_type<T(U::*)>
> +{
> +  typedef T type;
> +};
> +
> +template <typename T>
> +struct object_type;
> +
> +template <typename T, typename U>
> +struct object_type<T(U::*)>
> +{
> +  typedef U type;
> +};
> +
> +template <typename F, typename T, typename... Args>
> +struct member_info
> +{
> +  typedef F member_type;
> +
> +  const char* name;
> +  F member;
> +  eet::descriptor<T, Args...> const* descriptor;
> +};
> +
> +template <typename F>
> +struct member_info<F, void>
> +{
> +  typedef F member_type;
> +
> +  const char* name;
> +  F member;
> +};
> +
> +template <typename F, typename U, typename... Args>
> +void descriptor_type_register_impl
> + (std::false_type
> +  , ::Eet_Data_Descriptor* cls
> +  , member_desc_info i
> +  , member_info<F, U, Args...> arg0
> +  , typename std::enable_if
> +  <
> +    !std::is_pointer<typename _detail::member_type<F>::type>::value
> +  >::type* = 0)
> +{
> +  // composition by value
> +  static_assert(std::is_member_object_pointer<F>::value, "");
> +  typedef typename _detail::member_type<F>::type member_type;
> +  typedef typename _detail::object_type<F>::type object_type;
> +  static_assert(!std::is_pointer<member_type>::value, "");
> +  static_assert(std::is_same<member_type, U>::value, "");
> +  static_assert(std::is_pod<member_type>::value, "");
> +
> +  _detail::descriptor_type_register_composite(cls, i, arg0.descriptor);
> +}
> +
> +template <typename F, typename U, typename... Args>
> +void descriptor_type_register_impl
> + (std::false_type
> +  , ::Eet_Data_Descriptor* cls
> +  , member_desc_info i
> +  , member_info<F, U, Args...> arg0
> +  , typename std::enable_if
> +  <
> +    std::is_pointer<typename _detail::member_type<F>::type>::value
> +  >::type* = 0)
> +{
> +  // composition by pointer
> +  static_assert(std::is_member_object_pointer<F>::value, "");
> +  typedef typename _detail::member_type<F>::type pointer_member_type;
> +  typedef typename _detail::object_type<F>::type object_type;
> +  static_assert(std::is_pointer<pointer_member_type>::value, "");
> +  typedef typename std::remove_pointer<pointer_member_type>::type 
> member_type;
> +  static_assert(std::is_same<member_type, U>::value, "");
> +
> +  eet_data_descriptor_element_add
> +    (cls, i.name
> +     , EET_T_UNKNOW
> +     , EET_G_UNKNOWN
> +     , i.offset
> +     , 0
> +     , nullptr
> +     , const_cast<descriptor<U, 
> Args...>*>(arg0.descriptor)->native_handle());
> +}
> +
> +template <typename F>
> +void descriptor_type_register_impl
> + (std::true_type, ::Eet_Data_Descriptor* cls
> +  , member_desc_info i
> +  , member_info<F, void>)
> +{
> +  static_assert(std::is_member_object_pointer<F>::value, "");
> +  typedef typename _detail::member_type<F>::type member_type;
> +  typedef typename _detail::object_type<F>::type object_type;
> +
> +  eet_data_descriptor_element_add(cls, i.name, 
> _eet_type<member_type>::value, EET_G_UNKNOWN
> +                                  , i.offset, 0, nullptr, nullptr);
> +}
> +
> +inline void descriptor_type_register( ::Eet_Data_Descriptor*, 
> member_desc_info*)
> +{
> +}
> +
> +template <typename F, typename D, typename... Args, typename... FArgs>
> +void descriptor_type_register( ::Eet_Data_Descriptor* cls, member_desc_info* 
> i
> +                               , member_info<F, D, Args...> a0, FArgs... 
> args)
> +{
> +  static_assert(std::is_member_object_pointer<F>::value, "");
> +  typedef typename _detail::member_type<F>::type member_type;
> +
> +  _detail::descriptor_type_register_impl(is_eet_primitive<member_type>(), 
> cls, *i, a0);
> +  _detail::descriptor_type_register(cls, ++i, args...);
> +}
> +
> +} } }
> +
> +#endif
> diff --git a/src/bindings/eet_cxx/eet_tuple.hh 
> b/src/bindings/eet_cxx/eet_tuple.hh
> new file mode 100644
> index 0000000..2fbb395
> --- /dev/null
> +++ b/src/bindings/eet_cxx/eet_tuple.hh
> @@ -0,0 +1,39 @@
> +#ifndef EFL_EET_EET_TUPLE_HH_
> +#define EFL_EET_EET_TUPLE_HH_
> +
> +namespace efl { namespace eet {
> +
> +namespace _mpl {
> +
> +template <typename A, typename... Args>
> +struct push_back;
> +
> +template <template <typename... Args> class C, typename... Args, typename... 
> AArgs>
> +struct push_back<C<Args...>, AArgs...>
> +{
> +  typedef C<Args..., AArgs...> type;
> +};
> +
> +template <typename A, typename... Args>
> +struct push_front;
> +
> +template <template <typename... Args> class C, typename... Args, typename... 
> AArgs>
> +struct push_front<C<Args...>, AArgs...>
> +{
> +  typedef C<Args..., AArgs...> type;
> +};
> +
> +template <typename A>
> +struct pop_front;
> +
> +template <template <typename...> class C, typename T, typename... Args>
> +struct pop_front<C<T, Args...> >
> +{
> +  typedef C<Args...> type;
> +};
> +
> +}
> +
> +} }
> +
> +#endif
> diff --git a/src/bindings/eet_cxx/eet_type.hh 
> b/src/bindings/eet_cxx/eet_type.hh
> new file mode 100644
> index 0000000..e12bc98
> --- /dev/null
> +++ b/src/bindings/eet_cxx/eet_type.hh
> @@ -0,0 +1,78 @@
> +#ifndef _EET_TYPE_HH
> +#define _EET_TYPE_HH
> +
> +#include <Eet.h>
> +#include <Eina.hh>
> +
> +#include <type_traits>
> +
> +namespace efl { namespace eet {
> +
> +template <typename T>
> +struct _eet_type;
> +
> +template <>
> +struct _eet_type<char> : std::integral_constant<int, EET_T_CHAR>
> +{};
> +
> +template <>
> +struct _eet_type<short> : std::integral_constant<int, EET_T_SHORT>
> +{};
> +
> +template <>
> +struct _eet_type<int> : std::integral_constant<int, EET_T_INT>
> +{};
> +
> +template <>
> +struct _eet_type<long long> : std::integral_constant<int, EET_T_LONG_LONG>
> +{};
> +
> +template <>
> +struct _eet_type<float> : std::integral_constant<int, EET_T_FLOAT>
> +{};
> +
> +template <>
> +struct _eet_type<double> : std::integral_constant<int, EET_T_DOUBLE>
> +{};
> +
> +template <>
> +struct _eet_type<unsigned char> : std::integral_constant<int, EET_T_UCHAR>
> +{};
> +
> +template <>
> +struct _eet_type<unsigned short> : std::integral_constant<int, EET_T_USHORT>
> +{};
> +
> +template <>
> +struct _eet_type<unsigned int> : std::integral_constant<int, EET_T_UINT>
> +{};
> +
> +template <>
> +struct _eet_type<unsigned long long> : std::integral_constant<int, 
> EET_T_ULONG_LONG>
> +{};
> +
> +template <>
> +struct _eet_type<char*> : std::integral_constant<int, EET_T_STRING>
> +{};
> +
> +template <>
> +struct _eet_type<void*> : std::integral_constant<int, EET_T_NULL>
> +{};
> +
> +template <>
> +struct _eet_type<eina::value> : std::integral_constant<int, EET_T_VALUE>
> +{};
> +
> +template <typename T>
> +struct _void { typedef void type; };
> +
> +template <typename T, typename Enabler = void>
> +struct is_eet_primitive : std::false_type {};
> +
> +template <typename T>
> +struct is_eet_primitive<T, typename _void<typename _eet_type<T>::type>::type>
> +  : std::true_type {};
> +
> +} }
> +
> +#endif
> diff --git a/src/lib/eet/Eet.h b/src/lib/eet/Eet.h
> index ab90733..60e58d4 100644
> --- a/src/lib/eet/Eet.h
> +++ b/src/lib/eet/Eet.h
> @@ -3528,6 +3528,43 @@ eet_data_read_cipher(Eet_File *ef,
>                        const char *cipher_key);
>
>   /**
> + * Read a data structure from an eet file and decodes it into a buffer using 
> a cipher,
> + * @param ef The eet file handle to read from.
> + * @param edd The data descriptor handle to use when decoding.
> + * @param name The key the data is stored under in the eet file.
> + * @param cipher_key The key to use as cipher.
> + * @param buffer Buffer
> + * @return A pointer to buffer if successful and NULL on error.
> + *
> + * This function decodes a data structure stored in an eet file, returning
> + * a pointer to it if it decoded successfully, or NULL on failure. This
> + * can save a programmer dozens of hours of work in writing configuration
> + * file parsing and writing code, as eet does all that work for the program
> + * and presents a program-friendly data structure, just as the programmer
> + * likes. Eet can handle members being added or deleted from the data in
> + * storage and safely zero-fills unfilled members if they were not found
> + * in the data. It checks sizes and headers whenever it reads data, allowing
> + * the programmer to not worry about corrupt data.
> + *
> + * Once a data structure has been described by the programmer with the
> + * fields they wish to save or load, storing or retrieving a data structure
> + * from an eet file, or from a chunk of memory is as simple as a single
> + * function call.
> + *
> + * @see eet_data_read_cipher()
> + *
> + * @since 1.10.0
> + * @ingroup Eet_Data_Cipher_Group
> + */
> +EAPI void *
> +eet_data_read_cipher_buffer(Eet_File            *ef,
> +                            Eet_Data_Descriptor *edd,
> +                            const char          *name,
> +                            const char          *cipher_key,
> +                            char                *buffer,
> +                            int                 buffer_size);
> +
> +/**
>    * Read a data structure from an eet extended attribute and decodes it 
> using a cipher.
>    * @param filename The file to extract the extended attribute from.
>    * @param attribute The attribute to get the data from.
> diff --git a/src/lib/eet/eet_data.c b/src/lib/eet/eet_data.c
> index ea51ed0..c92a526 100644
> --- a/src/lib/eet/eet_data.c
> +++ b/src/lib/eet/eet_data.c
> @@ -2284,6 +2284,44 @@ eet_data_read_cipher(Eet_File            *ef,
>      return data_dec;
>   }
>
> +EAPI void *
> +eet_data_read_cipher_buffer(Eet_File            *ef,
> +                            Eet_Data_Descriptor *edd,
> +                            const char          *name,
> +                            const char          *cipher_key,
> +                            char* buffer,
> +                            int buffer_size)
> +{
> +   const Eet_Dictionary *ed = NULL;
> +   const void *data = NULL;
> +   void *data_dec;
> +   Eet_Free_Context context;
> +   int required_free = 0;
> +   int size;
> +
> +   ed = eet_dictionary_get(ef);
> +
> +   if (!cipher_key)
> +     data = eet_read_direct(ef, name, &size);
> +
> +   if (!data)
> +     {
> +        required_free = 1;
> +        data = eet_read_cipher(ef, name, &size, cipher_key);
> +        if (!data)
> +          return NULL;
> +     }
> +
> +   eet_free_context_init(&context);
> +   data_dec = _eet_data_descriptor_decode(&context, ed, edd, data, size, 
> buffer, buffer_size);
> +   eet_free_context_shutdown(&context);
> +
> +   if (required_free)
> +     free((void *)data);
> +
> +   return data_dec;
> +}
> +
>   EAPI Eet_Node *
>   eet_data_node_read_cipher(Eet_File   *ef,
>                             const char *name,
> diff --git a/src/tests/eet_cxx/eet_cxx_suite.cc 
> b/src/tests/eet_cxx/eet_cxx_suite.cc
> new file mode 100644
> index 0000000..26e658b
> --- /dev/null
> +++ b/src/tests/eet_cxx/eet_cxx_suite.cc
> @@ -0,0 +1,104 @@
> +
> +#include "Eet.hh"
> +#include <Eina.h>
> +
> +#include <cassert>
> +#include <algorithm>
> +
> +#include <check.h>
> +
> +void eet_test_descriptors(TCase* tc);
> +
> +typedef struct _Eet_Test_Case Eet_Test_Case;
> +struct _Eet_Test_Case
> +{
> +   const char *test_case;
> +   void (*build)(TCase *tc);
> +};
> +
> +static const Eet_Test_Case etc[] = {
> +   { "Descriptors", eet_test_descriptors },
> +   { NULL, NULL }
> +};
> +
> +static void
> +_list_tests(void)
> +{
> +   const Eet_Test_Case *itr = etc;
> +      fputs("Available Test Cases:\n", stderr);
> +   for (; itr->test_case; itr++)
> +      fprintf(stderr, "\t%s\n", itr->test_case);
> +}
> +
> +static Eina_Bool
> +_use_test(int argc, const char **argv, const char *test_case)
> +{
> +   if (argc < 1)
> +      return 1;
> +
> +   for (; argc > 0; argc--, argv++)
> +      if (strcmp(test_case, *argv) == 0)
> +         return 1;
> +
> +   return 0;
> +}
> +
> +Suite *
> +eet_build_suite(int argc, const char **argv)
> +{
> +   TCase *tc;
> +   Suite *s;
> +   int i;
> +
> +   s = suite_create("Eet C++");
> +
> +   for (i = 0; etc[i].test_case; ++i)
> +     {
> +        if (!_use_test(argc, argv, etc[i].test_case))
> +           continue;
> +
> +        tc = tcase_create(etc[i].test_case);
> +        tcase_set_timeout(tc, 0);
> +
> +        etc[i].build(tc);
> +        suite_add_tcase(s, tc);
> +     }
> +
> +   return s;
> +}
> +
> +int main(int argc, char* argv[])
> +{
> +   Suite *s;
> +   SRunner *sr;
> +   int i, failed_count;
> +
> +   for (i = 1; i < argc; i++)
> +      if ((strcmp(argv[i], "-h") == 0) ||
> +          (strcmp(argv[i], "--help") == 0))
> +        {
> +           fprintf(stderr, "Usage:\n\t%s [test_case1 .. [test_caseN]]\n",
> +                   argv[0]);
> +           _list_tests();
> +           return 0;
> +        }
> +      else if ((strcmp(argv[i], "-l") == 0) ||
> +               (strcmp(argv[i], "--list") == 0))
> +        {
> +           _list_tests();
> +           return 0;
> +        }
> +
> +   putenv(const_cast<char*>("EFL_RUN_IN_TREE=1"));
> +
> +   s = eet_build_suite(argc - 1, (const char **)argv + 1);
> +   sr = srunner_create(s);
> +
> +   srunner_set_xml(sr, TESTS_BUILD_DIR "/check-results.xml");
> +
> +   srunner_run_all(sr, CK_ENV);
> +   failed_count = srunner_ntests_failed(sr);
> +   srunner_free(sr);
> +
> +   return (failed_count == 0) ? 0 : 255;
> +}
> diff --git a/src/tests/eet_cxx/eet_cxx_test_descriptors.cc 
> b/src/tests/eet_cxx/eet_cxx_test_descriptors.cc
> new file mode 100644
> index 0000000..bc21418
> --- /dev/null
> +++ b/src/tests/eet_cxx/eet_cxx_test_descriptors.cc
> @@ -0,0 +1,231 @@
> +
> +#include "Eet.hh"
> +
> +#include <algorithm>
> +
> +#include <iostream>
> +
> +#include <check.h>
> +
> +struct pod_type
> +{
> +  int i;
> +  char c;
> +};
> +
> +START_TEST(eet_cxx_descriptors)
> +{
> +  efl::eet::eet_init init;
> +
> +  auto d = efl::eet::make_descriptor
> +    ("pod_type"
> +     , efl::eet::type("i", &pod_type::i)
> +     , efl::eet::type("c", &pod_type::c));
> +  static_assert(std::is_same<efl::eet::descriptor<pod_type, int, char>, 
> decltype(d)>::value, "");
> +
> +  Eet_File* file = eet_open("/tmp/eet_file_test.eet", 
> EET_FILE_MODE_READ_WRITE);
> +  ck_assert(file != 0);
> +
> +  pod_type pod = {1, 2};
> +
> +  int s = eet_data_write(file, d.native_handle(), "pod", &pod, true);
> +  std::cout << "bytes written " << s << std::endl;
> +  ck_assert(s > 0);
> +  eet_sync(file);
> +  auto p = efl::eet::read_by_ptr(file, "pod", d);
> +  ck_assert(p != 0);
> +  ck_assert(p->i == 1);
> +  ck_assert(p->c == 2);
> +
> +  eet_close(file);
> +}
> +END_TEST
> +
> +int constructors_called = 0
> +    , destructors_called = 0;
> +
> +struct non_pod
> +{
> +  non_pod() : i(10)
> +  {
> +    ++constructors_called;
> +  }
> +  non_pod(non_pod const& other)
> +    : i(other.i)
> +  {
> +    ++constructors_called;
> +  }
> +  ~non_pod()
> +  {
> +    ++destructors_called;
> +  }
> +
> +  int i;
> +};
> +
> +START_TEST(eet_cxx_descriptors_non_pod)
> +{
> +  efl::eet::eet_init init;
> +
> +  auto d = efl::eet::make_descriptor
> +    ("pod_type", EET_CXX_MEMBER(non_pod, i));
> +  static_assert(std::is_same<efl::eet::descriptor<non_pod, int>, 
> decltype(d)>::value, "");
> +
> +  {
> +    Eet_File* file = eet_open("/tmp/eet_file_test.eet", 
> EET_FILE_MODE_READ_WRITE);
> +    ck_assert(file != 0);
> +
> +    ::non_pod non_pod;
> +
> +    int s = eet_data_write(file, d.native_handle(), "non_pod", &non_pod, 
> true);
> +    std::cout << "bytes written " << s << std::endl;
> +    ck_assert(s > 0);
> +    eet_sync(file);
> +    auto p = efl::eet::read_by_ptr(file, "non_pod", d);
> +    ck_assert(p != 0);
> +    ck_assert(p->i == 10);
> +
> +    auto v = efl::eet::read(file, "non_pod", d);
> +    ck_assert(v.i == 10);
> +
> +    eet_close(file);
> +  }
> +
> +  std::cout << "constructors called for non pod: " << constructors_called
> +            << " destructors called for non pod: " << destructors_called << 
> std::endl;
> +
> +  ck_assert(constructors_called == destructors_called);
> +}
> +END_TEST
> +
> +struct pod_composited
> +{
> +  pod_type* member;
> +};
> +
> +struct pod_composited_with_non_pod
> +{
> +  non_pod* member;
> +};
> +
> +struct pod_value_composited
> +{
> +  pod_type member;
> +};
> +
> +START_TEST(eet_cxx_descriptors_composition)
> +{
> +  efl::eet::eet_init init;
> +
> +  auto pod_descriptor = efl::eet::make_descriptor
> +    ("pod_type"
> +     , efl::eet::type("i", &pod_type::i)
> +     , efl::eet::type("c", &pod_type::c));
> +  static_assert(std::is_same<efl::eet::descriptor<pod_type, int, char>
> +                , decltype(pod_descriptor)>::value, "");
> +
> +  auto non_pod_descriptor = efl::eet::make_descriptor
> +    ("non_pod"
> +     , efl::eet::type("i", &non_pod::i));
> +  static_assert(std::is_same<efl::eet::descriptor<non_pod, int>
> +                , decltype(non_pod_descriptor)>::value, "");
> +
> +  {
> +    auto d = efl::eet::make_descriptor
> +      ("pod_composited", efl::eet::type("pod_composited", 
> &pod_composited::member, pod_descriptor));
> +    static_assert(std::is_same<efl::eet::descriptor<pod_composited, 
> pod_type*>, decltype(d)>::value, "");
> +
> +    Eet_File* file = eet_open("/tmp/eet_file_test.eet", 
> EET_FILE_MODE_READ_WRITE);
> +    ck_assert(file != 0);
> +
> +    ::pod_composited pod_composited {new pod_type{5, 'a'}};
> +
> +    int s = eet_data_write(file, d.native_handle(), "foo", &pod_composited, 
> false);
> +    ck_assert(s > 0);
> +    eet_sync(file);
> +    auto p = efl::eet::read_by_ptr(file, "foo", d);
> +    ck_assert(p != 0);
> +    ck_assert(p->member->i == 5);
> +    ck_assert(p->member->c == 'a');
> +
> +    delete p->member;
> +
> +    auto v = efl::eet::read(file, "foo", d);
> +    ck_assert(v.member->i == 5);
> +    ck_assert(v.member->c == 'a');
> +
> +    delete v.member;
> +
> +    eet_close(file);
> +  }
> +
> +  {
> +    auto d = efl::eet::make_descriptor
> +      ("pod_composited_with_non_pod", 
> efl::eet::type("pod_composited_with_non_pod", 
> &pod_composited_with_non_pod::member, non_pod_descriptor));
> +    
> static_assert(std::is_same<efl::eet::descriptor<pod_composited_with_non_pod, 
> non_pod*>, decltype(d)>::value, "");
> +
> +    Eet_File* file = eet_open("/tmp/eet_file_test.eet", 
> EET_FILE_MODE_READ_WRITE);
> +    ck_assert(file != 0);
> +
> +    ::pod_composited_with_non_pod pod_composited_with_non_pod {new non_pod};
> +
> +    int s = eet_data_write(file, d.native_handle(), "foo", 
> &pod_composited_with_non_pod, false);
> +    ck_assert(s > 0);
> +    eet_sync(file);
> +    auto p = efl::eet::read_by_ptr(file, "foo", d);
> +    ck_assert(p != 0);
> +    ck_assert(p->member->i == 10);
> +
> +    delete p->member;
> +
> +    auto v = efl::eet::read(file, "foo", d);
> +    ck_assert(v.member->i == 10);
> +
> +    delete v.member;
> +
> +    eet_close(file);
> +
> +    delete pod_composited_with_non_pod.member;
> +  }
> +
> +  std::cout << "constructors called for non pod: " << constructors_called
> +            << " destructors called for non pod: " << destructors_called << 
> std::endl;
> +
> +  ck_assert(constructors_called == destructors_called);
> +
> +  {
> +    auto d = efl::eet::make_descriptor
> +      ("pod_value_composited", efl::eet::type("member"
> +                                              , 
> &pod_value_composited::member, pod_descriptor));
> +    static_assert(std::is_same<efl::eet::descriptor<pod_value_composited, 
> pod_type>, decltype(d)>::value, "");
> +
> +    Eet_File* file = eet_open("/tmp/eet_file_test.eet", 
> EET_FILE_MODE_READ_WRITE);
> +    ck_assert(file != 0);
> +
> +    ::pod_value_composited pod_value_composited {{5, 'a'}};
> +
> +    int s = eet_data_write(file, d.native_handle(), "foo", 
> &pod_value_composited, false);
> +    ck_assert(s > 0);
> +    eet_sync(file);
> +    auto p = efl::eet::read_by_ptr(file, "foo", d);
> +    ck_assert(p != 0);
> +    ck_assert(p->member.i == 5);
> +    ck_assert(p->member.c == 'a');
> +
> +    auto v = efl::eet::read(file, "foo", d);
> +    ck_assert(v.member.i == 5);
> +    ck_assert(v.member.c == 'a');
> +
> +    eet_close(file);
> +  }
> +
> +}
> +END_TEST
> +
> +void
> +eet_test_descriptors(TCase* tc)
> +{
> +  tcase_add_test(tc, eet_cxx_descriptors);
> +  tcase_add_test(tc, eet_cxx_descriptors_non_pod);
> +  tcase_add_test(tc, eet_cxx_descriptors_composition);
> +}
>


------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to