Пример #1
0
        private void ReadNodeInNodeSection(BinaryReaderEx reader, XbfNodeSection nodeSection, int offset)
        {
            // Save the current position and skip ahead to the new position
            long originalPosition = reader.BaseStream.Position;
            int  newPosition      = _firstNodeSectionPosition + nodeSection.NodeOffset;
            int  newEndPosition   = _firstNodeSectionPosition + nodeSection.PositionalOffset;

            reader.BaseStream.Position = newPosition + offset;

            int objectStackDepthBefore           = _objectStack.Count;
            int objectCollectionStackDepthBefore = _objectCollectionStack.Count;

            // Read the node from the specified position
            ReadNodes(reader, int.MaxValue, false, true);

            if (_objectStack.Count != objectStackDepthBefore)
            {
                throw new InvalidDataException("_objectStack corrupted");
            }
            if (_objectCollectionStack.Count != objectCollectionStackDepthBefore)
            {
                throw new InvalidDataException("_objectCollectionStack corrupted");
            }

            // Return to the original position
            reader.BaseStream.Position = originalPosition;
        }
Пример #2
0
        private void ReadDataTemplate(BinaryReaderEx reader)
        {
            string propertyName = GetPropertyName(reader.ReadUInt16()); // Always "Template"

            XbfNodeSection nodeSection = NodeSectionTable[reader.Read7BitEncodedInt()];

            // List of StaticResources and ThemeResources referenced from inside the DataTemplate
            int staticResourceCount = reader.Read7BitEncodedInt();
            int themeResourceCount  = reader.Read7BitEncodedInt();

            for (int i = 0; i < staticResourceCount; i++)
            {
                string staticResource = StringTable[reader.ReadUInt16()];
            }
            for (int i = 0; i < themeResourceCount; i++)
            {
                string themeResource = StringTable[reader.ReadUInt16()];
            }

            ReadNodeSection(reader, nodeSection);

            // Add the object we found as a property
            var obj = _objectStack.Pop();

            _objectStack.Peek().Properties.Add(new XbfObjectProperty(propertyName, obj));
        }
Пример #3
0
        private void ReadResourceDictionary(BinaryReaderEx reader, XbfNodeSection nodeSection, bool extended)
        {
            // Resources with keys
            int resourcesCount = reader.Read7BitEncodedInt();

            for (int i = 0; i < resourcesCount; i++)
            {
                string resourceKey = StringTable[reader.ReadUInt16()];
                int    position    = reader.Read7BitEncodedInt(); // Secondary node stream offset

                XbfObject obj = ReadObjectInNodeSection(reader, nodeSection, position);
                obj.Key = resourceKey;
                _objectCollectionStack.Peek().Add(obj);
            }

            // A subset of the resource keys from above seem to get repeated here, purpose unknown
            int count = reader.Read7BitEncodedInt();

            for (int i = 0; i < count; i++)
            {
                string resourceKey = StringTable[reader.ReadUInt16()];
            }

            // Styles with TargetType and no key
            int styleCount = reader.Read7BitEncodedInt();

            for (int i = 0; i < styleCount; i++)
            {
                string targetType = StringTable[reader.ReadUInt16()];
                int    position   = reader.Read7BitEncodedInt(); // Secondary node stream offset

                XbfObject obj = ReadObjectInNodeSection(reader, nodeSection, position);
                _objectCollectionStack.Peek().Add(obj);
            }

            if (extended)
            {
                if (reader.Read7BitEncodedInt() != 0) // TODO: purpose unknown
                {
                    throw new InvalidDataException("Unexpected value");
                }
            }

            // A subset of the target types from above seem to get repeated here, purpose unknown
            int count2 = reader.Read7BitEncodedInt();

            for (int i = 0; i < count2; i++)
            {
                string targetType = StringTable[reader.ReadUInt16()];
            }
        }
Пример #4
0
        private void ReadNodeSection(BinaryReaderEx reader, XbfNodeSection nodeSection)
        {
            // Save the current position and skip ahead to the new position
            long originalPosition = reader.BaseStream.Position;
            int  newPosition      = _firstNodeSectionPosition + nodeSection.NodeOffset;
            int  newEndPosition   = _firstNodeSectionPosition + nodeSection.PositionalOffset;

            reader.BaseStream.Position = newPosition;

            // Read the nodes from the specified position
            ReadNodes(reader, newEndPosition);

            // Return to the original position
            reader.BaseStream.Position = originalPosition;
        }
