GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Add setting for optional zip compression (different approach) by DisabledMallis · Pull Request #244 · ReClassNET/ReClass.NET

Add setting for optional zip compression (different approach) #244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Sign up for GitHub

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
DisabledMallis wants to merge 1 commit into ReClassNET:master
base: master
Loading
Loading
from DisabledMallis:master

Uh oh!

There was an error while loading. Please reload this page.

Open

Add setting for optional zip compression (different approach) #244

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1 commit
Select commit
2a81428
Add setting for optional zip compression
DisabledMallis Nov 8, 2022
File filter
Filter by extension


Clear filters
Conversations
Failed to load comments.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Jump to
Jump to file
Failed to load files.
Loading

Uh oh!

There was an error while loading. Please reload this page.

Diff view
Diff view
Add setting for optional zip compression
This is useful when the ReClass.NET project is in a git repository and multiple people are working on it at once. Git software often cannot merge ZIP archives, and thus cannot merge rcnet project files. Having the ability to save the project without compression can solve this issue.
  • Loading branch information

Uh oh!

There was an error while loading. Please reload this page.

@DisabledMallis
DisabledMallis committed Nov 8, 2022
commit 2a81428697efd092c249ce90192f16e1c509a63d

There are no files selected for viewing

41 changes: 41 additions & 0 deletions 41 ReClass.NET/DataExchange/ReClass/ReClassDataFile.Constants.cs
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace ReClassNET.DataExchange.ReClass
{
public partial class ReClassDataFile
{
public const string FormatName = "ReClass.NET Data File";
public const string FileExtension = ".xml";
public const string FileExtensionId = "rcdatafile";

private const uint FileVersion = 0x00010001;
private const uint FileVersionCriticalMask = 0xFFFF0000;

private const string SerializationClassName = "__Serialization_Class__";

public const string XmlRootElement = "reclass";
public const string XmlCustomDataElement = "custom_data";
public const string XmlTypeMappingElement = "type_mapping";
public const string XmlEnumsElement = "enums";
public const string XmlEnumElement = "enum";
public const string XmlClassesElement = "classes";
public const string XmlClassElement = "class";
public const string XmlNodeElement = "node";
public const string XmlMethodElement = "method";
public const string XmlVersionAttribute = "version";
public const string XmlPlatformAttribute = "type";
public const string XmlUuidAttribute = "uuid";
public const string XmlNameAttribute = "name";
public const string XmlCommentAttribute = "comment";
public const string XmlHiddenAttribute = "hidden";
public const string XmlAddressAttribute = "address";
public const string XmlTypeAttribute = "type";
public const string XmlReferenceAttribute = "reference";
public const string XmlCountAttribute = "count";
public const string XmlBitsAttribute = "bits";
public const string XmlLengthAttribute = "length";
public const string XmlSizeAttribute = "size";
public const string XmlSignatureAttribute = "signature";
public const string XmlFlagsAttribute = "flags";
public const string XmlItemElement = "item";
public const string XmlValueAttribute = "value";
}
}
333 changes: 333 additions & 0 deletions 333 ReClass.NET/DataExchange/ReClass/ReClassDataFile.Read.cs
Show comments
View file
Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Xml.Linq;
using ReClassNET.DataExchange.ReClass.Legacy;
using ReClassNET.Extensions;
using ReClassNET.Logger;
using ReClassNET.Nodes;
using ReClassNET.Project;

