Exemple #1
0
        /// <summary>
        /// Reads an existing BAML using BamlReaderWrapper. After reading each node, it calls the given
        /// callback function, providing the function with the data in the node just read.
        /// </summary>
        /// <param name="bamlIn">Path of the BAML to read</param>
        /// <param name="callback">Function to be called after reading each node</param>
        public static void ReadBaml(String bamlIn, BamlNodeCallback callback)
        {
            // Since we want to reuse the EditBaml function, we need to have an output BAML
            // file. So we create a temporary file, use the EditBaml function, and then
            // discard the temporary file.
            String tempFile = Path.GetTempFileName();

            EditBaml(bamlIn, tempFile, callback);
            File.Delete(tempFile);
        }
Exemple #2
0
        /// <summary>
        /// Reads an existing BAML using BamlReaderWrapper, allows editing of the contents
        /// and writes the (possibly modified) contents to a new BAML using BamlWriterWrapper.
        ///
        /// After each node is read from the BamlReaderWrapper, it calls the given callback function,
        /// passing the data in the node just read. The callback function can then modify the
        /// data. The callback function is also passed the BamlWriterWrapper, so that it can add
        /// nodes, if it wants.
        ///
        /// The callback function is supposed to return a BamlNodeAction, specifiying
        /// whether the current BAML node should be written to the output BAML file.
        /// By returning BamlNodeAction.Skip, the callback function can specify to delete nodes.
        ///
        /// If the callback function returns BamlNodeAction.Continue, then the (possibly modified)
        /// contents will be written into the new BAML.
        /// </summary>
        /// <param name="bamlIn">Path of the Original BAML</param>
        /// <param name="bamlOut">Path of the BAML to be written</param>
        /// <param name="callback">EditBamlNode callback. Can be null.</param>
        public static void EditBaml(string bamlIn, string bamlOut, BamlNodeCallback callback)
        {
            Stream bamlInStream  = File.OpenRead(bamlIn);
            Stream bamlOutStream = File.OpenWrite(bamlOut);

            try
            {
                EditBaml(bamlInStream, bamlOutStream, callback);
            }
            finally
            {
                bamlInStream.Close();
                bamlOutStream.Close();
            }
        }
