Created
November 19, 2021 17:18
-
-
Save endowdly/3532c938339498702a47e041693bbb4d to your computer and use it in GitHub Desktop.
Like Format-Hex but faster (probably not better though...)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Endowdly.Commands | |
{ | |
using System; | |
using System.Collections; | |
using System.IO; | |
using System.Management.Automation; | |
using System.Text; | |
[Cmdlet(VerbsCommon.Format, Noun, DefaultParameterSetName = NotAsHexParameterSet)] | |
public class FormatIntegerCommand : PSCmdlet | |
{ | |
private const string Noun = "Integer"; | |
private const string Space = " "; | |
private const string ReverseAlias = "SwapEndianness"; | |
private const string AsHexParameterSet = "AsHex"; | |
private const string NotAsHexParameterSet = "NotAsHex"; | |
private const string Newline = "\n"; | |
private const char Zero = '0'; | |
[Parameter( | |
Position = 0, | |
Mandatory = true, | |
ValueFromPipeline = true, | |
ValueFromPipelineByPropertyName = true | |
)] | |
public string Path { get; set; } | |
[Parameter(ParameterSetName = AsHexParameterSet)] | |
public SwitchParameter AsHex | |
{ | |
get { return asHex; } | |
set { asHex = value; } | |
} | |
[Parameter] | |
[Alias(ReverseAlias)] | |
public SwitchParameter Reverse | |
{ | |
get { return reverse; } | |
set { reverse = value; } | |
} | |
[Parameter(ParameterSetName = NotAsHexParameterSet)] | |
public SwitchParameter FlipOutput | |
{ | |
get { return flip; } | |
set { flip = value; } | |
} | |
private bool asHex; | |
private bool reverse; | |
private bool flip; | |
protected override void ProcessRecord() | |
{ | |
ProviderInfo provider; | |
Func<string, string> flipIfFlip = s => flip ? s.Reverse() : s; | |
var filePath = GetResolvedProviderPathFromPSPath(Path, out provider)[0]; | |
var fi = new FileInfo(filePath); | |
var oh = flipIfFlip(asHex ? Data.HexOverHeader : Data.BinaryOverHeader); | |
var h = flipIfFlip(asHex ? Data.HexHeader : Data.BinaryHeader); | |
// Header information | |
WriteObject(fi.Name.PadLeft(40)); | |
WriteObject(Newline); | |
WriteObject(oh); | |
WriteObject(h); | |
WriteObject(Newline); | |
var fileBytes = File.ReadAllBytes(fi.FullName); | |
var remBytes = fileBytes.Length % 4; | |
var bytes = new byte[fileBytes.Length + (4 - remBytes)]; | |
fileBytes.CopyTo(bytes, 0); | |
var numDWords = bytes.Length / 4; | |
var rowCounter = 0; | |
var toBase = asHex ? 16 : 2; | |
var dword = new byte[4]; | |
for (int i = 0; i < numDWords; i++) | |
{ | |
for (int j = 0; j <= 3; j++) | |
{ | |
dword[j] = bytes[(i * 4) + j]; | |
} | |
if (reverse) Array.Reverse(dword); | |
var sb = new StringBuilder(); | |
var bits = new BitArray(dword); | |
for (var b = 0; b <= 3; b++) | |
{ | |
if (asHex) | |
{ | |
var s = Convert.ToString(dword[b], toBase).PadLeft(2, Zero); | |
sb.Append(s).Append(Space); | |
} | |
else | |
{ | |
for (var bit = 0; bit < 8; bit++) | |
{ | |
var idx = (b << 3) + bit; | |
var v = bits[idx] ? 1 : 0; | |
sb.Append(v).Append(Space); | |
if (bit == 3) sb.Append(Space); // seperate on the nibbles too | |
} | |
sb.Append(Space); | |
} | |
} | |
var output = flipIfFlip(sb.ToString().TrimEnd()); | |
var lineNumber = rowCounter.ToString().PadLeft(3, Zero).PadRight(4); | |
rowCounter++; | |
WriteObject(output.Insert(0, lineNumber)); | |
} | |
} | |
} | |
internal static class Data | |
{ | |
private const string Space = " "; | |
internal const string FileNotFound = "File Not Found"; | |
internal const string CannotBeZero = "Parameter cannot be zero"; | |
internal const string HexOverHeader = " "; | |
internal const string HexHeader = " 00 01 02 03 "; | |
internal static string BinaryOverHeader | |
{ | |
get | |
{ | |
var sb = new StringBuilder(" "); | |
for (int i = 0; i <= 31; i++) | |
{ | |
if (i % 10 == 0) | |
{ | |
sb.Append(i/10); | |
} | |
else | |
{ | |
sb.Append(Space); | |
} | |
sb.Append(Space); | |
if ((i + 1) % 4 == 0) sb.Append(Space); | |
} | |
sb.Append(" "); | |
return sb.ToString(); | |
} | |
} | |
internal static string BinaryHeader | |
{ | |
get | |
{ | |
var sb = new StringBuilder(" "); | |
for (int i = 0; i <= 31; i++) | |
{ | |
sb.Append(i % 10); | |
sb.Append(Space); | |
if ((i + 1) % 4 == 0) sb.Append(Space); | |
} | |
sb.Append(" "); | |
return sb.ToString(); | |
} | |
} | |
} | |
internal static class Helpers | |
{ | |
// TODO: Needs work --rjd @low | |
// internal static byte[] SwapEndianness(byte[] a) | |
// { | |
// var b = new byte[4]; | |
// var b0 = (a[0] >> 0) & 0xff; | |
// var b1 = (a[1] >> 8) & 0xff; | |
// var b2 = (a[2] >> 16) & 0xff; | |
// var b3 = (a[3] >> 24) & 0xff; | |
// b[0] = (byte)(b0 << 24); | |
// b[1] = (byte)(b1 << 16); | |
// b[2] = (byte)(b2 << 8); | |
// b[3] = (byte)(b3 << 0); | |
// return b; | |
// } | |
// This is cheap and easy but not unicode safe. | |
internal static string Reverse(this string s) | |
{ | |
var a = s.ToCharArray(); | |
Array.Reverse(a); | |
return new string(a); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment