Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Base64Conversion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace PSBinaryModule
{
public sealed record Base64ConversionResult(string Input, string Output, string Encoding)
{
internal static Base64ConversionResult FromEncoding(string input, string encodedData, string encodingName) =>
new(input, encodedData, encodingName);
}
}
83 changes: 83 additions & 0 deletions src/Commands/ConvertFromBase64Command.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System.Management.Automation;
using System.Text;

namespace PSBinaryModule.Commands
{
/// <summary>
/// Decodes a Base64 string back to its original format.
/// </summary>
[Cmdlet(VerbsData.ConvertFrom, "Base64")]
[OutputType(typeof(Base64ConversionResult))]
public sealed class ConvertFromBase64Command : PSCmdlet
{
/// <summary>
/// Gets or sets the Base64 string to decode.
/// </summary>
[Parameter(
Mandatory = true,
Position = 0,
ValueFromPipeline = true,
HelpMessage = "Base64 string to decode")]
[ValidateNotNullOrEmpty]
public string InputString { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the encoding to use.
/// </summary>
[Parameter(
Mandatory = false,
HelpMessage = "Text encoding to use (UTF8, ASCII, Unicode). Default is UTF8")]
[ValidateSet("UTF8", "ASCII", "Unicode")]
public string Encoding { get; set; } = "UTF8";

protected override void ProcessRecord()
{
try
{
// Get encoding
var enc = GetEncoding(Encoding);

// Decode from Base64
var bytes = Convert.FromBase64String(InputString);
var decoded = enc.GetString(bytes);

// Create result
var inputPreview = InputString.Length > 100
? InputString.AsSpan(0, 100).ToString() + "..."
: InputString;
var result = Base64ConversionResult.FromEncoding(
inputPreview,
decoded,
Encoding);

WriteObject(result);
}
catch (FormatException ex)
{
WriteError(new ErrorRecord(
new FormatException($"The input string is not a valid Base64 string: {ex.Message}", ex),
"InvalidBase64Format",
ErrorCategory.InvalidData,
InputString));
}
catch (Exception ex)
{
WriteError(new ErrorRecord(
ex,
"DecodingError",
ErrorCategory.InvalidOperation,
InputString));
}
}

private static Encoding GetEncoding(string encodingName)
{
return encodingName switch
{
"ASCII" => System.Text.Encoding.ASCII,
"Unicode" => System.Text.Encoding.Unicode,
_ => System.Text.Encoding.UTF8,
};
}
}
}
133 changes: 133 additions & 0 deletions src/Commands/ConvertToBase64Command.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using System.Management.Automation;
using System.Text;

namespace PSBinaryModule.Commands
{
/// <summary>
/// Encodes a string or file contents to Base64.
/// </summary>
[Cmdlet(VerbsData.ConvertTo, "Base64")]
[OutputType(typeof(Base64ConversionResult))]
public sealed class ConvertToBase64Command : PSCmdlet
{
/// <summary>
/// Gets or sets the string to encode.
/// </summary>
[Parameter(
Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ParameterSetName = "InputString",
HelpMessage = "String to encode to Base64")]
[ValidateNotNullOrEmpty]
public string InputString { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the file path to encode.
/// </summary>
[Parameter(
Mandatory = true,
Position = 0,
ParameterSetName = "Path",
HelpMessage = "Path to file to encode to Base64")]
[ValidateNotNullOrEmpty]
public string Path { get; set; } = string.Empty;

/// <summary>
/// Gets or sets the encoding to use.
/// </summary>
[Parameter(
Mandatory = false,
HelpMessage = "Text encoding to use (UTF8, ASCII, Unicode). Default is UTF8")]
[ValidateSet("UTF8", "ASCII", "Unicode")]
public string Encoding { get; set; } = "UTF8";

protected override void ProcessRecord()
{
try
{
// Get the data to encode based on parameter set
string dataToEncode;
if (ParameterSetName == "InputString")
{
dataToEncode = InputString;
}
else
{
// Resolve the file path
var resolvedPaths = SessionState.Path.GetResolvedPSPathFromPSPath(Path);

if (resolvedPaths.Count == 0)
{
WriteError(new ErrorRecord(
new FileNotFoundException($"Cannot find path '{Path}' because it does not exist."),
"PathNotFound",
ErrorCategory.ObjectNotFound,
Path));
return;
}

if (resolvedPaths.Count > 1)
{
WriteError(new ErrorRecord(
new ArgumentException($"Path '{Path}' resolves to multiple items. Please specify a single file."),
"MultiplePathsResolved",
ErrorCategory.InvalidArgument,
Path));
return;
}

var resolvedPath = resolvedPaths[0].Path;

if (!File.Exists(resolvedPath))
{
WriteError(new ErrorRecord(
new FileNotFoundException($"Cannot find file '{resolvedPath}'."),
"FileNotFound",
ErrorCategory.ObjectNotFound,
resolvedPath));
return;
}

dataToEncode = File.ReadAllText(resolvedPath);
}

// Get encoding
var enc = GetEncoding(Encoding);

// Encode to Base64
var bytes = enc.GetBytes(dataToEncode);
var encoded = Convert.ToBase64String(bytes);

// Create result
var inputPreview = dataToEncode.Length > 100
? dataToEncode.AsSpan(0, 100).ToString() + "..."
: dataToEncode;
var result = Base64ConversionResult.FromEncoding(
inputPreview,
encoded,
Encoding);

WriteObject(result);
}
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
{
WriteError(new ErrorRecord(
ex,
"FileAccessError",
ErrorCategory.ReadError,
ParameterSetName == "Path" ? Path : null));
}
}

private static Encoding GetEncoding(string encodingName)
{
return encodingName switch
{
"ASCII" => System.Text.Encoding.ASCII,
"Unicode" => System.Text.Encoding.Unicode,
_ => System.Text.Encoding.UTF8,
};
}
}
}
18 changes: 18 additions & 0 deletions src/Commands/GetEnvironmentInfoCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Management.Automation;

namespace PSBinaryModule.Commands
{
/// <summary>
/// Gets environment metadata information.
/// </summary>
[Cmdlet(VerbsCommon.Get, "EnvironmentInfo")]
[OutputType(typeof(EnvironmentInfo))]
public sealed class GetEnvironmentInfoCommand : PSCmdlet
{
protected override void ProcessRecord()
{
var environmentInfo = EnvironmentInfo.GetCurrent();
WriteObject(environmentInfo);
}
}
}
Loading
Loading