summaryrefslogtreecommitdiff
path: root/src/bindings/mono/eina_mono/eina_stringshare.cs
blob: 5b97e731e4255898d13b1f36af2025cba0a10670 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#pragma warning disable 1591

using System;
using System.Runtime.InteropServices;


namespace Eina
{

// TODO: move all native functions to a "NativeMethods" class
public static partial class NativeMethods
{
    [DllImport(efl.Libs.Eina)] public static extern IntPtr
        eina_stringshare_add(IntPtr str);
    [DllImport(efl.Libs.Eina)] public static extern System.IntPtr
        eina_stringshare_add_length(IntPtr str, UInt32 slen);
    [DllImport(efl.Libs.Eina)] public static extern void
        eina_stringshare_del(IntPtr str);
    [DllImport(efl.Libs.CustomExports)] public static extern void
        efl_mono_native_stringshare_del_ref(IntPtr str);
    [DllImport(efl.Libs.CustomExports)] public 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.
/// </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 convertion or the factory method to create a new instance.
    /// <see cref="Create(string)"/>
    /// <see cref="implicit operator Stringshare(string)"/>
    /// </summary>
    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.
    /// <seealso cref="implicit operator Stringshare(string)"/>
    /// </summary>
    /// <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 convertion to string.
    /// </summary>
    public static implicit operator string(Stringshare ss)
    {
        if (ReferenceEquals(null, ss))
        {
            return null;
        }

        return ss.Str;
    }

    /// <summary>
    /// Implicit convertion from string to Stringshare.
    /// </summary>
    /// <remarks>
    /// Note that this method can be used to create an instance of this class,
    /// either via an explicit cast or an implicit convertion.
    /// <seealso cref="Create(string)"/>
    /// </remarks>
    public static implicit operator Stringshare(string s)
    {
        if (ReferenceEquals(null, s))
        {
            return null;
        }

        return new Stringshare(s);
    }

    /// <summary>
    /// Check two Stringshare objects for equality.
    /// </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.
    /// </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.
    /// <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.
    /// </summary>
    /// <returns>
    /// The wrapped string hash code.
    /// </returns>
    public override int GetHashCode()
    {
        return Str.GetHashCode();
    }

    /// <summary>
    /// Check the given object for equality.
    /// </summary>
    /// <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.
    /// </summary>
    /// <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.
    /// </summary>
    /// <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.
    /// <seealso cref="Str"/>
    /// <seealso cref="ToString()"/>
    /// </summary>
    /// <returns>The wrapped string. Same as the property Str.</returns>
    public string Get()
    {
        return Str;
    }
}

}