You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
8.7 KiB
276 lines
8.7 KiB
/* |
|
* 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; |
|
|
|
|
|
namespace Eina |
|
{ |
|
|
|
// TODO: move all native functions to a "NativeMethods" class |
|
[EditorBrowsable(EditorBrowsableState.Never)] |
|
internal static partial class NativeMethods |
|
{ |
|
[DllImport(efl.Libs.Eina)] internal static extern IntPtr |
|
eina_stringshare_add(IntPtr str); |
|
[DllImport(efl.Libs.Eina)] internal static extern System.IntPtr |
|
eina_stringshare_add_length(IntPtr str, UInt32 slen); |
|
[DllImport(efl.Libs.Eina)] internal static extern void |
|
eina_stringshare_del(IntPtr str); |
|
[DllImport(efl.Libs.CustomExports)] internal static extern void |
|
efl_mono_native_stringshare_del_ref(IntPtr str); |
|
[DllImport(efl.Libs.CustomExports)] internal static extern IntPtr |
|
efl_mono_native_stringshare_del_addr_get(); |
|
} |
|
|
|
/// <summary> |
|
/// Placeholder type to interact with the native type Eina_Stringshare, mainly for eina containers. |
|
/// |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <remarks> |
|
/// Using System.String and merely converting this type to it (by cast or implicitly) |
|
/// is recommended for simplicity and ease of use. |
|
/// |
|
/// This type is just a System.String wrapper that works as a placeholder for |
|
/// instrumentalizing proper interaction with native EFL API that demands |
|
/// strings to be stringshares. |
|
/// |
|
/// Both C strings and eina stringshares are bound as regular strings in EFL#, |
|
/// as working directly with these types would demand unnecessary hassle from |
|
/// the user viewpoint. |
|
/// But for eina containers this distinction is important, and since C# generics |
|
/// do not provide a convenient way of dealing with the same type requiring |
|
/// a different management based on some other condition (at least not without |
|
/// compromising the usability for other types), we use this string wrapper |
|
/// in order to signal this distinction. |
|
/// |
|
/// Implements equality/inequality methods for easier comparison with strings and |
|
/// other Stringshare objects. For more specific operations convert to a string. |
|
/// </remarks> |
|
public class Stringshare : IEquatable<Stringshare>, IEquatable<string> |
|
{ |
|
/// <summary> |
|
/// Main constructor. Wrap the given string. |
|
/// Have private acess to avoid wrapping a null reference, |
|
/// use conversion or the factory method to create a new instance. |
|
/// <para>Since EFL 1.23.</para> |
|
/// <see cref="Create(string)"/> |
|
/// <see cref="implicit operator Stringshare(string)"/> |
|
/// </summary> |
|
/// <param name="s">The string to be wrapped.</param> |
|
private Stringshare(string s) |
|
{ |
|
Str = s; |
|
} |
|
|
|
/// <summary> |
|
/// Auto-implemented property that holds the wrapped string value. |
|
/// </summary> |
|
public string Str { get; private set; } |
|
|
|
/// <summary> |
|
/// Factory method to instantiate a new object. |
|
/// Get a wrappper for the given string or a null reference if the given |
|
/// string reference is also null. |
|
/// <para>Since EFL 1.23.</para> |
|
/// <seealso cref="implicit operator Stringshare(string)"/> |
|
/// </summary> |
|
/// <param name="s">The string to be wrapped.</param> |
|
/// <returns> |
|
/// A new instance wrapping the given string, or a null reference if |
|
/// the given string reference is also null. |
|
/// </returns> |
|
public static Stringshare Create(string s) |
|
{ |
|
if (s == null) |
|
{ |
|
return null; |
|
} |
|
|
|
return new Stringshare(s); |
|
} |
|
|
|
/// <summary> |
|
/// Implicit conversion to string. |
|
/// </summary> |
|
public static implicit operator string(Stringshare ss) |
|
{ |
|
if (ReferenceEquals(null, ss)) |
|
{ |
|
return null; |
|
} |
|
|
|
return ss.Str; |
|
} |
|
|
|
/// <summary> |
|
/// Implicit conversion from string to Stringshare. |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <remarks> |
|
/// Note that this method can be used to create an instance of this class, |
|
/// either via an explicit cast or an implicit conversion. |
|
/// <seealso cref="Create(string)"/> |
|
/// </remarks> |
|
public static implicit operator Stringshare(string s) |
|
{ |
|
if (ReferenceEquals(null, s)) |
|
{ |
|
return null; |
|
} |
|
|
|
return new Stringshare(s); |
|
} |
|
|
|
/// <summary> |
|
/// Conversion from string to Stringshare. |
|
/// <para>Since EFL 1.24.</para> |
|
/// </summary> |
|
/// <remarks> |
|
/// Note that this method can be used to create an instance of this class, |
|
/// either via an explicit cast or an implicit conversion. |
|
/// <seealso cref="Create(string)"/> |
|
/// </remarks> |
|
public static Stringshare FromString(string s) => s; |
|
|
|
/// <summary> |
|
/// Check two Stringshare objects for equality. |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <returns> |
|
/// True if both wrapped strings have the same content or if both |
|
/// references are null, false otherwise. |
|
/// </returns> |
|
public static bool operator==(Stringshare ss1, Stringshare ss2) |
|
{ |
|
return ((string)ss1) == ((string)ss2); |
|
} |
|
|
|
|
|
/// <summary> |
|
/// Check two Stringshare objects for inequality. |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <returns> |
|
/// True if the wrapped strings have different content or if one reference is null |
|
/// and the other is not, false otherwise. |
|
/// </returns> |
|
public static bool operator!=(Stringshare ss1, Stringshare ss2) |
|
{ |
|
return !(ss1 == ss2); |
|
} |
|
|
|
/// <summary> |
|
/// Returns the wrapped string. |
|
/// <para>Since EFL 1.23.</para> |
|
/// <seealso cref="Str"/> |
|
/// <seealso cref="Get()"/> |
|
/// </summary> |
|
/// <returns>The wrapped string. Same as the property Str.</returns> |
|
public override string ToString() |
|
{ |
|
return Str; |
|
} |
|
|
|
/// <summary> |
|
/// Override of GetHashCode for consistency with user-defined equality methods. |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <returns> |
|
/// The wrapped string hash code. |
|
/// </returns> |
|
public override int GetHashCode() |
|
{ |
|
return Str.GetHashCode(StringComparison.Ordinal); |
|
} |
|
|
|
/// <summary> |
|
/// Check the given object for equality. |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <param name="other">The string to be compare to.</param> |
|
/// <returns> |
|
/// True if the given object is the same object or if it is another Stringshare object |
|
/// and both wrapped strings are equal or if it is a string object and its content |
|
/// is the same of the wrapped string. |
|
/// In any other case it returns false. |
|
/// </returns> |
|
public override bool Equals(object other) |
|
{ |
|
if (ReferenceEquals(null, other)) |
|
{ |
|
return false; |
|
} |
|
|
|
if (ReferenceEquals(this, other)) |
|
{ |
|
return true; |
|
} |
|
|
|
if (other.GetType() == typeof(string)) |
|
{ |
|
return this.Str == (string)other; |
|
} |
|
|
|
return other.GetType() == typeof(Stringshare) && this == ((Stringshare)other); |
|
} |
|
|
|
/// <summary> |
|
/// Check the given Stringshare for equality. |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <param name="other">The string share to compare to.</param> |
|
/// <returns> |
|
/// True if the given Stringshare object is not null and its wrapped string |
|
/// have the same content of this.Str, false otherwise. |
|
/// </returns> |
|
public bool Equals(Stringshare other) |
|
{ |
|
return this == other; |
|
} |
|
|
|
/// <summary> |
|
/// Check the given Stringshare for equality. |
|
/// <para>Since EFL 1.23.</para> |
|
/// </summary> |
|
/// <param name="other">The string to compare to.</param> |
|
/// <returns> |
|
/// True if the given string is not null and the wrapped string have the same |
|
/// content of the given string, false otherwise. |
|
/// </returns> |
|
public bool Equals(string other) |
|
{ |
|
return this.Str == other; |
|
} |
|
|
|
/// <summary> |
|
/// Get the wrapped string. |
|
/// <para>Since EFL 1.23.</para> |
|
/// <seealso cref="Str"/> |
|
/// <seealso cref="ToString()"/> |
|
/// </summary> |
|
/// <returns>The wrapped string. Same as the property Str.</returns> |
|
public string Get() |
|
{ |
|
return Str; |
|
} |
|
} |
|
|
|
}
|
|
|