From 49f1209035aac1fcfad5dbbe25f7b2306d3be86c Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Thu, 7 Dec 2017 14:19:05 -0800 Subject: Support MSI backends creating custom tables and remove WixToolset.Data.WindowsInstaller --- .../Rows/WixActionRowCollection.cs | 328 +++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 src/WixToolset.Core.WindowsInstaller/Rows/WixActionRowCollection.cs (limited to 'src/WixToolset.Core.WindowsInstaller/Rows/WixActionRowCollection.cs') diff --git a/src/WixToolset.Core.WindowsInstaller/Rows/WixActionRowCollection.cs b/src/WixToolset.Core.WindowsInstaller/Rows/WixActionRowCollection.cs new file mode 100644 index 00000000..d72198ee --- /dev/null +++ b/src/WixToolset.Core.WindowsInstaller/Rows/WixActionRowCollection.cs @@ -0,0 +1,328 @@ +// 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.Core.WindowsInstaller.Rows +{ + using System; + using System.Collections; + using System.Diagnostics; + using System.Globalization; + using System.Xml; + using WixToolset.Data.Tuples; + using WixToolset.Data.WindowsInstaller.Rows; + + /// + /// A collection of action rows sorted by their sequence table and action name. + /// + internal sealed class WixActionRowCollection : ICollection + { + private SortedList collection; + + /// + /// Creates a new action table object. + /// + public WixActionRowCollection() + { + this.collection = new SortedList(); + } + + /// + /// Gets the number of items in the collection. + /// + /// Number of items in collection. + public int Count + { + get { return this.collection.Count; } + } + + /// + /// Gets if the collection has been synchronized. + /// + /// True if the collection has been synchronized. + public bool IsSynchronized + { + get { return this.collection.IsSynchronized; } + } + + /// + /// Gets the object used to synchronize the collection. + /// + /// Oject used the synchronize the collection. + public object SyncRoot + { + get { return this; } + } + + /// + /// Get an ActionRow by its sequence table and action name. + /// + /// The sequence table of the ActionRow. + /// The action name of the ActionRow. + public WixActionRow this[SequenceTable sequenceTable, string action] + { + get { return (WixActionRow)this.collection[GetKey(sequenceTable, action)]; } + } + + /// + /// Add an ActionRow to the collection. + /// + /// The ActionRow to add. + /// true to overwrite an existing ActionRow; false otherwise. + public void Add(WixActionRow actionRow, bool overwrite) + { + string key = GetKey(actionRow.SequenceTable, actionRow.Action); + + if (overwrite) + { + this.collection[key] = actionRow; + } + else + { + this.collection.Add(key, actionRow); + } + } + + /// + /// Add an ActionRow to the collection. + /// + /// The ActionRow to add. + public void Add(WixActionRow actionRow) + { + this.Add(actionRow, false); + } + + /// + /// Determines if the collection contains an ActionRow with a specific sequence table and name. + /// + /// The sequence table of the ActionRow. + /// The action name of the ActionRow. + /// true if the ActionRow was found; false otherwise. + public bool Contains(SequenceTable sequenceTable, string action) + { + return this.collection.Contains(GetKey(sequenceTable, action)); + } + + /// + /// Copies the collection into an array. + /// + /// Array to copy the collection into. + /// Index to start copying from. + public void CopyTo(System.Array array, int index) + { + this.collection.Values.CopyTo(array, index); + } + + /// + /// Gets the enumerator for the collection. + /// + /// The enumerator for the collection. + public IEnumerator GetEnumerator() + { + return this.collection.Values.GetEnumerator(); + } + + /// + /// Remove an ActionRow from the collection. + /// + /// The sequence table of the ActionRow. + /// The action name of the ActionRow. + public void Remove(SequenceTable sequenceTable, string action) + { + this.collection.Remove(GetKey(sequenceTable, action)); + } + + /// + /// Load an action table from an XmlReader. + /// + /// Reader to get data from. + /// The ActionRowCollection represented by the xml. + internal static WixActionRowCollection Load(XmlReader reader) + { + reader.MoveToContent(); + + return Parse(reader); + } + + /// + /// Creates a new action table object and populates it from an Xml reader. + /// + /// Reader to get data from. + /// The parsed ActionTable. + private static WixActionRowCollection Parse(XmlReader reader) + { + if (!reader.LocalName.Equals("actions")) + { + throw new XmlException(); + } + + WixActionRowCollection actionRows = new WixActionRowCollection(); + bool empty = reader.IsEmptyElement; + + while (reader.MoveToNextAttribute()) + { + } + + if (!empty) + { + bool done = false; + + // loop through all the fields in a row + while (!done && reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.Element: + switch (reader.LocalName) + { + case "action": + WixActionRow[] parsedActionRows = ParseActions(reader); + + foreach (WixActionRow actionRow in parsedActionRows) + { + actionRows.Add(actionRow); + } + break; + default: + throw new XmlException(); + } + break; + case XmlNodeType.EndElement: + done = true; + break; + } + } + + if (!done) + { + throw new XmlException(); + } + } + + return actionRows; + } + + /// + /// Get the key for storing an ActionRow. + /// + /// The sequence table of the ActionRow. + /// The action name of the ActionRow. + /// The string key. + private static string GetKey(SequenceTable sequenceTable, string action) + { + return GetKey(sequenceTable.ToString(), action); + } + + /// + /// Get the key for storing an ActionRow. + /// + /// The sequence table of the ActionRow. + /// The action name of the ActionRow. + /// The string key. + private static string GetKey(string sequenceTable, string action) + { + return String.Concat(sequenceTable, '/', action); + } + + /// + /// Parses ActionRows from the Xml reader. + /// + /// Xml reader that contains serialized ActionRows. + /// The parsed ActionRows. + internal static WixActionRow[] ParseActions(XmlReader reader) + { + Debug.Assert("action" == reader.LocalName); + + string id = null; + string condition = null; + bool empty = reader.IsEmptyElement; + int sequence = int.MinValue; + int sequenceCount = 0; + SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length]; + + while (reader.MoveToNextAttribute()) + { + switch (reader.Name) + { + case "name": + id = reader.Value; + break; + case "AdminExecuteSequence": + if (reader.Value.Equals("yes")) + { + sequenceTables[sequenceCount] = SequenceTable.AdminExecuteSequence; + ++sequenceCount; + } + break; + case "AdminUISequence": + if (reader.Value.Equals("yes")) + { + sequenceTables[sequenceCount] = SequenceTable.AdminUISequence; + ++sequenceCount; + } + break; + case "AdvtExecuteSequence": + if (reader.Value.Equals("yes")) + { + sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence; + ++sequenceCount; + } + break; + case "condition": + condition = reader.Value; + break; + case "InstallExecuteSequence": + if (reader.Value.Equals("yes")) + { + sequenceTables[sequenceCount] = SequenceTable.InstallExecuteSequence; + ++sequenceCount; + } + break; + case "InstallUISequence": + if (reader.Value.Equals("yes")) + { + sequenceTables[sequenceCount] = SequenceTable.InstallUISequence; + ++sequenceCount; + } + break; + case "sequence": + sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture); + break; + } + } + + if (null == id) + { + throw new XmlException(); + } + + if (int.MinValue == sequence) + { + throw new XmlException(); + } + else if (1 > sequence) + { + throw new XmlException(); + } + + if (0 == sequenceCount) + { + throw new XmlException(); + } + + if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent()) + { + throw new XmlException(); + } + + // create the actions + WixActionRow[] actionRows = new WixActionRow[sequenceCount]; + for (int i = 0; i < sequenceCount; i++) + { + //WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence); + //actionRows[i] = actionRow; + throw new NotImplementedException(); + } + + return actionRows; + } + } +} -- cgit v1.2.3-55-g6feb