1 #pragma warning disable CS1591
3 using System.Runtime.InteropServices;
4 using System.Collections.Generic;
6 using System.ComponentModel;
7 namespace Efl { namespace Io {
8 /// <summary>Generic interface for objects that can write data from a provided memory.
9 /// This interface allows external objects to transparently write data to this object and be notified whether more data can be written or if it's reached capacity.
11 /// Calls to <see cref="Efl.Io.IWriter.Write"/> may or may not block: that's not up to this interface to specify. The user can check with event "can_write,changed" or property <see cref="Efl.Io.IWriter.CanWrite"/> to known whenever a write could push more data.
12 /// (Since EFL 1.22)</summary>
13 [IWriterNativeInherit]
14 public interface IWriter :
15 Efl.Eo.IWrapper, IDisposable
17 /// <summary>If <c>true</c> will notify <see cref="Efl.Io.IWriter.Write"/> can be called without blocking or failing.
18 /// (Since EFL 1.22)</summary>
19 /// <returns><c>true</c> if it can be written without blocking or failure, <c>false</c> otherwise</returns>
21 /// <summary>If <c>true</c> will notify <see cref="Efl.Io.IWriter.Write"/> can be called without blocking or failing.
22 /// (Since EFL 1.22)</summary>
23 /// <param name="can_write"><c>true</c> if it can be written without blocking or failure, <c>false</c> otherwise</param>
24 /// <returns></returns>
25 void SetCanWrite( bool can_write);
26 /// <summary>Writes data from a pre-populated buffer.
27 /// This operation will be executed immediately and may or may not block the caller thread for some time. The details of blocking behavior is defined by the implementation and may be subject to other parameters such as non-blocking flags, maximum timeout or even retry attempts.
29 /// You can understand this method as write(2) libc function.
30 /// (Since EFL 1.22)</summary>
31 /// <param name="slice">Provides a pre-populated memory to be used up to slice.len. The returned slice will be adapted as length will be set to the actually used amount of bytes, which can be smaller than the request.</param>
32 /// <param name="remaining">Convenience to output the remaining parts of slice that was not written. If the full slice was written, this will be a slice of zero-length.</param>
33 /// <returns>0 on succeed, a mapping of errno otherwise</returns>
34 Eina.Error Write( ref Eina.Slice slice, ref Eina.Slice remaining);
35 /// <summary>Notifies can_write property changed.
36 /// If <see cref="Efl.Io.IWriter.CanWrite"/> is <c>true</c> there is data to <see cref="Efl.Io.IWriter.Write"/> without blocking/error. If <see cref="Efl.Io.IWriter.CanWrite"/> is <c>false</c>, <see cref="Efl.Io.IWriter.Write"/> would either block or fail.
38 /// Note that usually this event is dispatched from inside <see cref="Efl.Io.IWriter.Write"/>, thus before it returns.
39 /// (Since EFL 1.22)</summary>
40 event EventHandler<Efl.Io.IWriterCanWriteChangedEvt_Args> CanWriteChangedEvt;
41 /// <summary>If <c>true</c> will notify <see cref="Efl.Io.IWriter.Write"/> can be called without blocking or failing.
42 /// (Since EFL 1.22)</summary>
43 /// <value><c>true</c> if it can be written without blocking or failure, <c>false</c> otherwise</value>
49 ///<summary>Event argument wrapper for event <see cref="Efl.Io.IWriter.CanWriteChangedEvt"/>.</summary>
50 public class IWriterCanWriteChangedEvt_Args : EventArgs {
51 ///<summary>Actual event payload.</summary>
52 public bool arg { get; set; }
54 /// <summary>Generic interface for objects that can write data from a provided memory.
55 /// This interface allows external objects to transparently write data to this object and be notified whether more data can be written or if it's reached capacity.
57 /// Calls to <see cref="Efl.Io.IWriter.Write"/> may or may not block: that's not up to this interface to specify. The user can check with event "can_write,changed" or property <see cref="Efl.Io.IWriter.CanWrite"/> to known whenever a write could push more data.
58 /// (Since EFL 1.22)</summary>
59 sealed public class IWriterConcrete :
64 ///<summary>Pointer to the native class description.</summary>
65 public System.IntPtr NativeClass {
67 if (((object)this).GetType() == typeof (IWriterConcrete))
68 return Efl.Io.IWriterNativeInherit.GetEflClassStatic();
70 return Efl.Eo.ClassRegister.klassFromType[((object)this).GetType()];
73 private EventHandlerList eventHandlers = new EventHandlerList();
74 private System.IntPtr handle;
75 ///<summary>Pointer to the native instance.</summary>
76 public System.IntPtr NativeHandle {
77 get { return handle; }
79 [System.Runtime.InteropServices.DllImport(efl.Libs.Efl)] internal static extern System.IntPtr
80 efl_io_writer_interface_get();
81 ///<summary>Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>
82 private IWriterConcrete(System.IntPtr raw)
85 RegisterEventProxies();
87 ///<summary>Destructor.</summary>
92 ///<summary>Releases the underlying native instance.</summary>
93 void Dispose(bool disposing)
95 if (handle != System.IntPtr.Zero) {
96 Efl.Eo.Globals.efl_unref(handle);
97 handle = System.IntPtr.Zero;
100 ///<summary>Releases the underlying native instance.</summary>
101 public void Dispose()
104 GC.SuppressFinalize(this);
106 ///<summary>Verifies if the given object is equal to this one.</summary>
107 public override bool Equals(object obj)
109 var other = obj as Efl.Object;
112 return this.NativeHandle == other.NativeHandle;
114 ///<summary>Gets the hash code for this object based on the native pointer it points to.</summary>
115 public override int GetHashCode()
117 return this.NativeHandle.ToInt32();
119 ///<summary>Turns the native pointer into a string representation.</summary>
120 public override String ToString()
122 return $"{this.GetType().Name}@[{this.NativeHandle.ToInt32():x}]";
124 private readonly object eventLock = new object();
125 private Dictionary<string, int> event_cb_count = new Dictionary<string, int>();
126 ///<summary>Adds a new event handler, registering it to the native event. For internal use only.</summary>
127 ///<param name="lib">The name of the native library definining the event.</param>
128 ///<param name="key">The name of the native event.</param>
129 ///<param name="evt_delegate">The delegate to be called on event raising.</param>
130 ///<returns>True if the delegate was successfully registered.</returns>
131 private bool AddNativeEventHandler(string lib, string key, Efl.EventCb evt_delegate) {
133 if (!event_cb_count.TryGetValue(key, out event_count))
134 event_cb_count[key] = event_count;
135 if (event_count == 0) {
136 IntPtr desc = Efl.EventDescription.GetNative(lib, key);
137 if (desc == IntPtr.Zero) {
138 Eina.Log.Error($"Failed to get native event {key}");
141 bool result = Efl.Eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evt_delegate, System.IntPtr.Zero);
143 Eina.Log.Error($"Failed to add event proxy for event {key}");
146 Eina.Error.RaiseIfUnhandledException();
148 event_cb_count[key]++;
151 ///<summary>Removes the given event handler for the given event. For internal use only.</summary>
152 ///<param name="key">The name of the native event.</param>
153 ///<param name="evt_delegate">The delegate to be removed.</param>
154 ///<returns>True if the delegate was successfully registered.</returns>
155 private bool RemoveNativeEventHandler(string key, Efl.EventCb evt_delegate) {
157 if (!event_cb_count.TryGetValue(key, out event_count))
158 event_cb_count[key] = event_count;
159 if (event_count == 1) {
160 IntPtr desc = Efl.EventDescription.GetNative(efl.Libs.Efl, key);
161 if (desc == IntPtr.Zero) {
162 Eina.Log.Error($"Failed to get native event {key}");
165 bool result = Efl.Eo.Globals.efl_event_callback_del(handle, desc, evt_delegate, System.IntPtr.Zero);
167 Eina.Log.Error($"Failed to remove event proxy for event {key}");
170 Eina.Error.RaiseIfUnhandledException();
171 } else if (event_count == 0) {
172 Eina.Log.Error($"Trying to remove proxy for event {key} when there is nothing registered.");
175 event_cb_count[key]--;
178 private static object CanWriteChangedEvtKey = new object();
179 /// <summary>Notifies can_write property changed.
180 /// If <see cref="Efl.Io.IWriter.CanWrite"/> is <c>true</c> there is data to <see cref="Efl.Io.IWriter.Write"/> without blocking/error. If <see cref="Efl.Io.IWriter.CanWrite"/> is <c>false</c>, <see cref="Efl.Io.IWriter.Write"/> would either block or fail.
182 /// Note that usually this event is dispatched from inside <see cref="Efl.Io.IWriter.Write"/>, thus before it returns.
183 /// (Since EFL 1.22)</summary>
184 public event EventHandler<Efl.Io.IWriterCanWriteChangedEvt_Args> CanWriteChangedEvt
188 string key = "_EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED";
189 if (AddNativeEventHandler(efl.Libs.Efl, key, this.evt_CanWriteChangedEvt_delegate)) {
190 eventHandlers.AddHandler(CanWriteChangedEvtKey , value);
192 Eina.Log.Error($"Error adding proxy for event {key}");
197 string key = "_EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED";
198 if (RemoveNativeEventHandler(key, this.evt_CanWriteChangedEvt_delegate)) {
199 eventHandlers.RemoveHandler(CanWriteChangedEvtKey , value);
201 Eina.Log.Error($"Error removing proxy for event {key}");
205 ///<summary>Method to raise event CanWriteChangedEvt.</summary>
206 public void On_CanWriteChangedEvt(Efl.Io.IWriterCanWriteChangedEvt_Args e)
208 EventHandler<Efl.Io.IWriterCanWriteChangedEvt_Args> evt;
210 evt = (EventHandler<Efl.Io.IWriterCanWriteChangedEvt_Args>)eventHandlers[CanWriteChangedEvtKey];
212 evt?.Invoke(this, e);
214 Efl.EventCb evt_CanWriteChangedEvt_delegate;
215 private void on_CanWriteChangedEvt_NativeCallback(System.IntPtr data, ref Efl.Event.NativeStruct evt)
217 Efl.Io.IWriterCanWriteChangedEvt_Args args = new Efl.Io.IWriterCanWriteChangedEvt_Args();
218 args.arg = evt.Info != IntPtr.Zero;
220 On_CanWriteChangedEvt(args);
221 } catch (Exception e) {
222 Eina.Log.Error(e.ToString());
223 Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);
227 ///<summary>Register the Eo event wrappers making the bridge to C# events. Internal usage only.</summary>
228 void RegisterEventProxies()
230 evt_CanWriteChangedEvt_delegate = new Efl.EventCb(on_CanWriteChangedEvt_NativeCallback);
232 /// <summary>If <c>true</c> will notify <see cref="Efl.Io.IWriter.Write"/> can be called without blocking or failing.
233 /// (Since EFL 1.22)</summary>
234 /// <returns><c>true</c> if it can be written without blocking or failure, <c>false</c> otherwise</returns>
235 public bool GetCanWrite() {
236 var _ret_var = Efl.Io.IWriterNativeInherit.efl_io_writer_can_write_get_ptr.Value.Delegate(this.NativeHandle);
237 Eina.Error.RaiseIfUnhandledException();
240 /// <summary>If <c>true</c> will notify <see cref="Efl.Io.IWriter.Write"/> can be called without blocking or failing.
241 /// (Since EFL 1.22)</summary>
242 /// <param name="can_write"><c>true</c> if it can be written without blocking or failure, <c>false</c> otherwise</param>
243 /// <returns></returns>
244 public void SetCanWrite( bool can_write) {
245 Efl.Io.IWriterNativeInherit.efl_io_writer_can_write_set_ptr.Value.Delegate(this.NativeHandle, can_write);
246 Eina.Error.RaiseIfUnhandledException();
248 /// <summary>Writes data from a pre-populated buffer.
249 /// This operation will be executed immediately and may or may not block the caller thread for some time. The details of blocking behavior is defined by the implementation and may be subject to other parameters such as non-blocking flags, maximum timeout or even retry attempts.
251 /// You can understand this method as write(2) libc function.
252 /// (Since EFL 1.22)</summary>
253 /// <param name="slice">Provides a pre-populated memory to be used up to slice.len. The returned slice will be adapted as length will be set to the actually used amount of bytes, which can be smaller than the request.</param>
254 /// <param name="remaining">Convenience to output the remaining parts of slice that was not written. If the full slice was written, this will be a slice of zero-length.</param>
255 /// <returns>0 on succeed, a mapping of errno otherwise</returns>
256 public Eina.Error Write( ref Eina.Slice slice, ref Eina.Slice remaining) {
257 var _ret_var = Efl.Io.IWriterNativeInherit.efl_io_writer_write_ptr.Value.Delegate(this.NativeHandle, ref slice, ref remaining);
258 Eina.Error.RaiseIfUnhandledException();
261 /// <summary>If <c>true</c> will notify <see cref="Efl.Io.IWriter.Write"/> can be called without blocking or failing.
262 /// (Since EFL 1.22)</summary>
263 /// <value><c>true</c> if it can be written without blocking or failure, <c>false</c> otherwise</value>
264 public bool CanWrite {
265 get { return GetCanWrite(); }
266 set { SetCanWrite( value); }
268 private static IntPtr GetEflClassStatic()
270 return Efl.Io.IWriterConcrete.efl_io_writer_interface_get();
273 public class IWriterNativeInherit : Efl.Eo.NativeClass{
274 public static Efl.Eo.NativeModule _Module = new Efl.Eo.NativeModule(efl.Libs.Efl);
275 public override System.Collections.Generic.List<Efl_Op_Description> GetEoOps(System.Type type)
277 var descs = new System.Collections.Generic.List<Efl_Op_Description>();
278 var methods = Efl.Eo.Globals.GetUserMethods(type);
279 if (efl_io_writer_can_write_get_static_delegate == null)
280 efl_io_writer_can_write_get_static_delegate = new efl_io_writer_can_write_get_delegate(can_write_get);
281 if (methods.FirstOrDefault(m => m.Name == "GetCanWrite") != null)
282 descs.Add(new Efl_Op_Description() {api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(_Module.Module, "efl_io_writer_can_write_get"), func = Marshal.GetFunctionPointerForDelegate(efl_io_writer_can_write_get_static_delegate)});
283 if (efl_io_writer_can_write_set_static_delegate == null)
284 efl_io_writer_can_write_set_static_delegate = new efl_io_writer_can_write_set_delegate(can_write_set);
285 if (methods.FirstOrDefault(m => m.Name == "SetCanWrite") != null)
286 descs.Add(new Efl_Op_Description() {api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(_Module.Module, "efl_io_writer_can_write_set"), func = Marshal.GetFunctionPointerForDelegate(efl_io_writer_can_write_set_static_delegate)});
287 if (efl_io_writer_write_static_delegate == null)
288 efl_io_writer_write_static_delegate = new efl_io_writer_write_delegate(write);
289 if (methods.FirstOrDefault(m => m.Name == "Write") != null)
290 descs.Add(new Efl_Op_Description() {api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(_Module.Module, "efl_io_writer_write"), func = Marshal.GetFunctionPointerForDelegate(efl_io_writer_write_static_delegate)});
293 public override IntPtr GetEflClass()
295 return Efl.Io.IWriterConcrete.efl_io_writer_interface_get();
297 public static IntPtr GetEflClassStatic()
299 return Efl.Io.IWriterConcrete.efl_io_writer_interface_get();
303 [return: MarshalAs(UnmanagedType.U1)] private delegate bool efl_io_writer_can_write_get_delegate(System.IntPtr obj, System.IntPtr pd);
306 [return: MarshalAs(UnmanagedType.U1)] public delegate bool efl_io_writer_can_write_get_api_delegate(System.IntPtr obj);
307 public static Efl.Eo.FunctionWrapper<efl_io_writer_can_write_get_api_delegate> efl_io_writer_can_write_get_ptr = new Efl.Eo.FunctionWrapper<efl_io_writer_can_write_get_api_delegate>(_Module, "efl_io_writer_can_write_get");
308 private static bool can_write_get(System.IntPtr obj, System.IntPtr pd)
310 Eina.Log.Debug("function efl_io_writer_can_write_get was called");
311 Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.PrivateDataGet(pd);
312 if(wrapper != null) {
313 bool _ret_var = default(bool);
315 _ret_var = ((IWriter)wrapper).GetCanWrite();
316 } catch (Exception e) {
317 Eina.Log.Warning($"Callback error: {e.ToString()}");
318 Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);
322 return efl_io_writer_can_write_get_ptr.Value.Delegate(Efl.Eo.Globals.efl_super(obj, Efl.Eo.Globals.efl_class_get(obj)));
325 private static efl_io_writer_can_write_get_delegate efl_io_writer_can_write_get_static_delegate;
328 private delegate void efl_io_writer_can_write_set_delegate(System.IntPtr obj, System.IntPtr pd, [MarshalAs(UnmanagedType.U1)] bool can_write);
331 public delegate void efl_io_writer_can_write_set_api_delegate(System.IntPtr obj, [MarshalAs(UnmanagedType.U1)] bool can_write);
332 public static Efl.Eo.FunctionWrapper<efl_io_writer_can_write_set_api_delegate> efl_io_writer_can_write_set_ptr = new Efl.Eo.FunctionWrapper<efl_io_writer_can_write_set_api_delegate>(_Module, "efl_io_writer_can_write_set");
333 private static void can_write_set(System.IntPtr obj, System.IntPtr pd, bool can_write)
335 Eina.Log.Debug("function efl_io_writer_can_write_set was called");
336 Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.PrivateDataGet(pd);
337 if(wrapper != null) {
340 ((IWriter)wrapper).SetCanWrite( can_write);
341 } catch (Exception e) {
342 Eina.Log.Warning($"Callback error: {e.ToString()}");
343 Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);
346 efl_io_writer_can_write_set_ptr.Value.Delegate(Efl.Eo.Globals.efl_super(obj, Efl.Eo.Globals.efl_class_get(obj)), can_write);
349 private static efl_io_writer_can_write_set_delegate efl_io_writer_can_write_set_static_delegate;
352 private delegate Eina.Error efl_io_writer_write_delegate(System.IntPtr obj, System.IntPtr pd, ref Eina.Slice slice, ref Eina.Slice remaining);
355 public delegate Eina.Error efl_io_writer_write_api_delegate(System.IntPtr obj, ref Eina.Slice slice, ref Eina.Slice remaining);
356 public static Efl.Eo.FunctionWrapper<efl_io_writer_write_api_delegate> efl_io_writer_write_ptr = new Efl.Eo.FunctionWrapper<efl_io_writer_write_api_delegate>(_Module, "efl_io_writer_write");
357 private static Eina.Error write(System.IntPtr obj, System.IntPtr pd, ref Eina.Slice slice, ref Eina.Slice remaining)
359 Eina.Log.Debug("function efl_io_writer_write was called");
360 Efl.Eo.IWrapper wrapper = Efl.Eo.Globals.PrivateDataGet(pd);
361 if(wrapper != null) {
362 remaining = default(Eina.Slice); Eina.Error _ret_var = default(Eina.Error);
364 _ret_var = ((IWriter)wrapper).Write( ref slice, ref remaining);
365 } catch (Exception e) {
366 Eina.Log.Warning($"Callback error: {e.ToString()}");
367 Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);
371 return efl_io_writer_write_ptr.Value.Delegate(Efl.Eo.Globals.efl_super(obj, Efl.Eo.Globals.efl_class_get(obj)), ref slice, ref remaining);
374 private static efl_io_writer_write_delegate efl_io_writer_write_static_delegate;