Пример #5
0
        private void ReadNodeSectionReference(BinaryReaderEx reader)
        {
            // The node section we're skipping to
            XbfNodeSection nodeSection = NodeSectionTable[reader.Read7BitEncodedInt()];

            if (reader.ReadUInt16() != 0) // TODO: unknown purpose
            {
                throw new InvalidDataException($"Unexpected value");
            }

            // Get the type of nodes contained in this section
            int type = reader.Read7BitEncodedInt();

            switch (type)
            {
            case 2:     // Style
            case 8:     // 8 seems to be equivalent
                ReadStyle(reader, nodeSection);
                break;

            case 7:     // ResourceDictionary
                ReadResourceDictionary(reader, nodeSection, false);
                break;

            case 371:     // ResourceDictionary
                ReadResourceDictionary(reader, nodeSection, true);
                break;

            case 5:     // Visual states
                SkipVisualStateBytes(reader);
                ReadNodeSection(reader, nodeSection);
                break;

            case 6:     // DeferredElement
                ReadDeferredElement(reader, nodeSection, true);
                break;

            case 746:     // DeferredElement
                ReadDeferredElement(reader, nodeSection, false);
                break;

            default:
                throw new InvalidDataException(string.Format("Unknown node type {0} while parsing referenced code section", type));
            }
        }
Пример #6
0
        private void ReadDeferredElement(BinaryReaderEx reader, XbfNodeSection nodeSection, bool extended)
        {
            string deferredElementName = StringTable[reader.ReadUInt16()];

            if (extended)
            {
                // The following properties can be ignored as they will appear in the secondary node section again
                int count = reader.Read7BitEncodedInt();
                for (int i = 0; i < count; i++)
                {
                    string propertyName  = GetPropertyName(reader.ReadUInt16());
                    object propertyValue = GetPropertyValue(reader);
                }
            }

            ReadNodeSection(reader, nodeSection);
            XbfObject childObj        = _objectStack.Pop();
            XbfObject deferredElement = _objectStack.Peek();

            deferredElement.Children.Add(childObj);
        }
Пример #7
0
        private void ReadStyle(BinaryReaderEx reader, XbfNodeSection nodeSection)
        {
            int setterCount = reader.Read7BitEncodedInt();

            for (int i = 0; i < setterCount; i++)
            {
                int valueType = reader.ReadByte();

                string propertyName  = null;
                string typeName      = null; // Name of type implementing the property, currently ignored
                object propertyValue = null;
                int    valueOffset   = 0;

                switch (valueType)
                {
                case 0x01:     // ThemeResource
                case 0x02:     // StaticResource
                case 0x08:     // General objects
                    propertyName = StringTable[reader.ReadUInt16()];
                    typeName     = GetTypeName(reader.ReadUInt16());
                    valueOffset  = reader.Read7BitEncodedInt();
                    break;

                case 0x11:     // ThemeResource
                case 0x12:     // StaticResource
                case 0x18:     // General objects
                    propertyName = GetPropertyName(reader.ReadUInt16());
                    valueOffset  = reader.Read7BitEncodedInt();
                    break;

                case 0x20:
                    propertyName  = StringTable[reader.ReadUInt16()];
                    typeName      = GetTypeName(reader.ReadUInt16());
                    propertyValue = GetPropertyValue(reader);
                    break;

                case 0x30:
                    propertyName  = GetPropertyName(reader.ReadUInt16());
                    propertyValue = GetPropertyValue(reader);
                    break;

                default:
                    throw new InvalidDataException("Unexpected value");
                }

                // General objects can be read directly with ReadObjectInNodeSection
                if (valueType == 0x08 || valueType == 0x18)
                {
                    propertyValue = ReadObjectInNodeSection(reader, nodeSection, valueOffset);
                }

                if (propertyValue != null)
                {
                    var setter = new XbfObject();
                    setter.TypeName = "Setter";
                    setter.Properties.Add(new XbfObjectProperty("Property", propertyName));
                    setter.Properties.Add(new XbfObjectProperty("Value", propertyValue));
                    _objectCollectionStack.Peek().Add(setter);
                }
                else // StaticResource or ThemeResource need to be read with the Setter already on the stack
                {
                    var setter = new XbfObject();
                    setter.TypeName = "Setter";
                    setter.Properties.Add(new XbfObjectProperty("Property", propertyName));
                    _objectCollectionStack.Peek().Add(setter);

                    _objectStack.Push(setter);
                    ReadNodeInNodeSection(reader, nodeSection, valueOffset);
                    _objectStack.Pop();
                }
            }
        }