// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
namespace WixToolset.Data.WindowsInstaller.Rows
{
using System;
using System.Diagnostics.CodeAnalysis;
///
/// Specialization of a row for the WixComplexReference table.
///
public sealed class WixComplexReferenceRow : Row, IComparable
{
///
/// Creates a WixComplexReferenceRow row that belongs to a table.
///
/// Original source lines for this row.
/// Table this row belongs to and should get its column definitions from.
public WixComplexReferenceRow(SourceLineNumber sourceLineNumbers, Table table)
: base(sourceLineNumbers, table)
{
}
///
/// Gets the parent type of the complex reference.
///
/// Parent type of the complex reference.
public ComplexReferenceParentType ParentType
{
get { return (ComplexReferenceParentType)Enum.ToObject(typeof(ComplexReferenceParentType), (int)this.Fields[1].Data); }
set { this.Fields[1].Data = (int)value; }
}
///
/// Gets or sets the parent identifier of the complex reference.
///
/// Parent identifier of the complex reference.
public string ParentId
{
get { return (string)this.Fields[0].Data; }
set { this.Fields[0].Data = value; }
}
///
/// Gets the parent language of the complex reference.
///
/// Parent language of the complex reference.
public string ParentLanguage
{
get { return (string)this.Fields[2].Data; }
set { this.Fields[2].Data = value; }
}
///
/// Gets the child type of the complex reference.
///
/// Child type of the complex reference.
public ComplexReferenceChildType ChildType
{
get { return (ComplexReferenceChildType)Enum.ToObject(typeof(ComplexReferenceChildType), (int)this.Fields[4].Data); }
set { this.Fields[4].Data = (int)value; }
}
///
/// Gets the child identifier of the complex reference.
///
/// Child identifier of the complex reference.
public string ChildId
{
get { return (string)this.Fields[3].Data; }
set { this.Fields[3].Data = value; }
}
///
/// Gets if this is the primary complex reference.
///
/// true if primary complex reference.
public bool IsPrimary
{
get
{
return (0x1 == ((int)this.Fields[5].Data & 0x1));
}
set
{
if (null == this.Fields[5].Data)
{
this.Fields[5].Data = 0;
}
if (value)
{
this.Fields[5].Data = (int)this.Fields[5].Data | 0x1;
}
else
{
this.Fields[5].Data = (int)this.Fields[5].Data & ~0x1;
}
}
}
///
/// Determines if two complex references are equivalent.
///
/// Complex reference to compare.
/// True if complex references are equivalent.
public override bool Equals(object obj)
{
return 0 == this.CompareTo(obj);
}
///
/// Gets the hash code for the complex reference.
///
/// Hash code for the complex reference.
public override int GetHashCode()
{
return this.ChildType.GetHashCode() ^ this.ChildId.GetHashCode() ^ this.ParentType.GetHashCode() ^ this.ParentLanguage.GetHashCode() ^ this.ParentId.GetHashCode() ^ this.IsPrimary.GetHashCode();
}
///
/// Compares two complex references.
///
/// Complex reference to compare to.
/// Zero if the objects are equivalent, negative number if the provided object is less, positive if greater.
public int CompareTo(object obj)
{
int comparison = this.CompareToWithoutConsideringPrimary(obj);
if (0 == comparison)
{
comparison = ((WixComplexReferenceRow)obj).IsPrimary.CompareTo(this.IsPrimary); // Note: the order of these is purposely switched to ensure that "Yes" is lower than "No" and "NotSet"
}
return comparison;
}
///
/// Compares two complex references without considering the primary bit.
///
/// Complex reference to compare to.
/// Zero if the objects are equivalent, negative number if the provided object is less, positive if greater.
[SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "System.ArgumentException.#ctor(System.String,System.String)")]
public int CompareToWithoutConsideringPrimary(object obj)
{
var other = obj as WixComplexReferenceRow ?? throw new ArgumentNullException(nameof(obj));
int comparison = this.ChildType - other.ChildType;
if (0 == comparison)
{
comparison = String.Compare(this.ChildId, other.ChildId, StringComparison.Ordinal);
if (0 == comparison)
{
comparison = this.ParentType - other.ParentType;
if (0 == comparison)
{
string thisParentLanguage = null == this.ParentLanguage ? String.Empty : this.ParentLanguage;
string otherParentLanguage = null == other.ParentLanguage ? String.Empty : other.ParentLanguage;
comparison = String.Compare(thisParentLanguage, otherParentLanguage, StringComparison.Ordinal);
if (0 == comparison)
{
comparison = String.Compare(this.ParentId, other.ParentId, StringComparison.Ordinal);
}
}
}
}
return comparison;
}
///
/// Creates a shallow copy of the ComplexReference.
///
/// A shallow copy of the ComplexReference.
public WixComplexReferenceRow Clone()
{
WixComplexReferenceRow wixComplexReferenceRow = new WixComplexReferenceRow(this.SourceLineNumbers, this.Table);
wixComplexReferenceRow.ParentType = this.ParentType;
wixComplexReferenceRow.ParentId = this.ParentId;
wixComplexReferenceRow.ParentLanguage = this.ParentLanguage;
wixComplexReferenceRow.ChildType = this.ChildType;
wixComplexReferenceRow.ChildId = this.ChildId;
wixComplexReferenceRow.IsPrimary = this.IsPrimary;
return wixComplexReferenceRow;
}
///
/// Changes all of the parent references to point to the passed in parent reference.
///
/// New parent complex reference.
public void Reparent(WixComplexReferenceRow parent)
{
this.ParentId = parent.ParentId;
this.ParentLanguage = parent.ParentLanguage;
this.ParentType = parent.ParentType;
if (!this.IsPrimary)
{
this.IsPrimary = parent.IsPrimary;
}
}
}
}