namespace ReClassNET.DataExchange.ReClass
{
public partial class ReClassDataFile
{
public void Load(string filePath, ILogger logger)
{
using var fs = new FileStream(filePath, FileMode.Open);

Load(fs, logger);
}

public void Load(Stream input, ILogger logger)
{
Contract.Requires(input != null);
Contract.Requires(logger != null);

var document = XDocument.Load(input);
if (document.Root?.Element(XmlClassesElement) == null)
{
throw new FormatException("The data has not the correct format.");
}

uint.TryParse(document.Root.Attribute(XmlVersionAttribute)?.Value, out var fileVersion);
if ((fileVersion & FileVersionCriticalMask) > (FileVersion & FileVersionCriticalMask))
{
throw new FormatException($"The file version is unsupported. A newer {Constants.ApplicationName} version is required to read it.");
}

var platform = document.Root.Attribute(XmlPlatformAttribute)?.Value;
if (platform != Constants.Platform)
{
logger.Log(LogLevel.Warning, $"The platform of the file ({platform}) doesn't match the program platform ({Constants.Platform}).");
}

var customDataElement = document.Root.Element(XmlCustomDataElement);
if (customDataElement != null)
{
project.CustomData.Deserialize(customDataElement);
}

var typeMappingElement = document.Root.Element(XmlTypeMappingElement);
if (typeMappingElement != null)
{
project.TypeMapping.Deserialize(typeMappingElement);
}

var enumsElement = document.Root.Element(XmlEnumsElement);
if (enumsElement != null)
{
foreach (var enumElement in enumsElement.Elements(XmlEnumElement))
{
var name = enumElement.Attribute(XmlNameAttribute)?.Value ?? string.Empty;
var useFlagsMode = (bool?)enumElement.Attribute(XmlFlagsAttribute) ?? false;
var size = enumElement.Attribute(XmlSizeAttribute).GetEnumValue<EnumDescription.UnderlyingTypeSize>();

var values = new Dictionary<string, long>();
foreach (var itemElement in enumElement.Elements(XmlItemElement))
{
var itemName = itemElement.Attribute(XmlNameAttribute)?.Value ?? string.Empty;
var itemValue = (long?)itemElement.Attribute(XmlValueAttribute) ?? 0L;

values.Add(itemName, itemValue);
}

var @enum = new EnumDescription
{
Name = name
};
@enum.SetData(useFlagsMode, size, values);

project.AddEnum(@enum);
}
}

var classes = new List<(XElement, ClassNode)>();

var classesElement = document.Root.Element(XmlClassesElement);
if (classesElement != null)
{
foreach (var element in classesElement
.Elements(XmlClassElement)
.DistinctBy(e => e.Attribute(XmlUuidAttribute)?.Value))
{
var node = new ClassNode(false)
{
Uuid = ParseUuid(element.Attribute(XmlUuidAttribute)?.Value),
Name = element.Attribute(XmlNameAttribute)?.Value ?? string.Empty,
Comment = element.Attribute(XmlCommentAttribute)?.Value ?? string.Empty,
AddressFormula = element.Attribute(XmlAddressAttribute)?.Value ?? string.Empty
};

if (!project.ContainsClass(node.Uuid))
{
project.AddClass(node);

classes.Add((element, node));
}
}
}

foreach (var (element, classNode) in classes)
{
var nodes = element.Elements(XmlNodeElement)
.Select(e => CreateNodeFromElement(e, classNode, logger))
.Where(n => n != null);

classNode.BeginUpdate();
classNode.AddNodes(nodes);
classNode.EndUpdate();
}
}

private BaseNode CreateNodeFromElement(XElement element, BaseNode parent, ILogger logger)
{
Contract.Requires(element != null);
Contract.Requires(logger != null);

BaseNode CreateNode()
{
var converter = CustomNodeSerializer.GetReadConverter(element);
if (converter != null)
{
return converter.CreateNodeFromElement(element, parent, project.Classes, logger, CreateNodeFromElement);
}

if (!buildInStringToTypeMap.TryGetValue(element.Attribute(XmlTypeAttribute)?.Value ?? string.Empty, out var nodeType))
{
logger.Log(LogLevel.Error, $"Skipping node with unknown type: {element.Attribute(XmlTypeAttribute)?.Value}");
logger.Log(LogLevel.Warning, element.ToString());

return null;
}

return BaseNode.CreateInstanceFromType(nodeType, false);
}

var node = CreateNode();
if (node == null)
{
logger.Log(LogLevel.Error, "Could not create node.");

return null;
}

node.ParentNode = parent;

node.Name = element.Attribute(XmlNameAttribute)?.Value ?? string.Empty;
node.Comment = element.Attribute(XmlCommentAttribute)?.Value ?? string.Empty;
node.IsHidden = bool.TryParse(element.Attribute(XmlHiddenAttribute)?.Value, out var val) && val;

if (node is BaseWrapperNode wrapperNode)
{
ClassNode GetClassNodeFromElementReference()
{
var reference = ParseUuid(element.Attribute(XmlReferenceAttribute)?.Value);
if (!project.ContainsClass(reference))
{
logger.Log(LogLevel.Error, $"Skipping node with unknown reference: {reference}");
logger.Log(LogLevel.Warning, element.ToString());

return null;
}

return project.GetClassByUuid(reference);
}

// Legacy Support
if (node is ClassPointerNode || node is ClassInstanceArrayNode || node is ClassPointerArrayNode)
{
var innerClass = GetClassNodeFromElementReference();
if (innerClass == null)
{
return null;
}

node = node switch
{
BaseClassArrayNode classArrayNode => classArrayNode.GetEquivalentNode(0, innerClass),
ClassPointerNode classPointerNode => classPointerNode.GetEquivalentNode(innerClass)
};
}
else
{
BaseNode innerNode = null;

if (node is BaseClassWrapperNode)
{
innerNode = GetClassNodeFromElementReference();
if (innerNode == null)
{
return null;
}
}
else
{
var innerElement = element.Elements().FirstOrDefault();
if (innerElement != null)
{
innerNode = CreateNodeFromElement(innerElement, node, logger);
}
}

if (wrapperNode.CanChangeInnerNodeTo(innerNode))
{
var rootWrapperNode = node.GetRootWrapperNode();
if (rootWrapperNode.ShouldPerformCycleCheckForInnerNode()
&& innerNode is ClassNode classNode
&& ClassUtil.IsCyclicIfClassIsAccessibleFromParent(node.GetParentClass(), classNode, project.Classes))
{
logger.Log(LogLevel.Error, $"Skipping node with cyclic class reference: {node.GetParentClass().Name}->{rootWrapperNode.Name}");

return null;
}

wrapperNode.ChangeInnerNode(innerNode);
}
else
{
logger.Log(LogLevel.Error, $"The node {innerNode} is not a valid child for {node}.");
}
}
}

switch (node)
{
case VirtualMethodTableNode vtableNode:
{
var nodes = element
.Elements(XmlMethodElement)
.Select(e => new VirtualMethodNode
{
Name = e.Attribute(XmlNameAttribute)?.Value ?? string.Empty,
Comment = e.Attribute(XmlCommentAttribute)?.Value ?? string.Empty,
IsHidden = (bool?)e.Attribute(XmlHiddenAttribute) ?? false
});

vtableNode.AddNodes(nodes);
break;
}
case UnionNode unionNode:
{
var nodes = element
.Elements()
.Select(e => CreateNodeFromElement(e, unionNode, logger));

unionNode.AddNodes(nodes);
break;
}
case BaseWrapperArrayNode arrayNode:
{
arrayNode.Count = (int?)element.Attribute(XmlCountAttribute) ?? 0;
break;
}
case BaseTextNode textNode:
{
textNode.Length = (int?)element.Attribute(XmlLengthAttribute) ?? 0;
break;
}
case BitFieldNode bitFieldNode:
{
bitFieldNode.Bits = (int?)element.Attribute(XmlBitsAttribute) ?? 0;
break;
}
case FunctionNode functionNode:
{
functionNode.Signature = element.Attribute(XmlSignatureAttribute)?.Value ?? string.Empty;

var reference = ParseUuid(element.Attribute(XmlReferenceAttribute)?.Value);
if (project.ContainsClass(reference))
{
functionNode.BelongsToClass = project.GetClassByUuid(reference);
}
break;
}
case EnumNode enumNode:
{
var enumName = element.Attribute(XmlReferenceAttribute)?.Value ?? string.Empty;
var @enum = project.Enums.FirstOrDefault(e => e.Name == enumName) ?? EnumDescription.Default;

enumNode.ChangeEnum(@enum);
break;
}
}

return node;
}

private static Guid ParseUuid(string raw) => raw == null
? throw new ArgumentNullException()
: raw.Length == 24
? new Guid(Convert.FromBase64String(raw))
: Guid.Parse(raw);

public static Tuple<List<ClassNode>, List<BaseNode>> DeserializeNodesFromStream(Stream input, ReClassNetProject templateProject, ILogger logger)
{
Contract.Requires(input != null);
Contract.Requires(logger != null);
Contract.Ensures(Contract.Result<Tuple<List<ClassNode>, List<BaseNode>>>() != null);

using var project = new ReClassNetProject();
templateProject?.Classes.ForEach(project.AddClass);

var file = new ReClassDataFile(project);
file.Load(input, logger);

var classes = project.Classes
.Where(c => c.Name != SerializationClassName);
if (templateProject != null)
{
classes = classes.Where(c => !templateProject.ContainsClass(c.Uuid));
}

var nodes = project.Classes
.Where(c => c.Name == SerializationClassName)
.SelectMany(c => c.Nodes);

return Tuple.Create(classes.ToList(), nodes.ToList());
}
}
}
Loading
Oops, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.