Skip to content

Commit

Permalink
improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeAlhayek committed Nov 7, 2024
1 parent fefc90d commit 3edaeaf
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Cysharp.Text;
using Microsoft.IO;
using UglyToad.PdfPig;

namespace OrchardCore.Media.Indexing;
Expand All @@ -18,7 +17,7 @@ public async Task<string> GetTextAsync(string path, Stream fileStream)
if (!fileStream.CanSeek)
{
seekableStream = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 4096, FileOptions.DeleteOnClose);

await fileStream.CopyToAsync(seekableStream);

seekableStream.Position = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ public async Task<IActionResult> ServiceEndpoint([ModelBinder(BinderType = typeo
result.Save(w);
}

var content = Encoding.UTF8.GetString(stream.ToArray());
var content = Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);

return Content(content, "text/xml");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public Task<byte[]> SerializeAsync<TDocument>(TDocument document, int compressTh
var data = JsonSerializer.SerializeToUtf8Bytes(document, _serializerOptions);
if (data.Length >= compressThreshold)
{
data = Compress(data);
data = Compress(data).ToArray();
}

return Task.FromResult(data);
Expand All @@ -33,12 +33,16 @@ public Task<byte[]> SerializeAsync<TDocument>(TDocument document, int compressTh
public Task<TDocument> DeserializeAsync<TDocument>(byte[] data)
where TDocument : class, IDocument, new()
{
TDocument document;

if (IsCompressed(data))
{
data = Decompress(data);
document = JsonSerializer.Deserialize<TDocument>(Decompress(data), _serializerOptions);
}
else
{
document = JsonSerializer.Deserialize<TDocument>(data, _serializerOptions);
}

var document = JsonSerializer.Deserialize<TDocument>(data, _serializerOptions);

return Task.FromResult(document);
}
Expand All @@ -55,37 +59,24 @@ internal static bool IsCompressed(byte[] data)
return false;
}

internal static byte[] Compress(byte[] data)
internal static ReadOnlySpan<byte> Compress(byte[] data)
{
using var input = new MemoryStream(data);
using var output = MemoryStreamFactory.GetStream();
using (var gzip = new GZipStream(output, CompressionMode.Compress))
{
input.CopyTo(gzip);
}
using var gZip = new GZipStream(output, CompressionMode.Compress);

if (output.TryGetBuffer(out var buffer))
{
return buffer.Array;
}
input.CopyTo(gZip);

return output.ToArray();
return output.GetBuffer().AsSpan().Slice(0, (int)gZip.Length);
}

internal static byte[] Decompress(byte[] data)
internal static ReadOnlySpan<byte> Decompress(byte[] data)
{
using var input = new MemoryStream(data);
using var output = MemoryStreamFactory.GetStream();
using (var gzip = new GZipStream(input, CompressionMode.Decompress))
{
gzip.CopyTo(output);
}

if (output.TryGetBuffer(out var buffer))
{
return buffer.Array;
}
using var gZip = new GZipStream(input, CompressionMode.Decompress);
gZip.CopyTo(output);

return output.ToArray();
return output.GetBuffer().AsSpan().Slice(0, (int)gZip.Length);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ public class CommonGeneratorMethods : IGlobalMethodProvider
Name = "base64",
Method = serviceProvider => (Func<string, string>)(encoded =>
{
return Encoding.UTF8.GetString(Convert.FromBase64String(encoded));
var neededLength = GetByteArrayLengthFromBase64(encoded);
Span<byte> bytes = new byte[neededLength];
if (!Convert.TryFromBase64String(encoded, bytes, out var bytesWritten))
{
throw new FormatException("Invalid Base64 string.");
}
return Encoding.UTF8.GetString(bytes);
}),
};

Expand All @@ -33,35 +41,41 @@ public class CommonGeneratorMethods : IGlobalMethodProvider
Name = "gzip",
Method = serviceProvider => (Func<string, string>)(encoded =>
{
var bytes = new Span<byte>();
var neededLength = GetByteArrayLengthFromBase64(encoded);
var stream = MemoryStreamFactory.GetStream();
Span<byte> bytes = new byte[neededLength];
if (Convert.TryFromBase64String(encoded, bytes, out _))
{
stream.Write(bytes);
}
else
if (!Convert.TryFromBase64String(encoded, bytes, out var _))
{
stream.Write(Convert.FromBase64String(encoded));
throw new FormatException("Invalid Base64 string.");
}
using var gzip = new GZipStream(stream, CompressionMode.Decompress);
using var stream = MemoryStreamFactory.GetStream();
stream.Write(bytes);
stream.Seek(0, SeekOrigin.Begin);
using var gZip = new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true);
using var decompressed = MemoryStreamFactory.GetStream();
var buffer = new byte[1024];
int nRead;
while ((nRead = gzip.Read(buffer, 0, buffer.Length)) > 0)
while ((nRead = gZip.Read(buffer, 0, buffer.Length)) > 0)
{
decompressed.Write(buffer, 0, nRead);
}
stream.Dispose();
return Convert.ToBase64String(decompressed.GetBuffer());
return Convert.ToBase64String(decompressed.GetBuffer(), 0, (int)decompressed.Length);
}),
};

public IEnumerable<GlobalMethod> GetMethods() => new[] { _base64, _html, _gZip };
public IEnumerable<GlobalMethod> GetMethods()
=> new[] { _base64, _html, _gZip };

// Base64 string length gives us the original byte length. It encodes 3 bytes into 4 characters.
// The formula to calculate the number of bytes from the base64 string length is:
private static int GetByteArrayLengthFromBase64(string base64String)
{
return (base64String.Length * 3) / 4;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ public object Evaluate(IScriptingScope scope, string script)

using var fileStream = fileInfo.CreateReadStream();
using var memoryStream = MemoryStreamFactory.GetStream();
memoryStream.WriteTo(fileStream);
memoryStream.Seek(0, SeekOrigin.Begin);

return Convert.ToBase64String(memoryStream.GetBuffer());
return Convert.ToBase64String(memoryStream.GetBuffer().AsSpan().Slice(0, (int)memoryStream.Length));
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion test/OrchardCore.Tests/Stubs/MemoryFileBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public async Task SetFileAsync(string subpath, Stream stream)
{
using var ms = MemoryStreamFactory.GetStream();
await stream.CopyToAsync(ms);
VirtualFiles[subpath] = ms.ToArray();
VirtualFiles[subpath] = ms.GetBuffer().AsSpan().Slice((int)ms.Length).ToArray();
}

/// <summary>
Expand Down

0 comments on commit 3edaeaf

Please sign in to comment.