-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move
Snowberry.IO.SingleFile
to this repository
- Loading branch information
Showing
24 changed files
with
1,360 additions
and
19 deletions.
There are no files selected for viewing
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
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
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using CommandLine; | ||
|
||
namespace Snowberry.IO.SingleFile.CLI; | ||
|
||
internal class Options | ||
{ | ||
[Option('i', "input", Required = true, HelpText = "Sets the input single file path.")] | ||
public string InputFilePath { get; set; } = string.Empty; | ||
|
||
[Option('o', "output", Required = false, HelpText = "Sets the output directory.")] | ||
public string OutputDirectory { get; set; } = string.Empty; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
using CommandLine; | ||
using Serilog; | ||
using Snowberry.IO.SingleFile; | ||
using Snowberry.IO.SingleFile.CLI; | ||
|
||
Log.Logger = new LoggerConfiguration() | ||
.MinimumLevel.Debug() | ||
.WriteTo.Console() | ||
#if DEBUG | ||
.WriteTo.Debug() | ||
#endif | ||
.CreateLogger(); | ||
|
||
Parser.Default.ParseArguments<Options>(args) | ||
.WithParsed(o => | ||
{ | ||
if (!File.Exists(o.InputFilePath)) | ||
{ | ||
Log.Fatal("Could not find input file path: {input}", o.InputFilePath); | ||
Environment.Exit(-1); | ||
} | ||
|
||
Log.Information("Processing: {path}", o.InputFilePath); | ||
|
||
bool useOutputDirectory = !string.IsNullOrWhiteSpace(o.OutputDirectory); | ||
|
||
try | ||
{ | ||
using var singleFileBinaryData = SingleFileBinaryData.GetFromFile(o.InputFilePath); | ||
|
||
if (singleFileBinaryData == null) | ||
{ | ||
Log.Fatal("Specified file is not a published single file!"); | ||
Environment.Exit(-1); | ||
} | ||
|
||
if (singleFileBinaryData.BundleManifest == null) | ||
return; | ||
|
||
var bundleManifest = singleFileBinaryData.BundleManifest; | ||
Log.Information($"{"Bundle ID:",-24} {{id}}", bundleManifest.BundleID); | ||
Log.Information($"{"Bundle Major Version:",-24} {{ver}}", bundleManifest.BundleMajorVersion); | ||
Log.Information($"{"Bundle Minor Version:",-24} {{ver}}", bundleManifest.BundleMinorVersion); | ||
Log.Information($"{"Bundle Flags:",-24} {{flags}}", bundleManifest.Flags); | ||
Log.Information($"{"Bundle File Count:",-24} {{count}}", bundleManifest.FileEntries.Count); | ||
Log.Information(""); | ||
|
||
string? outputDirectory = useOutputDirectory ? o.OutputDirectory : null; | ||
|
||
if (useOutputDirectory && !Directory.Exists(outputDirectory)) | ||
Directory.CreateDirectory(outputDirectory!); | ||
|
||
for (int i = 0; i < bundleManifest.FileEntries.Count; i++) | ||
{ | ||
var fileEntry = bundleManifest.FileEntries[i]; | ||
|
||
Log.Information("File: {type}/{path}", fileEntry.FileType, fileEntry.RelativePath); | ||
|
||
if (useOutputDirectory) | ||
{ | ||
using var fileEntryStream = singleFileBinaryData.GetStream(fileEntry); | ||
|
||
if (fileEntryStream == null) | ||
{ | ||
Log.Fatal(" Could not open stream for file entry!"); | ||
Environment.Exit(-1); | ||
} | ||
|
||
string filePath = Path.Combine(outputDirectory!, fileEntry.RelativePath); | ||
string? directory = Path.GetDirectoryName(filePath); | ||
|
||
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) | ||
Directory.CreateDirectory(directory); | ||
|
||
using var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); | ||
fileEntryStream.CopyTo(fs); | ||
} | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
Log.Fatal(e, "Could not process file: {input}", o.InputFilePath); | ||
} | ||
|
||
Log.Information("Done..."); | ||
}); |
8 changes: 8 additions & 0 deletions
8
src/Snowberry.IO.SingleFile.CLI/Properties/launchSettings.json
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"profiles": { | ||
"Snowberry.IO.SingleFile.CLI": { | ||
"commandName": "Project", | ||
"commandLineArgs": "" | ||
} | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/Snowberry.IO.SingleFile.CLI/Snowberry.IO.SingleFile.CLI.csproj
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net9.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<AssemblyVersion>1.0.0.0</AssemblyVersion> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="CommandLineParser" Version="2.9.1" /> | ||
<PackageReference Include="Serilog" Version="4.1.0" /> | ||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" /> | ||
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Snowberry.IO.SingleFile\Snowberry.IO.SingleFile.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
using System.IO.MemoryMappedFiles; | ||
|
||
namespace Snowberry.IO.SingleFile; | ||
|
||
public static class BinarySearchHelper | ||
{ | ||
public static unsafe int SearchInView(MemoryMappedViewAccessor accessor, byte[] toSearch) | ||
{ | ||
var safeBuffer = accessor.SafeMemoryMappedViewHandle; | ||
byte* buffer = (byte*)safeBuffer.DangerousGetHandle(); | ||
return SearchInBuffer(buffer, (int)accessor.Capacity, toSearch); | ||
} | ||
|
||
public static unsafe int SearchInBuffer(byte* buffer, int length, byte[] toSearch) | ||
{ | ||
if (toSearch.Length > length) | ||
return -1; | ||
|
||
int[] table = BuildTable(toSearch); | ||
|
||
int i = 0; | ||
int j = 0; | ||
|
||
while (i + j < length) | ||
{ | ||
if (toSearch[j] == buffer[i + j]) | ||
{ | ||
j++; | ||
|
||
if (j == toSearch.Length) | ||
{ | ||
return i; | ||
} | ||
} | ||
else | ||
{ | ||
i += j - table[j]; | ||
j = Math.Max(0, table[j]); | ||
} | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
private static int[] BuildTable(byte[] toSearch) | ||
{ | ||
int[] table = new int[toSearch.Length]; | ||
int position = 2; | ||
int candidate = 0; | ||
|
||
table[0] = -1; | ||
table[1] = 0; | ||
|
||
while (position < toSearch.Length) | ||
{ | ||
if (toSearch[position - 1] == toSearch[candidate]) | ||
{ | ||
table[position++] = ++candidate; | ||
continue; | ||
} | ||
|
||
if (candidate > 0) | ||
{ | ||
candidate = table[candidate]; | ||
continue; | ||
} | ||
|
||
table[position++] = 0; | ||
} | ||
|
||
return table; | ||
} | ||
} | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System.Text.Json.Serialization; | ||
|
||
namespace Snowberry.IO.SingleFile; | ||
|
||
/// <summary> | ||
/// The bundler options. | ||
/// </summary> | ||
public class BundlerOptions | ||
{ | ||
/// <summary> | ||
/// Gets or sets a value indicating whether to use compression for the files. | ||
/// </summary> | ||
/// <remarks>It depends on the bundle version whether compressing is supported.</remarks> | ||
[JsonPropertyName(nameof(UseCompression))] | ||
public bool UseCompression { get; set; } = true; | ||
|
||
/// <summary> | ||
/// Gets or sets the compression threshold. | ||
/// </summary> | ||
/// <remarks>If the compressed size is smaller than the original size multiplied by this value, the compressed data will be used.</remarks> | ||
[JsonPropertyName(nameof(CompressionThreshold))] | ||
public float CompressionThreshold { get; set; } = 0.75F; | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether to force compression for the files even if the compressed size exceeds the compression threshold. | ||
/// </summary> | ||
[JsonPropertyName(nameof(ForceCompression))] | ||
public bool ForceCompression { get; set; } | ||
} |
Oops, something went wrong.