private static void ReadDataRef(XmlReader reader, string name, uint offset, bool visible, IPluginVisitor visitor, uint pluginLine) { string format = "bytes"; if (reader.MoveToAttribute("format")) { format = reader.Value; } if (format != "bytes" && format != "unicode" && format != "asciiz") { throw new ArgumentException("Invalid format. Must be either `bytes`, `unicode` or `asciiz`."); } int align = 4; if (reader.MoveToAttribute("align")) { align = ParseInt(reader.Value); } visitor.VisitDataReference(name, offset, format, visible, align, pluginLine); }
private void WritePlugin(MetaMap map, int size, IPluginVisitor writer) { for (int offset = 0; offset < size; offset += 4) { MetaValueGuess guess = map.GetGuess(offset); if (guess != null) { switch (guess.Type) { case MetaValueType.DataReference: if (offset <= size - 0x14) { writer.VisitDataReference("Unknown", (uint)offset, "bytes", false, 4, 0); offset += 0x10; continue; } break; case MetaValueType.TagReference: if (offset <= size - 0x10) { writer.VisitTagReference("Unknown", (uint)offset, false, true, true, 0); offset += 0xC; continue; } break; case MetaValueType.Reflexive: if (offset <= size - 0xC) { MetaMap subMap = map.GetSubMap(offset); if (subMap != null) { int subMapSize = subMap.GetBestSizeEstimate(); writer.EnterReflexive("Unknown", (uint)offset, false, (uint)subMapSize, 4, 0); WritePlugin(subMap, subMapSize, writer); writer.LeaveReflexive(); offset += 0x8; continue; } } break; } } // Just write an unknown value depending upon how much space we have left if (offset <= size - 4) { writer.VisitUndefined("Unknown", (uint)offset, false, 0); } else if (offset <= size - 2) { writer.VisitInt16("Unknown", (uint)offset, false, 0); } else { writer.VisitInt8("Unknown", (uint)offset, false, 0); } } }
/// <summary> /// Handles an element which describes how a value /// should be read from the cache file. /// </summary> /// <param name="reader">The XmlReader that read the element.</param> /// <param name="elementName">The element's name.</param> /// <param name="visitor">The IPluginVisitor to call to.</param> private static void HandleValueElement(XmlReader reader, string elementName, IPluginVisitor visitor) { var name = "Unknown"; uint offset = 0; var xmlLineInfo = reader as IXmlLineInfo; if (xmlLineInfo == null) return; var pluginLine = (uint)xmlLineInfo.LineNumber; var visible = true; if (reader.MoveToAttribute("name")) name = reader.Value; if (reader.MoveToAttribute("offset")) offset = ParseUInt(reader.Value); if (reader.MoveToAttribute("visible")) visible = ParseBool(reader.Value); reader.MoveToElement(); switch (elementName.ToLower()) // FIXME: Using ToLower() here violates XML standards { case "uint8": visitor.VisitUInt8(name, offset, visible, pluginLine); break; case "int8": visitor.VisitInt8(name, offset, visible, pluginLine); break; case "uint16": visitor.VisitUInt16(name, offset, visible, pluginLine); break; case "int16": visitor.VisitInt16(name, offset, visible, pluginLine); break; case "uint32": visitor.VisitUInt32(name, offset, visible, pluginLine); break; case "int32": visitor.VisitInt32(name, offset, visible, pluginLine); break; case "float32": case "float": visitor.VisitFloat32(name, offset, visible, pluginLine); break; case "undefined": visitor.VisitUndefined(name, offset, visible, pluginLine); break; case "vector3": visitor.VisitVector3(name, offset, visible, pluginLine); break; case "degree": visitor.VisitDegree(name, offset, visible, pluginLine); break; case "stringid": visitor.VisitStringID(name, offset, visible, pluginLine); break; case "tagref": ReadTagRef(reader, name, offset, visible, visitor, pluginLine); break; case "range": ReadRange(reader, name, offset, visible, visitor, pluginLine); break; case "ascii": ReadAscii(reader, name, offset, visible, visitor, pluginLine); break; case "utf16": ReadUtf16(reader, name, offset, visible, visitor, pluginLine); break; case "bitfield8": if (visitor.EnterBitfield8(name, offset, visible, pluginLine)) ReadBits(reader, visitor); else reader.Skip(); break; case "bitfield16": if (visitor.EnterBitfield16(name, offset, visible, pluginLine)) ReadBits(reader, visitor); else reader.Skip(); break; case "bitfield32": if (visitor.EnterBitfield32(name, offset, visible, pluginLine)) ReadBits(reader, visitor); else reader.Skip(); break; case "enum8": if (visitor.EnterEnum8(name, offset, visible, pluginLine)) ReadOptions(reader, visitor); else reader.Skip(); break; case "enum16": if (visitor.EnterEnum16(name, offset, visible, pluginLine)) ReadOptions(reader, visitor); else reader.Skip(); break; case "enum32": if (visitor.EnterEnum32(name, offset, visible, pluginLine)) ReadOptions(reader, visitor); else reader.Skip(); break; //case "color8": case "colour8": //case "color16": case "colour16": case "color": case "colour": visitor.VisitColorInt(name, offset, visible, ReadColorFormat(reader), pluginLine); break; case "color24": case "colour24": visitor.VisitColorInt(name, offset, visible, "rgb", pluginLine); break; case "color32": case "colour32": visitor.VisitColorInt(name, offset, visible, "argb", pluginLine); break; case "colorf": case "colourf": visitor.VisitColorF(name, offset, visible, ReadColorFormat(reader), pluginLine); break; case "dataref": visitor.VisitDataReference(name, offset, ReadDataRef(reader), visible, pluginLine); break; case "reflexive": ReadReflexive(reader, name, offset, visible, visitor, pluginLine); break; case "raw": ReadRaw(reader, name, offset, visible, visitor, pluginLine); break; default: throw new ArgumentException("Unknown element \"" + elementName + "\"." + PositionInfo(reader)); } }
/// <summary> /// Handles an element which describes how a value /// should be read from the cache file. /// </summary> /// <param name="reader">The XmlReader that read the element.</param> /// <param name="elementName">The element's name.</param> /// <param name="visitor">The IPluginVisitor to call to.</param> private void HandleValueElement(XmlReader reader, string elementName, IPluginVisitor visitor) { string name = "Unknown"; uint offset = 0; var pluginLine = (uint) (reader as IXmlLineInfo).LineNumber; bool visible = true; if (reader.MoveToAttribute("name")) name = reader.Value; if (reader.MoveToAttribute("offset")) offset = ParseUInt(reader.Value); if (reader.MoveToAttribute("visible")) visible = ParseBool(reader.Value); reader.MoveToElement(); switch (elementName.ToLower()) { case "uint8": case "byte": visitor.VisitUInt8(name, offset, visible, pluginLine); break; case "sbyte": case "int8": visitor.VisitInt8(name, offset, visible, pluginLine); break; case "ushort": case "uint16": visitor.VisitUInt16(name, offset, visible, pluginLine); break; case "short": case "int16": visitor.VisitInt16(name, offset, visible, pluginLine); break; case "dword": case "uint": case "uint32": case "long": case "true": visitor.VisitUInt32(name, offset, visible, pluginLine); break; case "int": case "int32": visitor.VisitInt32(name, offset, visible, pluginLine); break; case "undefined": case "unknown": visitor.VisitUndefined(name, offset, visible, pluginLine); break; case "float": case "float32": case "degree": visitor.VisitFloat32(name, offset, visible, pluginLine); break; case "vector3": visitor.VisitVector3(name, offset, visible, pluginLine); break; case "stringid": visitor.VisitStringID(name, offset, visible, pluginLine); break; case "tag": case "tagid": case "tagref": case "ident": ReadTagRef(reader, name, offset, visible, visitor, pluginLine); break; case "string": case "ascii": ReadAscii(reader, name, offset, visible, visitor, pluginLine); break; case "string32": visitor.VisitAscii(name, offset, visible, 32, pluginLine); break; case "string64": visitor.VisitAscii(name, offset, visible, 64, pluginLine); break; case "string256": visitor.VisitAscii(name, offset, visible, 256, pluginLine); break; case "unicode": case "utf16": ReadUtf16(reader, name, offset, visible, visitor, pluginLine); break; case "unicode32": visitor.VisitUtf16(name, offset, visible, 32, pluginLine); break; case "unicode64": visitor.VisitUtf16(name, offset, visible, 64, pluginLine); break; case "unicode256": visitor.VisitUtf16(name, offset, visible, 256, pluginLine); break; case "bitfield8": case "bitmask8": if (visitor.EnterBitfield8(name, offset, visible, pluginLine)) ReadBits(reader, visitor); break; case "bitmask16": case "bitfield16": if (visitor.EnterBitfield16(name, offset, visible, pluginLine)) ReadBits(reader, visitor); break; case "bitmask32": case "bitfield32": if (visitor.EnterBitfield32(name, offset, visible, pluginLine)) ReadBits(reader, visitor); break; case "enum8": if (visitor.EnterEnum8(name, offset, visible, pluginLine)) ReadOptions(reader, visitor); break; case "enum16": if (visitor.EnterEnum16(name, offset, visible, pluginLine)) ReadOptions(reader, visitor); break; case "enum32": if (visitor.EnterEnum32(name, offset, visible, pluginLine)) ReadOptions(reader, visitor); break; case "tagdata": case "dataref": visitor.VisitDataReference(name, offset, ReadDataRef(reader), visible, pluginLine); break; case "struct": case "reflexive": case "reflexives": ReadReflexive(reader, name, offset, visible, visitor, pluginLine); break; case "bytearray": case "raw": ReadRaw(reader, name, offset, visible, visitor, pluginLine); break; case "color8": case "color16": case "color24": case "color32": visitor.VisitColorInt(name, offset, visible, ReadColorFormat(reader), pluginLine); break; case "colorf": visitor.VisitColorF(name, offset, visible, ReadColorFormat(reader), pluginLine); break; case "id": // Class ID, part of a tag reference break; case "unused": case "unusued": case "ununused": // Do nothing, I really don't understand the point of this break; default: throw new ArgumentException("Unknown element \"" + elementName + "\"." + PositionInfo(reader)); } }
private static void ReadDataRef(XmlReader reader, string name, uint offset, bool visible, IPluginVisitor visitor, uint pluginLine) { string format = "bytes"; if (reader.MoveToAttribute("format")) format = reader.Value; if (format != "bytes" && format != "unicode" && format != "asciiz") throw new ArgumentException("Invalid format. Must be either `bytes`, `unicode` or `asciiz`."); int align = 4; if (reader.MoveToAttribute("align")) align = ParseInt(reader.Value); visitor.VisitDataReference(name, offset, format, visible, align, pluginLine); }
private void WritePlugin(MetaMap map, int size, IPluginVisitor writer) { for (int offset = 0; offset < size; offset += 4) { MetaValueGuess guess = map.GetGuess(offset); if (guess != null) { switch (guess.Type) { case MetaValueType.DataReference: if (offset <= size - 0x14) { writer.VisitDataReference("Unknown", (uint) offset, "bytes", false, 4, 0); offset += 0x10; continue; } break; case MetaValueType.TagReference: if (offset <= size - 0x10) { writer.VisitTagReference("Unknown", (uint) offset, false, true, true, 0); offset += 0xC; continue; } break; case MetaValueType.Reflexive: if (offset <= size - 0xC) { MetaMap subMap = map.GetSubMap(offset); if (subMap != null) { int subMapSize = subMap.GetBestSizeEstimate(); writer.EnterReflexive("Unknown", (uint) offset, false, (uint)subMapSize, 4, 0); WritePlugin(subMap, subMapSize, writer); writer.LeaveReflexive(); offset += 0x8; continue; } } break; } } // Just write an unknown value depending upon how much space we have left if (offset <= size - 4) writer.VisitUndefined("Unknown", (uint) offset, false, 0); else if (offset <= size - 2) writer.VisitInt16("Unknown", (uint) offset, false, 0); else writer.VisitInt8("Unknown", (uint) offset, false, 0); } }