inline bool is_struct_blacklisted(std::string const& full_name)
{
return full_name == "Efl.Event.Description"
- // || full_name == "Eina.File"
|| full_name == "Eina.Binbuf"
|| full_name == "Eina.Slice"
|| full_name == "Eina.Rw_Slice";
return regular && regular->is_struct() && !is_struct_blacklisted(*regular);
}
+inline bool need_pointer_conversion(attributes::regular_type_def const* regular)
+{
+ if (!regular)
+ return false;
+
+ if (regular->is_enum()
+ || (regular->is_struct() && type_full_name(*regular) != "Eina.Binbuf")
+ )
+ return true;
+
+ std::set<std::string> const types {
+ "bool", "char"
+ , "byte" , "short" , "int" , "long" , "llong" , "int8" , "int16" , "int32" , "int64" , "ssize"
+ , "ubyte", "ushort", "uint", "ulong", "ullong", "uint8", "uint16", "uint32", "uint64", "size"
+ , "ptrdiff"
+ , "float", "double"
+ };
+ if (types.find(regular->base_type) != types.end())
+ return true;
+
+ return false;
+}
+
+
}
#endif
}}
};
- if (regular.is_struct() && !is_struct_blacklisted(regular))
+ if (!is_ptr && regular.is_struct() && !is_struct_blacklisted(regular))
{
return as_generator(*(lower_case[string] << ".") << string << "_StructInternal")
.generate(sink, std::make_tuple(eolian_mono::escape_namespace(regular.namespaces), regular.base_type), *context);
{
return *b;
}
+ else if (is_ptr && need_pointer_conversion(®ular))
+ {
+ regular_type_def r = regular;
+ r.base_type = " System.IntPtr";
+ r.namespaces.clear();
+ return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(r);
+ }
else
{
- return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return}(regular);
+ return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(regular);
}
}
bool operator()(attributes::klass_name klass_name) const
{
- return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return}(klass_name);
+ return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(klass_name);
// return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
}
bool operator()(attributes::complex_type_def const& complex) const
}
//return default_match(complex);
- return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return}(complex);
+ return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(complex);
// return as_generator(" System.IntPtr").generate(sink, attributes::unused, *context);
}
};
if (need_struct_conversion(regular))
return true;
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ return true;
+
return false;
}
if (need_struct_conversion(regular))
return true;
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ return true;
+
return false;
}
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (need_struct_conversion(regular))
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ "var " << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << escape_keyword(param.param_name) << ");\n"
+ ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
+ }
+ else if (need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = " << type << "_StructConvertion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (need_struct_conversion(regular))
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ "var " << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << escape_keyword(param.param_name) << ");\n"
+ ).generate(sink, in_variable_name(param.param_name), context);
+ }
+ else if (need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = " << type << "_StructConvertion.ToInternal(" << escape_keyword(param.param_name) << ");\n"
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (need_struct_conversion(regular))
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ "System.IntPtr " << string << " = System.IntPtr.Zero;\n"
+ ).generate(sink, out_variable_name(param.param_name), context);
+ }
+ else if (need_struct_conversion(regular))
{
return as_generator(
"var " << string << " = new " << marshall_type << "();\n"
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (need_struct_conversion(regular)
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ type << " " << string << " = default(" << type << ");\n"
+ ).generate(sink, std::make_tuple(param, out_variable_name(param.param_name), param), context);
+ }
+ else if (need_struct_conversion(regular)
|| param_is_acceptable(param, "const char *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Stringshare *", !WANT_OWN, WANT_OUT))
{
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (need_struct_conversion(regular))
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(" << out_variable_name(param.param_name) << ");\n"
+ ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
+ }
+ else if (need_struct_conversion(regular))
{
return as_generator(
string << " = " << type << "_StructConvertion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
- if (need_struct_conversion(regular))
+ if (ret_type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ "return eina.PrimitiveConversion.PointerToManaged<" << type << ">(_ret_var);\n"
+ ).generate(sink, ret_type, context);
+ }
+ else if (need_struct_conversion(regular))
{
return as_generator(
"return " << type << "_StructConvertion.ToExternal(_ret_var);\n"
return true;
auto regular = efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
- if (need_struct_conversion(regular))
+ if (param.type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(" << string << ");\n"
+ ).generate(sink, std::make_tuple(escape_keyword(param.param_name), out_variable_name(param.param_name)), context);
+ }
+ else if (need_struct_conversion(regular))
{
return as_generator(
string << " = " << type << "_StructConvertion.ToInternal(" << string << ");\n"
bool generate(OutputIterator sink, attributes::type_def const& ret_type, Context const& context) const
{
auto regular = efl::eina::get<attributes::regular_type_def>(&ret_type.original_type);
- if (need_struct_conversion(regular))
+ if (ret_type.is_ptr && need_pointer_conversion(regular))
+ {
+ return as_generator(
+ "return eina.PrimitiveConversion.ManagedToPointerAlloc(_ret_var);\n"
+ ).generate(sink, attributes::unused, context);
+ }
+ else if (need_struct_conversion(regular))
{
return as_generator(
"return " << type << "_StructConvertion.ToInternal(_ret_var);\n"
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
+ else if (field.type.is_ptr && need_pointer_conversion(regular))
+ {
+ if (!as_generator(
+ scope_tab << scope_tab << "_internal_struct." << string << " = eina.PrimitiveConversion.ManagedToPointerAlloc(_external_struct." << string << ");\n")
+ .generate(sink, std::make_tuple(field_name, field_name), context))
+ return false;
+ }
else if (need_struct_conversion(regular))
{
if (!as_generator(
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
+ else if (field.type.is_ptr && need_pointer_conversion(regular))
+ {
+ if (!as_generator(
+ scope_tab << scope_tab << "_external_struct." << string << " = eina.PrimitiveConversion.PointerToManaged<" << type << ">(_internal_struct." << string << ");\n")
+ .generate(sink, std::make_tuple(field_name, field.type, field_name), context))
+ return false;
+ }
else if (need_struct_conversion(regular))
{
if (!as_generator(
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
{
- return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return});
+ return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr});
}
template <typename OutputIterator, typename Context>
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
{
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
- , param.direction != attributes::parameter_direction::in, false});
+ , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr});
}
bool is_return;
std::string c_type;
bool is_out;
bool is_return;
+ bool is_ptr;
typedef visitor_generate<OutputIterator, Context> visitor_type;
typedef bool result_type;
, {"ptrdiff", nullptr, [&] { return replace_base_integer<ptrdiff_t>(regular); }}
, {"intptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
+ , {"uintptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
, {"void_ptr", nullptr, [&] { return replace_base_type(regular, " System.IntPtr"); }}
, {"void", nullptr, [&]
{
}
}
+[StructLayout(LayoutKind.Sequential)]
+public struct ConvertWrapper<T>
+{
+ public T val;
+}
+
+public static class PrimitiveConversion
+{
+ public static T PointerToManaged<T>(IntPtr nat)
+ {
+ if (nat == IntPtr.Zero)
+ {
+ eina.Log.Error("Null pointer for primitive type.");
+ return default(T);
+ }
+
+ var w = Marshal.PtrToStructure<eina.ConvertWrapper<T> >(nat);
+ return w.val;
+ }
+
+ public static IntPtr ManagedToPointerAlloc<T>(T man)
+ {
+ GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned);
+ IntPtr ptr = pinnedData.AddrOfPinnedObject();
+ IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<T>());
+ pinnedData.Free();
+ return nat;
+ }
+}
+
public static class StringConversion
{
public static IntPtr ManagedStringToNativeUtf8Alloc(string managedString)
}
[StructLayout(LayoutKind.Sequential)]
-public struct ConvertWrapper<T>
-{
- public T Val {get;set;}
-}
-
-[StructLayout(LayoutKind.Sequential)]
public struct InlistMem
{
public IntPtr next {get;set;}
public IntPtr ManagedToNativeAlloc(T man)
{
- GCHandle pinnedData = GCHandle.Alloc(man, GCHandleType.Pinned);
- IntPtr ptr = pinnedData.AddrOfPinnedObject();
- IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<T>());
- pinnedData.Free();
- return nat;
+ return PrimitiveConversion.ManagedToPointerAlloc(man);
}
public IntPtr ManagedToNativeAllocInlistNode(T man)
eina.Log.Error("Null pointer on primitive/struct container.");
return default(T);
}
- var w = Marshal.PtrToStructure<eina.ConvertWrapper<T> >(nat);
- return w.Val;
+ return PrimitiveConversion.PointerToManaged<T>(nat);
}
public T NativeToManagedRef(IntPtr nat)