support XOR (and others, in the future) transformations directly on the Reader / Writer

This commit is contained in:
Michael Becker 2020-04-05 02:49:42 -04:00
parent 428849ce10
commit 3954603fef
No known key found for this signature in database
GPG Key ID: 389DFF5D73781A12
6 changed files with 173 additions and 65 deletions

View File

@ -97,6 +97,9 @@ namespace UniversalEditor.IO
{
return (sbyte)(ReadBytes(1)[0]);
}
private int xorkey_index = 0;
[CLSCompliant(false)]
public byte[] ReadBytes(uint length)
{
@ -111,6 +114,11 @@ namespace UniversalEditor.IO
Array.Copy(buf2, 0, buf, lastct, buf2.Length);
lastct += (uint)ct;
}
for (int i = 0; i < Transformations.Count; i++)
{
buf = Transformations[i].Transform(buf);
}
return buf;
}

View File

@ -26,65 +26,67 @@ using System.Text;
namespace UniversalEditor.IO
{
public abstract class ReaderWriterBase
{
private Endianness mvarEndianness = Endianness.LittleEndian;
public Endianness Endianness { get { return mvarEndianness; } set { mvarEndianness = value; } }
public abstract class ReaderWriterBase
{
private Endianness mvarEndianness = Endianness.LittleEndian;
public Endianness Endianness { get { return mvarEndianness; } set { mvarEndianness = value; } }
public void SwapEndianness()
{
if (mvarEndianness == Endianness.LittleEndian)
{
mvarEndianness = Endianness.BigEndian;
}
else
{
mvarEndianness = Endianness.LittleEndian;
}
}
public void SwapEndianness()
{
if (mvarEndianness == Endianness.LittleEndian)
{
mvarEndianness = Endianness.BigEndian;
}
else
{
mvarEndianness = Endianness.LittleEndian;
}
}
private bool mvarReverse = false;
public bool Reverse { get { return mvarReverse; } }
private bool mvarReverse = false;
public bool Reverse { get { return mvarReverse; } }
private Accessor mvarAccessor = null;
public Accessor Accessor { get { return mvarAccessor; } }
private Accessor mvarAccessor = null;
public Accessor Accessor { get { return mvarAccessor; } }
private NewLineSequence mvarNewLineSequence = NewLineSequence.Default;
public NewLineSequence NewLineSequence { get { return mvarNewLineSequence; } set { mvarNewLineSequence = value; } }
public string GetNewLineSequence()
{
string newline = System.Environment.NewLine;
switch (mvarNewLineSequence)
{
case IO.NewLineSequence.CarriageReturn:
{
newline = "\r";
break;
}
case IO.NewLineSequence.LineFeed:
{
newline = "\n";
break;
}
case IO.NewLineSequence.CarriageReturnLineFeed:
{
newline = "\r\n";
break;
}
case IO.NewLineSequence.LineFeedCarriageReturn:
{
newline = "\n\r";
break;
}
}
return newline;
}
public Transformation.TransformationCollection Transformations { get; } = new Transformation.TransformationCollection();
public ReaderWriterBase(Accessor accessor)
{
this.mvarAccessor = accessor;
this.mvarEndianness = Endianness.LittleEndian;
this.mvarReverse = false;
private NewLineSequence mvarNewLineSequence = NewLineSequence.Default;
public NewLineSequence NewLineSequence { get { return mvarNewLineSequence; } set { mvarNewLineSequence = value; } }
public string GetNewLineSequence()
{
string newline = System.Environment.NewLine;
switch (mvarNewLineSequence)
{
case IO.NewLineSequence.CarriageReturn:
{
newline = "\r";
break;
}
case IO.NewLineSequence.LineFeed:
{
newline = "\n";
break;
}
case IO.NewLineSequence.CarriageReturnLineFeed:
{
newline = "\r\n";
break;
}
case IO.NewLineSequence.LineFeedCarriageReturn:
{
newline = "\n\r";
break;
}
}
return newline;
}
public ReaderWriterBase(Accessor accessor)
{
this.mvarAccessor = accessor;
this.mvarEndianness = Endianness.LittleEndian;
this.mvarReverse = false;
}
/// <summary>

View File

@ -0,0 +1,37 @@
//
// Transformation.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2020 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace UniversalEditor.IO
{
public abstract class Transformation
{
public class TransformationCollection
: System.Collections.ObjectModel.Collection<Transformation>
{
}
protected abstract byte[] TransformInternal(byte[] input);
public byte[] Transform(byte[] input)
{
return TransformInternal(input);
}
}
}

View File

@ -0,0 +1,58 @@
//
// XorTransform.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2020 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace UniversalEditor.IO.Transformations
{
public class XorTransformation : Transformation
{
/// <summary>
/// Gets or sets a key used to encrypt or decrypt the stream.
/// </summary>
/// <remarks>Pronounced "zorkie", like Sonny Eclipse ;)</remarks>
/// <value>The key used to encrypt or decrypt this stream, or <see langword="null"/> if no key is needed.</value>
public byte[] XorKey { get; set; } = null;
public int XorKeyIndex { get; set; } = 0;
/// <summary>
/// Initializes a new instance of the <see cref="T:UniversalEditor.IO.Transformations.XorTransformation"/> class.
/// </summary>
/// <param name="xorkey">The key used to encrypt or decrypt this stream, or <see langword="null"/> if no key is needed.</param>
public XorTransformation(byte[] xorkey = null)
{
XorKey = xorkey;
XorKeyIndex = 0;
}
protected override byte[] TransformInternal(byte[] input)
{
if (XorKey == null) return input;
for (int i = 0; i < input.Length; i++)
{
if (XorKeyIndex >= XorKey.Length)
XorKeyIndex = 0;
input[i] ^= XorKey[XorKeyIndex];
}
return input;
}
}
}

View File

@ -50,9 +50,16 @@ namespace UniversalEditor.IO
{
WriteBytes(new byte[] { (byte)value });
}
private int xorkey_index = 0;
public void WriteBytes(byte[] data)
{
if (data == null) return;
for (int i = 0; i < Transformations.Count; i++)
{
data = Transformations[i].Transform(data);
}
Write(data, 0, data.Length);
}
@ -204,21 +211,12 @@ namespace UniversalEditor.IO
public void WriteNullTerminatedString(string sz)
{
if (sz != null)
{
for (int i = 0; i < sz.Length; i++)
{
WriteChar(sz[i]);
}
}
WriteChar('\0');
WriteNullTerminatedString(sz, Encoding.UTF8);
}
public void WriteNullTerminatedString(string sz, Encoding encoding)
{
byte[] values = encoding.GetBytes(sz);
byte[] values = encoding.GetBytes(sz + '\0');
WriteBytes(values);
WriteInt16(0);
}
public void WriteNullTerminatedString(string sz, int length)
{

View File

@ -89,6 +89,8 @@
<Compile Include="References.cs" />
<Compile Include="IO\FileNameShortener.cs" />
<Compile Include="CustomOptionAttribute.cs" />
<Compile Include="IO\Transformations\XorTransformation.cs" />
<Compile Include="IO\Transformation.cs" />
</ItemGroup>
<ItemGroup />
<ItemGroup>
@ -97,6 +99,9 @@
<Name>MBS.Framework</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="IO\Transformations\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.