diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
index 3f48a9bd119..18f370849ea 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/format-hex/Format-Hex.cs
@@ -54,10 +54,25 @@ public sealed class FormatHex : PSCmdlet
[ValidateNotNullOrEmpty]
public Encoding Encoding { get; set; } = ClrFacade.GetDefaultEncoding();
+ ///
+ /// Gets and sets count of bytes to read from the input stream.
+ ///
+ [Parameter()]
+ [ValidateRange(ValidateRangeKind.Positive)]
+ public Int64 Count { get; set; } = Int64.MaxValue;
+
+ ///
+ /// Gets and sets offset of bytes to start reading the input stream from.
+ ///
+ [Parameter()]
+ [ValidateRange(ValidateRangeKind.NonNegative)]
+ public Int64 Offset { get; set; }
+
///
/// This parameter is no-op.
///
- [Parameter(ParameterSetName = "ByInputObject")]
+ [Parameter(ParameterSetName = "ByInputObject", DontShow = true)]
+ [Obsolete("Raw parameter is deprecated.", true)]
public SwitchParameter Raw { get; set; }
#endregion
@@ -157,42 +172,36 @@ private void ProcessPath(List pathsToProcess)
///
/// Creates a binary reader that reads the file content into a buffer (byte[]) 16 bytes at a time, and
- /// passes a copy of that array on to the ConvertToHexidecimal method to output.
+ /// passes a copy of that array on to the WriteHexidecimal method to output.
///
///
private void ProcessFileContent(string path)
{
- byte[] buffer = new byte[BUFFERSIZE];
+ Span buffer = stackalloc byte[BUFFERSIZE];
try
{
- using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read)))
+ using (BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
- UInt32 offset = 0;
+ Int64 offset = Offset;
Int32 bytesRead = 0;
+ Int64 count = 0;
- while ((bytesRead = reader.Read(buffer, 0, BUFFERSIZE)) > 0)
+ reader.BaseStream.Position = Offset;
+
+ while ((bytesRead = reader.Read(buffer)) > 0)
{
- if (bytesRead == BUFFERSIZE)
- {
- // We are reusing the same buffer so if we save the output to a variable, the variable
- // will just contain multiple references to the same buffer memory space (containing only the
- // last bytes of the file read). Copying the buffer allows us to pass the values on without
- // overwriting previous values.
- byte[] copyOfBuffer = new byte[16];
- Array.Copy(buffer, 0, copyOfBuffer, 0, bytesRead);
- ConvertToHexidecimal(copyOfBuffer, path, offset);
- }
- else
+ count += bytesRead;
+ if (count > Count)
{
- // Handle the case of a partial (and probably last) buffer. Copies the bytes read into a new,
- // shorter array so we do not have the extra bytes from the previous pass through at the end.
- byte[] remainingBytes = new byte[bytesRead];
- Array.Copy(buffer, 0, remainingBytes, 0, bytesRead);
- ConvertToHexidecimal(remainingBytes, path, offset);
+ bytesRead -= (int)(count - Count);
+ WriteHexidecimal(buffer.Slice(0, bytesRead), path, offset);
+ break;
}
- // Update offset value.
- offset += (UInt32)bytesRead;
+
+ WriteHexidecimal(buffer.Slice(0, bytesRead), path, offset);
+
+ offset += bytesRead;
}
}
}
@@ -221,85 +230,86 @@ private void ProcessFileContent(string path)
///
/// Creates a byte array from the object passed to the cmdlet (based on type) and passes
- /// that array on to the ConvertToHexidecimal method to output.
+ /// that array on to the WriteHexidecimal method to output.
///
///
private void ProcessObjectContent(PSObject inputObject)
{
Object obj = inputObject.BaseObject;
byte[] inputBytes = null;
- if (obj is System.IO.FileSystemInfo)
- {
- string[] path = { ((FileSystemInfo)obj).FullName };
- List pathsToProcess = ResolvePaths(path, true);
- ProcessPath(pathsToProcess);
- }
- else if (obj is string)
+ switch (obj)
{
- string inputString = obj.ToString();
- inputBytes = Encoding.GetBytes(inputString);
- }
+ case System.IO.FileSystemInfo fsi:
+ string[] path = { fsi.FullName };
+ List pathsToProcess = ResolvePaths(path, true);
+ ProcessPath(pathsToProcess);
+ return;
+ case string str:
+ inputBytes = Encoding.GetBytes(str);
+ break;
+ case byte b:
+ inputBytes = new byte[] { b };
+ break;
+ case byte[] byteArray:
+ inputBytes = byteArray;
+ break;
+ case Int32 iInt32:
+ inputBytes = BitConverter.GetBytes(iInt32);
+ break;
+ case Int32[] i32s:
+ int i32 = 0;
+ inputBytes = new byte[sizeof(Int32) * i32s.Length];
+ Span inputStreamArray32 = inputBytes;
+
+ foreach (Int32 value in i32s)
+ {
+ BitConverter.TryWriteBytes(inputStreamArray32.Slice(i32), value);
+ i32 += sizeof(Int32);
+ }
- else if (obj is byte)
- {
- inputBytes = new byte[] { (byte)obj };
- }
+ break;
+ case Int64 iInt64:
+ inputBytes = BitConverter.GetBytes(iInt64);
+ break;
+ case Int64[] inputInt64s:
+ int i64 = 0;
+ inputBytes = new byte[sizeof(Int64) * inputInt64s.Length];
+ Span inputStreamArray64 = inputBytes;
- else if (obj is byte[])
- {
- inputBytes = ((byte[])obj);
- }
-
- else if (obj is Int32)
- {
- inputBytes = BitConverter.GetBytes((Int32)obj);
- }
+ foreach (Int64 value in inputInt64s)
+ {
+ BitConverter.TryWriteBytes(inputStreamArray64.Slice(i64), value);
+ i64 += sizeof(Int64);
+ }
- else if (obj is Int32[])
- {
- List inputStreamArray = new List();
- Int32[] inputInts = (Int32[])obj;
- foreach (Int32 value in inputInts)
+ break;
+ // If the object type is not supported, throw an error. Once Serialization is
+ // available on CoreCLR, other types will be supported.
+ default:
{
- byte[] tempBytes = BitConverter.GetBytes(value);
- inputStreamArray.AddRange(tempBytes);
+ string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
+ ErrorRecord errorRecord = new ErrorRecord(new ArgumentException(errorMessage),
+ "FormatHexTypeNotSupported",
+ ErrorCategory.InvalidArgument,
+ obj.GetType());
+ WriteError(errorRecord);
+ break;
}
- inputBytes = inputStreamArray.ToArray();
- }
-
- else if (obj is Int64)
- {
- inputBytes = BitConverter.GetBytes((Int64)obj);
}
- else if (obj is Int64[])
+ if (inputBytes != null)
{
- List inputStreamArray = new List();
- Int64[] inputInts = (Int64[])obj;
- foreach (Int64 value in inputInts)
+ int offset = Math.Min(inputBytes.Length, Offset < (long)int.MaxValue ? (int)Offset : int.MaxValue);
+ int count = Math.Min(inputBytes.Length - offset, Count < (long)int.MaxValue ? (int)Count : int.MaxValue);
+ if (offset != 0 || count != inputBytes.Length)
{
- byte[] tempBytes = BitConverter.GetBytes(value);
- inputStreamArray.AddRange(tempBytes);
+ WriteHexidecimal(inputBytes.AsSpan().Slice(offset, count), null, 0);
+ }
+ else
+ {
+ WriteHexidecimal(inputBytes, null, 0);
}
- inputBytes = inputStreamArray.ToArray();
- }
-
- // If the object type is not supported, throw an error. Once Serialization is
- // available on CoreCLR, other types will be supported.
- else
- {
- string errorMessage = StringUtil.Format(UtilityCommonStrings.FormatHexTypeNotSupported, obj.GetType());
- ErrorRecord errorRecord = new ErrorRecord(new ArgumentException(errorMessage),
- "FormatHexTypeNotSupported",
- ErrorCategory.InvalidArgument,
- obj.GetType());
- WriteError(errorRecord);
- }
-
- if (inputBytes != null)
- {
- ConvertToHexidecimal(inputBytes, null, 0);
}
}
@@ -308,18 +318,21 @@ private void ProcessObjectContent(PSObject inputObject)
#region Output
///
- /// Outputs the hexadecimial representaion of the of the input data.
+ /// Outputs the hexadecimial representaion of the input data.
///
- ///
- ///
- ///
- private void ConvertToHexidecimal(byte[] inputBytes, string path, UInt32 offset)
+ /// Bytes for the hexadecimial representaion.
+ /// File path.
+ /// Offset in the file.
+ private void WriteHexidecimal(Span inputBytes, string path, Int64 offset)
{
- if (inputBytes != null)
- {
- ByteCollection byteCollectionObject = new ByteCollection(offset, inputBytes, path);
- WriteObject(byteCollectionObject);
- }
+ ByteCollection byteCollectionObject = new ByteCollection((UInt64)offset, inputBytes.ToArray(), path);
+ WriteObject(byteCollectionObject);
+ }
+
+ private void WriteHexidecimal(byte[] inputBytes, string path, Int64 offset)
+ {
+ ByteCollection byteCollectionObject = new ByteCollection((UInt64)offset, inputBytes, path);
+ WriteObject(byteCollectionObject);
}
#endregion
diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
index ffa96f4a0a8..d724330d864 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/UtilityCommon.cs
@@ -99,12 +99,12 @@ public class ByteCollection
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
/// Indicates the path of the file whose contents are wrapped in the ByteCollection.
+ [Obsolete("The constructor is deprecated.", true)]
public ByteCollection(UInt32 offset, Byte[] value, string path)
{
- this.Offset = offset;
- _initialOffSet = offset;
- this.Bytes = value;
- this.Path = path;
+ Offset64 = offset;
+ Bytes = value;
+ Path = path;
}
///
@@ -112,11 +112,50 @@ public ByteCollection(UInt32 offset, Byte[] value, string path)
///
/// The Offset address to be used while displaying the bytes in the collection.
/// Underlying bytes stored in the collection.
+ /// Indicates the path of the file whose contents are wrapped in the ByteCollection.
+ public ByteCollection(UInt64 offset, Byte[] value, string path)
+ {
+ if (value == null)
+ {
+ throw PSTraceSource.NewArgumentNullException("value");
+ }
+
+ Offset64 = offset;
+ Bytes = value;
+ Path = path;
+ }
+
+ ///
+ /// ByteCollection constructor.
+ ///
+ /// The Offset address to be used while displaying the bytes in the collection.
+ /// Underlying bytes stored in the collection.
+ [Obsolete("The constructor is deprecated.", true)]
public ByteCollection(UInt32 offset, Byte[] value)
{
- this.Offset = offset;
- _initialOffSet = offset;
- this.Bytes = value;
+ if (value == null)
+ {
+ throw PSTraceSource.NewArgumentNullException("value");
+ }
+
+ Offset64 = offset;
+ Bytes = value;
+ }
+
+ ///
+ /// ByteCollection constructor.
+ ///
+ /// The Offset address to be used while displaying the bytes in the collection.
+ /// Underlying bytes stored in the collection.
+ public ByteCollection(UInt64 offset, Byte[] value)
+ {
+ if (value == null)
+ {
+ throw PSTraceSource.NewArgumentNullException("value");
+ }
+
+ Offset64 = offset;
+ Bytes = value;
}
///
@@ -125,23 +164,44 @@ public ByteCollection(UInt32 offset, Byte[] value)
/// Underlying bytes stored in the collection.
public ByteCollection(Byte[] value)
{
- this.Bytes = value;
+ if (value == null)
+ {
+ throw PSTraceSource.NewArgumentNullException("value");
+ }
+
+ Bytes = value;
+ }
+
+ ///
+ /// Gets the Offset address to be used while displaying the bytes in the collection.
+ ///
+ [Obsolete("The property is deprecated, please use Offset64 instead.", true)]
+ public UInt32 Offset
+ {
+ get
+ {
+ return (UInt32)Offset64;
+ }
+
+ private set
+ {
+ Offset64 = value;
+ }
}
///
- /// The Offset address to be used while displaying the bytes in the collection.
+ /// Gets the Offset address to be used while displaying the bytes in the collection.
///
- public UInt32 Offset { get; private set; }
- private UInt32 _initialOffSet = 0;
+ public UInt64 Offset64 { get; private set; }
///
- /// Underlying bytes stored in the collection.
+ /// Gets underlying bytes stored in the collection.
///
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public Byte[] Bytes { get; private set; }
///
- /// Indicates the path of the file whose contents are wrapped in the ByteCollection.
+ /// Gets the path of the file whose contents are wrapped in the ByteCollection.
///
public string Path { get; private set; }
@@ -151,19 +211,27 @@ public ByteCollection(Byte[] value)
///
public override string ToString()
{
- StringBuilder result = new StringBuilder();
- StringBuilder nextLine = new StringBuilder();
- StringBuilder asciiEnd = new StringBuilder();
+ const int BytesPerLine = 16;
+ const string LineFormat = "{0:X20} ";
+
+ // '20 + 3' comes from format "{0:X20} ".
+ // '20' comes from '[Uint64]::MaxValue.ToString().Length'.
+ StringBuilder nextLine = new StringBuilder(20 + 3 + BytesPerLine*3);
+ StringBuilder asciiEnd = new StringBuilder(BytesPerLine);
+
+ // '+1' comes from 'result.Append(nextLine.ToString() + " " + asciiEnd.ToString());' below.
+ StringBuilder result = new StringBuilder(nextLine.Capacity+asciiEnd.Capacity + 1);
if (Bytes.Length > 0)
{
- UInt32 charCounter = 0;
+ Int64 charCounter = 0;
// ToString() in invoked thrice by the F&O for the same content.
// Hence making sure that Offset is not getting incremented thrice for the same bytes being displayed.
- Offset = _initialOffSet;
+ var currentOffset = Offset64;
+
+ nextLine.AppendFormat(CultureInfo.InvariantCulture, LineFormat, currentOffset);
- nextLine.AppendFormat("{0:X2} ", CultureInfo.InvariantCulture.TextInfo.ToUpper(Convert.ToString(Offset, 16)).PadLeft(8, '0'));
foreach (Byte currentByte in Bytes)
{
// Display each byte, in 2-digit hexadecimal, and add that to the left-hand side.
@@ -179,38 +247,40 @@ public override string ToString()
{
asciiEnd.Append('.');
}
+
charCounter++;
// If we've hit the end of a line, combine the right half with the
// left half, and start a new line.
- if ((charCounter % 16) == 0)
+ if ((charCounter % BytesPerLine) == 0)
{
- result.Append(nextLine.ToString() + " " + asciiEnd.ToString());
+ result.Append(nextLine).Append(' ').Append(asciiEnd);
nextLine.Clear();
asciiEnd.Clear();
- Offset += 0x10;
- nextLine.AppendFormat("{0:X2} ", CultureInfo.InvariantCulture.TextInfo.ToUpper(Convert.ToString(Offset, 16)).PadLeft(8, '0'));
+ currentOffset += BytesPerLine;
+ nextLine.AppendFormat(CultureInfo.InvariantCulture, LineFormat, currentOffset);
// Adding a newline to support long inputs strings flowing through InputObject parameterset.
if ((charCounter <= Bytes.Length) && string.IsNullOrEmpty(this.Path))
{
- result.Append("\r\n");
+ result.AppendLine();
}
}
}
// At the end of the file, we might not have had the chance to output
- // the end of the line yet. Only do this if we didn't exit on the 16-byte
+ // the end of the line yet. Only do this if we didn't exit on the 16-byte
// boundary, though.
if ((charCounter % 16) != 0)
{
while ((charCounter % 16) != 0)
{
- nextLine.Append(" ");
+ nextLine.Append(' ', 3);
asciiEnd.Append(' ');
charCounter++;
}
- result.Append(nextLine.ToString() + " " + asciiEnd.ToString());
+
+ result.Append(nextLine).Append(' ').Append(asciiEnd);
}
}
diff --git a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
index 12df579f3c0..fd65f060402 100644
--- a/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
+++ b/src/System.Management.Automation/FormatAndOutput/DefaultFormatters/PowerShellCore_format_ps1xml.cs
@@ -23,8 +23,8 @@ internal static IEnumerable GetFormatData()
.StartEntry()
.StartFrame()
.AddScriptBlockExpressionBinding(@"
- $header = "" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F""
- if($_.Path) { $header = "" "" + [Microsoft.PowerShell.Commands.UtilityResources]::FormatHexPathPrefix + $_.Path + ""`r`n`r`n"" + $header }
+ $header = "" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F""
+ if($_.Path) { $header = "" "" + [Microsoft.PowerShell.Commands.UtilityResources]::FormatHexPathPrefix + $_.Path + ""`r`n`r`n"" + $header }
$header
")
.EndFrame()
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1
index b1d23abe370..9dd90a125cf 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/FormatHex.Tests.ps1
@@ -18,6 +18,8 @@ Describe "FormatHex" -tags "CI" {
BeforeAll {
+ $newline = [Environment]::Newline
+
Setup -d FormatHexDataDir
$inputText1 = 'Hello World'
$inputText2 = 'More text'
@@ -77,25 +79,25 @@ Describe "FormatHex" -tags "CI" {
Name = "Can process int32[] type 'fhx -InputObject [int32[]](2032, 2033, 2034)'"
InputObject = [int32[]](2032, 2033, 2034)
Count = 1
- ExpectedResult = "00000000 F0 07 00 00 F1 07 00 00 F2 07 00 00 ð...ñ...ò..."
+ ExpectedResult = "00000000000000000000 F0 07 00 00 F1 07 00 00 F2 07 00 00 ð...ñ...ò..."
}
@{
Name = "Can process Int64 type 'fhx -InputObject [Int64]9223372036854775807'"
InputObject = [Int64]9223372036854775807
Count = 1
- ExpectedResult = "00000000 FF FF FF FF FF FF FF 7F ......."
+ ExpectedResult = "00000000000000000000 FF FF FF FF FF FF FF 7F ......."
}
@{
Name = "Can process Int64[] type 'fhx -InputObject [Int64[]](9223372036852,9223372036853)'"
InputObject = [Int64[]](9223372036852,9223372036853)
Count = 1
- ExpectedResult = "00000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c...õZÐ{c..."
+ ExpectedResult = "00000000000000000000 F4 5A D0 7B 63 08 00 00 F5 5A D0 7B 63 08 00 00 ôZÐ{c...õZÐ{c..."
}
@{
Name = "Can process string type 'fhx -InputObject hello world'"
InputObject = "hello world"
Count = 1
- ExpectedResult = "00000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
+ ExpectedResult = "00000000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
}
)
@@ -117,59 +119,59 @@ Describe "FormatHex" -tags "CI" {
Name = "Can process byte type '[byte]5 | fhx'"
InputObject = [byte]5
Count = 1
- ExpectedResult = "00000000 05"
+ ExpectedResult = "00000000000000000000 05"
}
@{
Name = "Can process byte[] type '[byte[]](1,2) | fhx'"
InputObject = [byte[]](1,2)
Count = 2
- ExpectedResult = "00000000 01 ."
- ExpectedSecondResult = "00000000 02 ."
+ ExpectedResult = "00000000000000000000 01 ."
+ ExpectedSecondResult = "00000000000000000000 02 ."
}
@{
Name = "Can process int type '7 | fhx'"
InputObject = 7
Count = 1
- ExpectedResult = "00000000 07 00 00 00 ...."
+ ExpectedResult = "00000000000000000000 07 00 00 00 ...."
}
@{
Name = "Can process int[] type '[int[]](5,6) | fhx'"
InputObject = [int[]](5,6)
Count = 2
- ExpectedResult = "00000000 05 00 00 00 ...."
- ExpectedSecondResult = "00000000 06 00 00 00 ...."
+ ExpectedResult = "00000000000000000000 05 00 00 00 ...."
+ ExpectedSecondResult = "00000000000000000000 06 00 00 00 ...."
}
@{
Name = "Can process int32 type '[int32]2032 | fhx'"
InputObject = [int32]2032
Count = 1
- ExpectedResult = "00000000 F0 07 00 00 ð..."
+ ExpectedResult = "00000000000000000000 F0 07 00 00 ð..."
}
@{
Name = "Can process int32[] type '[int32[]](2032, 2033) | fhx'"
InputObject = [int32[]](2032, 2033)
Count = 2
- ExpectedResult = "00000000 F0 07 00 00 ð..."
- ExpectedSecondResult = "00000000 F1 07 00 00 ñ..."
+ ExpectedResult = "00000000000000000000 F0 07 00 00 ð..."
+ ExpectedSecondResult = "00000000000000000000 F1 07 00 00 ñ..."
}
@{
Name = "Can process Int64 type '[Int64]9223372036854775807 | fhx'"
InputObject = [Int64]9223372036854775807
Count = 1
- ExpectedResult = "00000000 FF FF FF FF FF FF FF 7F ......."
+ ExpectedResult = "00000000000000000000 FF FF FF FF FF FF FF 7F ......."
}
@{
Name = "Can process Int64[] type '[Int64[]](9223372036852,9223372036853) | fhx'"
InputObject = [Int64[]](9223372036852,9223372036853)
Count = 2
- ExpectedResult = "00000000 F4 5A D0 7B 63 08 00 00 ôZÐ{c..."
- ExpectedSecondResult = "00000000 F5 5A D0 7B 63 08 00 00 õZÐ{c..."
+ ExpectedResult = "00000000000000000000 F4 5A D0 7B 63 08 00 00 ôZÐ{c..."
+ ExpectedSecondResult = "00000000000000000000 F5 5A D0 7B 63 08 00 00 õZÐ{c..."
}
@{
Name = "Can process string type 'hello world | fhx'"
InputObject = "hello world"
Count = 1
- ExpectedResult = "00000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
+ ExpectedResult = "00000000000000000000 68 65 6C 6C 6F 20 77 6F 72 6C 64 hello world"
}
)
@@ -262,37 +264,37 @@ Describe "FormatHex" -tags "CI" {
Name = "Can process ASCII encoding 'fhx -InputObject 'hello' -Encoding ASCII'"
Encoding = "ASCII"
Count = 1
- ExpectedResult = "00000000 68 65 6C 6C 6F hello"
+ ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
}
@{
Name = "Can process BigEndianUnicode encoding 'fhx -InputObject 'hello' -Encoding BigEndianUnicode'"
Encoding = "BigEndianUnicode"
Count = 1
- ExpectedResult = "00000000 00 68 00 65 00 6C 00 6C 00 6F .h.e.l.l.o"
+ ExpectedResult = "00000000000000000000 00 68 00 65 00 6C 00 6C 00 6F .h.e.l.l.o"
}
@{
Name = "Can process Unicode encoding 'fhx -InputObject 'hello' -Encoding Unicode'"
Encoding = "Unicode"
Count = 1
- ExpectedResult = "00000000 68 00 65 00 6C 00 6C 00 6F 00 h.e.l.l.o."
+ ExpectedResult = "00000000000000000000 68 00 65 00 6C 00 6C 00 6F 00 h.e.l.l.o."
}
@{
Name = "Can process UTF7 encoding 'fhx -InputObject 'hello' -Encoding UTF7'"
Encoding = "UTF7"
Count = 1
- ExpectedResult = "00000000 68 65 6C 6C 6F hello"
+ ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
}
@{
Name = "Can process UTF8 encoding 'fhx -InputObject 'hello' -Encoding UTF8'"
Encoding = "UTF8"
Count = 1
- ExpectedResult = "00000000 68 65 6C 6C 6F hello"
+ ExpectedResult = "00000000000000000000 68 65 6C 6C 6F hello"
}
@{
Name = "Can process UTF32 encoding 'fhx -InputObject 'hello' -Encoding UTF32'"
Encoding = "UTF32"
Count = 1
- ExpectedResult = "00000000 68 00 00 00 65 00 00 00 6C 00 00 00 6C 00 00 00 h...e...l...l...`r`n00000010 6F 00 00 00 o..."
+ ExpectedResult = "00000000000000000000 68 00 00 00 65 00 00 00 6C 00 00 00 6C 00 00 00 h...e...l...l...$($newline)00000000000000000010 6F 00 00 00 o..."
}
)
@@ -418,18 +420,80 @@ Describe "FormatHex" -tags "CI" {
$result | Should -Not -BeNullOrEmpty
,$result | Should -BeOfType 'Microsoft.PowerShell.Commands.ByteCollection'
- $result.ToString() | Should -MatchExactly "00000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa`r`n00000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa "
+ $result.ToString() | Should -MatchExactly "00000000000000000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa$($newline)00000000000000000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaa "
+ }
+
+ It "Validate that files do not have buffer underrun problems 'Format-Hex -Path `$InputFile4'" {
+
+ $result = Format-Hex -Path $InputFile4
+
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
+ }
+ }
+
+ Context "Count and Offset parameters" {
+ It "Count = length" {
+
+ $result = Format-Hex -Path $InputFile4 -Count $inputText4.Length
+
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
+ }
+
+ It "Count = 1" {
+ $result = Format-Hex -Path $inputFile4 -Count 1
+ $result.ToString() | Should -MatchExactly "00000000000000000000 4E N "
+ }
+
+ It "Offset = length" {
+
+ $result = Format-Hex -Path $InputFile4 -Offset $inputText4.Length
+ $result | Should -BeNullOrEmpty
+
+ $result = Format-Hex -InputObject $inputText4 -Offset $inputText4.Length
+ $result.Bytes | Should -HaveCount 0
+ }
+
+ It "Offset = 1" {
+
+ $result = Format-Hex -Path $InputFile4 -Offset 1
+
+ $result | Should -Not -BeNullOrEmpty
+ $result.Count | Should -Be 3
+ $result[0].ToString() | Should -MatchExactly "00000000000000000001 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 72 ow is the winter"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000011 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 65 of our disconte"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000021 6E 74 nt "
+ }
+
+ It "Count = 1 and Offset = 1" {
+ $result = Format-Hex -Path $inputFile4 -Count 1 -Offset 1
+ $result.ToString() | Should -MatchExactly "00000000000000000001 6F o "
+ }
+
+ It "Count should be > 0" {
+ { Format-Hex -Path $inputFile4 -Count 0 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
+ }
+
+ It "Offset should be >= 0" {
+ { Format-Hex -Path $inputFile4 -Offset -1 } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.FormatHex"
}
- It "Validate that files do not have buffer underrun problems 'Format-Hex -path `$InputFile4'" {
+ It "Offset = 0" {
- $result = Format-Hex -path $InputFile4
+ $result = Format-Hex -Path $InputFile4 -Offset 0
$result | Should -Not -BeNullOrEmpty
$result.Count | Should -Be 3
- $result[0].ToString() | Should -MatchExactly "00000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
- $result[1].ToString() | Should -MatchExactly "00000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
- $result[2].ToString() | Should -MatchExactly "00000020 65 6E 74 ent "
+ $result[0].ToString() | Should -MatchExactly "00000000000000000000 4E 6F 77 20 69 73 20 74 68 65 20 77 69 6E 74 65 Now is the winte"
+ $result[1].ToString() | Should -MatchExactly "00000000000000000010 72 20 6F 66 20 6F 75 72 20 64 69 73 63 6F 6E 74 r of our discont"
+ $result[2].ToString() | Should -MatchExactly "00000000000000000020 65 6E 74 ent "
}
}
}