Exemple #3
0
        /// <summary>
        /// Reads an existing BAML using BamlReaderWrapper, allows editing of the contents
        /// and writes the (possibly modified) contents to a new BAML using BamlWriterWrapper.
        ///
        /// After each node is read from the BamlReaderWrapper, it calls the given callback function,
        /// passing the data in the node just read. The callback function can then modify the
        /// data. The callback function is also passed the BamlWriterWrapper, so that it can add
        /// nodes, if it wants.
        ///
        /// The callback function is supposed to return a BamlNodeAction, specifiying
        /// whether the current BAML node should be written to the output BAML file.
        /// By returning BamlNodeAction.Skip, the callback function can specify to delete nodes.
        ///
        /// If the callback function returns BamlNodeAction.Continue, then the (possibly modified)
        /// contents will be written into the new BAML.
        /// </summary>
        /// <param name="bamlIn">Path of the Original BAML</param>
        /// <param name="bamlOut">Path of the BAML to be written</param>
        /// <param name="callback">EditBamlNode callback. Can be null.</param>
        public static void EditBaml(Stream bamlIn, Stream bamlOut, BamlNodeCallback callback)
        {
            BamlReaderWrapper reader = new BamlReaderWrapper(bamlIn);
            BamlWriterWrapper writer = new BamlWriterWrapper(bamlOut);

            // Stack for verifying matching BAML nodes
            Stack        matchingStack = new Stack();
            BamlNodeData expectedData;

            // Default action, in case there is no callback specified.
            BamlNodeAction action = BamlNodeAction.Continue;

            // Go through the input BAML, reading different types of records and
            // writing them to the output BAML
            while (reader.Read())
            {
                // Copy the significant fields from BamlReaderWrapper to BamlNodeData
                // This nodeData can be then passed to a BamlNodeCallback delegate
                BamlNodeData nodeData = new BamlNodeData();
                PopulateBamlNodeData(reader, nodeData);

                // Make another copy for pushing to stack, in case of those nodes
                // which we are checking for node matching
                // We cannot work with the previous copy, since that may be modified by the
                // callback.
                BamlNodeData stackData = new BamlNodeData();
                PopulateBamlNodeData(reader, stackData);

                switch (reader.NodeType)
                {
                case "StartDocument":
                    matchingStack.Push(stackData);
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteStartDocument();
                    }
                    break;

                case "EndDocument":
                    // Test for matching BAML nodes.
                    // Try to match the data with StartDocument's data
                    if (matchingStack.Count <= 0)
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    expectedData = matchingStack.Pop() as BamlNodeData;
                    if (expectedData.NodeType != "StartDocument")
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    CompareBamlNodes(stackData, expectedData);

                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteEndDocument();
                    }
                    break;

                case "StartElement":
                    matchingStack.Push(stackData);
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteStartElement(nodeData.AssemblyName, nodeData.Name, nodeData.IsInjected, nodeData.CreateUsingTypeConverter);
                    }
                    break;

                case "EndElement":
                    // Test for matching BAML nodes.
                    // Try to match the data with StartElement's data
                    if (matchingStack.Count <= 0)
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    expectedData = matchingStack.Pop() as BamlNodeData;
                    if (expectedData.NodeType != "StartElement")
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    CompareBamlNodes(stackData, expectedData);

                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteEndElement();
                    }
                    break;

                case "StartConstructor":
                    matchingStack.Push(stackData);
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteStartConstructor();
                    }
                    break;

                case "EndConstructor":
                    // Test for matching BAML nodes.
                    // Try to match the data with StartConstructor's data
                    if (matchingStack.Count <= 0)
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    expectedData = matchingStack.Pop() as BamlNodeData;
                    if (expectedData.NodeType != "StartConstructor")
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    CompareBamlNodes(stackData, expectedData);

                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteEndConstructor();
                    }
                    break;

                case "StartComplexProperty":
                    matchingStack.Push(stackData);
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteStartComplexProperty(nodeData.AssemblyName, nodeData.Name.Substring(0, nodeData.Name.LastIndexOf('.')), nodeData.LocalName);
                    }
                    break;

                case "EndComplexProperty":
                    // Test for matching BAML nodes.
                    // Try to match the data with StartComplexProperty's data
                    if (matchingStack.Count <= 0)
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    expectedData = matchingStack.Pop() as BamlNodeData;
                    if (expectedData.NodeType != "StartComplexProperty")
                    {
                        throw new Exception("Unmatched BAML nodes found");
                    }
                    CompareBamlNodes(stackData, expectedData);

                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteEndComplexProperty();
                    }
                    break;

                case "LiteralContent":
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteLiteralContent(nodeData.Value);
                    }
                    break;

                case "Text":
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteText(nodeData.Value, nodeData.TypeConverterAssemblyName, nodeData.TypeConverterName);
                    }
                    break;

                case "RoutedEvent":
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteRoutedEvent(nodeData.AssemblyName, nodeData.Name.Substring(0, nodeData.Name.LastIndexOf('.')), nodeData.LocalName, nodeData.Value);
                    }
                    break;

                case "Event":
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WriteEvent(nodeData.LocalName, nodeData.Value);
                    }
                    break;

                case "IncludeReference":
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    break;

                case "PIMapping":
                    if (callback != null)
                    {
                        action = callback(nodeData, writer);
                    }
                    if (BamlNodeAction.Continue == action)
                    {
                        writer.WritePIMapping(nodeData.XmlNamespace, nodeData.ClrNamespace, nodeData.AssemblyName);
                    }
                    break;

                default:
                    throw new Exception("Unexpected NodeType read from BamlReaderWrapper");
                }

                // Property nodes are not provided by BamlReaderWrapper when Read() is called
                // We need to go through them separately.
                if (reader.HasProperties)
                {
                    reader.MoveToFirstProperty();
                    do
                    {
                        // This has to be present in this loop, because reader values
                        // keep changing as we move thru the properties
                        PopulateBamlNodeData(reader, nodeData);

                        if (reader.NodeType == "Property")
                        {
                            if (callback != null)
                            {
                                action = callback(nodeData, writer);
                            }
                            if (BamlNodeAction.Continue == action)
                            {
                                writer.WriteProperty(nodeData.AssemblyName, nodeData.Name.Substring(0, nodeData.Name.LastIndexOf('.')), nodeData.LocalName, nodeData.Value, nodeData.AttributeUsage);
                            }
                        }
                        else if (reader.NodeType == "ContentProperty")
                        {
                            if (callback != null)
                            {
                                action = callback(nodeData, writer);
                            }
                            if (BamlNodeAction.Continue == action)
                            {
                                writer.WriteContentProperty(nodeData.AssemblyName, nodeData.Name.Substring(0, nodeData.Name.LastIndexOf('.')), nodeData.LocalName);
                            }
                        }
                        else if (reader.NodeType == "DefAttribute")
                        {
                            if (callback != null)
                            {
                                action = callback(nodeData, writer);
                            }
                            if (BamlNodeAction.Continue == action)
                            {
                                writer.WriteDefAttribute(nodeData.Name, nodeData.Value);
                            }
                        }
                        else if (reader.NodeType == "XmlnsProperty")
                        {
                            if (callback != null)
                            {
                                action = callback(nodeData, writer);
                            }
                            if (BamlNodeAction.Continue == action)
                            {
                                writer.WriteXmlnsProperty(nodeData.LocalName, nodeData.Value);
                            }
                        }
                        else if (reader.NodeType == "ConnectionId")
                        {
                            if (callback != null)
                            {
                                action = callback(nodeData, writer);
                            }
                            if (BamlNodeAction.Continue == action)
                            {
                                writer.WriteConnectionId(Int32.Parse(nodeData.Value));
                            }
                        }
                        else
                        {
                            throw new Exception("Unexpected NodeType read from BamlReaderWrapper while trying to read properties on an element");
                        }
                    } while (reader.MoveToNextProperty());
                }
            }

            // Check that matching stack is empty
            if (matchingStack.Count != 0)
            {
                throw new Exception("Unmatched BAML nodes found");
            }
        }