// // AnnotationAttribute.cs // // Author: Jeffrey Stedfast // // Copyright (c) 2013-2020 .NET Foundation and Contributors // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // using System; namespace MailKit { /// /// An annotation attribute. /// /// /// An annotation attribute. /// For more information about annotations, see /// rfc5257. /// public class AnnotationAttribute : IEquatable { static readonly char[] Wildcards = { '*', '%' }; /// /// The annotation value. /// /// /// Used to get or set both the private and shared values of an annotation. /// public static readonly AnnotationAttribute Value = new AnnotationAttribute ("value", AnnotationScope.Both); /// /// The shared annotation value. /// /// /// Used to get or set the shared value of an annotation. /// public static readonly AnnotationAttribute SharedValue = new AnnotationAttribute ("value", AnnotationScope.Shared); /// /// The private annotation value. /// /// /// Used to get or set the private value of an annotation. /// public static readonly AnnotationAttribute PrivateValue = new AnnotationAttribute ("value", AnnotationScope.Private); /// /// The size of an annotation value. /// /// /// Used to get the size of the both the private and shared annotation values. /// public static readonly AnnotationAttribute Size = new AnnotationAttribute ("size", AnnotationScope.Both); /// /// The size of a shared annotation value. /// /// /// Used to get the size of a shared annotation value. /// public static readonly AnnotationAttribute SharedSize = new AnnotationAttribute ("size", AnnotationScope.Shared); /// /// The size of a private annotation value. /// /// /// Used to get the size of a private annotation value. /// public static readonly AnnotationAttribute PrivateSize = new AnnotationAttribute ("size", AnnotationScope.Private); AnnotationAttribute (string name, AnnotationScope scope) { switch (scope) { case AnnotationScope.Shared: Specifier = string.Format ("{0}.shared", name); break; case AnnotationScope.Private: Specifier = string.Format ("{0}.priv", name); break; default: Specifier = name; break; } Scope = scope; Name = name; } /// /// Initializes a new instance of the class. /// /// The annotation attribute specifier. /// /// is null. /// /// /// contains illegal characters. /// public AnnotationAttribute (string specifier) { if (specifier == null) throw new ArgumentNullException (nameof (specifier)); if (specifier.Length == 0) throw new ArgumentException ("Annotation attribute specifiers cannot be empty.", nameof (specifier)); // TODO: improve validation if (specifier.IndexOfAny (Wildcards) != -1) throw new ArgumentException ("Annotation attribute specifiers cannot contain '*' or '%'.", nameof (specifier)); Specifier = specifier; if (specifier.EndsWith (".shared", StringComparison.Ordinal)) { Name = specifier.Substring (0, specifier.Length - ".shared".Length); Scope = AnnotationScope.Shared; } else if (specifier.EndsWith (".priv", StringComparison.Ordinal)) { Name = specifier.Substring (0, specifier.Length - ".priv".Length); Scope = AnnotationScope.Private; } else { Scope = AnnotationScope.Both; Name = specifier; } } /// /// Get the name of the annotation attribute. /// /// /// Gets the name of the annotation attribute. /// public string Name { get; private set; } /// /// Get the scope of the annotation attribute. /// /// /// Gets the scope of the annotation attribute. /// public AnnotationScope Scope { get; private set; } /// /// Get the annotation attribute specifier. /// /// /// Gets the annotation attribute specifier. /// public string Specifier { get; private set; } #region IEquatable implementation /// /// Determines whether the specified is equal to the current . /// /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// true if the specified is equal to the current /// ; otherwise, false. public bool Equals (AnnotationAttribute other) { return other?.Specifier == Specifier; } #endregion /// /// Determines whether two annotation attributes are equal. /// /// /// Determines whether two annotation attributes are equal. /// /// true if and are equal; otherwise, false. /// The first annotation attribute to compare. /// The second annotation attribute to compare. public static bool operator == (AnnotationAttribute attr1, AnnotationAttribute attr2) { return attr1?.Specifier == attr2?.Specifier; } /// /// Determines whether two annotation attributes are not equal. /// /// /// Determines whether two annotation attributes are not equal. /// /// true if and are not equal; otherwise, false. /// The first annotation attribute to compare. /// The second annotation attribute to compare. public static bool operator != (AnnotationAttribute attr1, AnnotationAttribute attr2) { return attr1?.Specifier != attr2?.Specifier; } /// /// Determine whether the specified is equal to the current . /// /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// true if the specified is equal to the current /// ; otherwise, false. public override bool Equals (object obj) { return obj is AnnotationAttribute && ((AnnotationAttribute) obj).Specifier == Specifier; } /// /// Serves as a hash function for a object. /// /// /// Serves as a hash function for a object. /// /// A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a hash table. public override int GetHashCode () { return Specifier.GetHashCode (); } /// /// Returns a that represents the current . /// /// /// Returns a that represents the current . /// /// A that represents the current . public override string ToString () { return Specifier; } } }