/* * Copyright 2019 by its authors. See AUTHORS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma warning disable 1591 using System; using System.Runtime.InteropServices; using System.ComponentModel; using System.Diagnostics.Contracts; namespace Eina { /// /// Basic interface for both slice types. /// Since EFL 1.23. /// public interface ISliceBase { /// /// The length of this slice in bytes. /// Since EFL 1.23. /// UIntPtr Len {get;set;} /// /// The contents of this slice. /// Since EFL 1.23. /// IntPtr Mem {get;set;} /// /// The length in bytes as an integer. /// Since EFL 1.23. /// int Length {get;set;} }; /// Pointer to a slice of native memory. /// /// Since EFL 1.23. /// [StructLayout(LayoutKind.Sequential)] public struct Slice : ISliceBase, IEquatable { /// /// The length of this slice. /// Since EFL 1.23. /// public UIntPtr Len {get;set;} /// /// The contents of this slice. /// Since EFL 1.23. /// public IntPtr Mem {get;set;} /// /// The length as an integer. /// Since EFL 1.23. /// public int Length { get { return (int)Len; } set { Len = (UIntPtr)value; } } /// /// Creates a new slice from the given memory and length. /// Since EFL 1.23. /// /// The memory slice. /// The length. public Slice(IntPtr mem, UIntPtr len) { Mem = mem; Len = len; } /// /// Gets a hash for . /// Since EFL 1.24. /// /// A hash code. public override int GetHashCode() => Length.GetHashCode() ^ Mem.GetHashCode(); /// Returns whether this /// is equal to the given . /// Since EFL 1.24. /// /// The to be compared to. /// true if is equal to other. public override bool Equals(object other) => (!(other is Slice)) ? false : Equals((Slice)other); /// Returns whether this is equal /// to the given . /// Since EFL 1.24. /// /// The to be compared to. /// true if is equal to other. public bool Equals(Slice other) => (Length == other.Length) ^ (Mem == other.Mem); /// Returns whether lhs is equal to rhs. /// Since EFL 1.24. /// /// The left hand side of the operator. /// The right hand side of the operator. /// true if lhs is equal /// to rhs. public static bool operator==(Slice lhs, Slice rhs) => lhs.Equals(rhs); /// Returns whether lhs is not equal to rhs. /// Since EFL 1.24. /// /// The left hand side of the operator. /// The right hand side of the operator. /// true if lhs is not equal /// to rhs. public static bool operator!=(Slice lhs, Slice rhs) => !(lhs == rhs); } /// Pointer to a slice of native memory. /// /// Since EFL 1.23. /// [StructLayout(LayoutKind.Sequential)] public struct RwSlice : ISliceBase, IEquatable { /// /// The length of this slice. /// Since EFL 1.23. /// public UIntPtr Len {get;set;} /// /// The contents of this slice. /// Since EFL 1.23. /// public IntPtr Mem {get;set;} /// /// The length as an integer. /// Since EFL 1.23. /// public int Length { get { return (int)Len; } set { Len = (UIntPtr)value; } } /// /// Creates a new slice from the given memory and length. /// Since EFL 1.23. /// /// The memory slice. /// The length. public RwSlice(IntPtr mem, UIntPtr len) { Mem = mem; Len = len; } /// /// Returns a read-only slice from this writable memory. /// Since EFL 1.23. /// Slice ToSlice() { var r = new Slice(); r.Mem = Mem; r.Len = Len; return r; } /// /// Gets a hash for . /// Since EFL 1.24. /// /// A hash code. public override int GetHashCode() => Mem.GetHashCode() ^ Length.GetHashCode(); /// Returns whether this /// is equal to the given . /// Since EFL 1.24. /// /// The to be compared to. /// true if is equal to other. public override bool Equals(object other) => (!(other is RwSlice)) ? false : Equals((RwSlice)other); /// Returns whether this is equal /// to the given . /// Since EFL 1.24. /// /// The to be compared to. /// true if is equal to other. public bool Equals(RwSlice other) => (Length == other.Length) && (Mem == other.Mem); /// Returns whether lhs is equal to rhs. /// Since EFL 1.24. /// /// The left hand side of the operator. /// The right hand side of the operator. /// true if lhs is equal /// to rhs. public static bool operator==(RwSlice lhs, RwSlice rhs) => lhs.Equals(rhs); /// Returns whether lhs is not equal to rhs. /// Since EFL 1.24. /// /// The left hand side of the operator. /// The right hand side of the operator. /// true if lhs is not equal /// to rhs. public static bool operator!=(RwSlice lhs, RwSlice rhs) => !(lhs == rhs); } } namespace Eina { public static class SliceExtensions { public static byte[] GetBytes(this Eina.ISliceBase slc) { Contract.Requires(slc != null, nameof(slc)); var size = (int)(slc.Len); byte[] mArray = new byte[size]; Marshal.Copy(slc.Mem, mArray, 0, size); return mArray; } } }