Ensure LazyCompressedString doesn't decompress when debugging

This commit is contained in:
Shannon
2021-01-27 15:11:16 +11:00
parent 0cb4952338
commit 9200c46cd0

View File

@@ -1,5 +1,6 @@
using K4os.Compression.LZ4;
using System;
using System.Diagnostics;
using System.Text;
using Umbraco.Core.Exceptions;
@@ -8,6 +9,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
/// <summary>
/// Lazily decompresses a LZ4 Pickler compressed UTF8 string
/// </summary>
[DebuggerDisplay("{Display}")]
internal struct LazyCompressedString
{
private byte[] _bytes;
@@ -22,29 +24,85 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
{
_locker = new object();
_bytes = bytes;
_str = null;
_str = null;
}
public byte[] GetBytes()
{
if (_bytes == null)
{
throw new InvalidOperationException("The bytes have already been expanded");
}
return _bytes;
}
public override string ToString()
/// <summary>
/// Returns the decompressed string from the bytes. This methods can only be called once.
/// </summary>
/// <returns></returns>
/// <exception cref="InvalidOperationException">Throws if this is called more than once</exception>
public string DecompressString()
{
if (_str != null) return _str;
if (_str != null)
{
return _str;
}
lock (_locker)
{
if (_str != null) return _str; // double check
if (_bytes == null) throw new PanicException("Bytes have already been cleared");
if (_str != null)
{
// double check
return _str;
}
if (_bytes == null)
{
throw new InvalidOperationException("Bytes have already been cleared");
}
_str = Encoding.UTF8.GetString(LZ4Pickler.Unpickle(_bytes));
_bytes = null;
}
return _str;
}
/// <summary>
/// Used to display debugging output since ToString() can only be called once
/// </summary>
private string Display
{
get
{
if (_str != null)
{
return $"Decompressed: {_str}";
}
lock (_locker)
{
if (_str != null)
{
// double check
return $"Decompressed: {_str}";
}
if (_bytes == null)
{
// This shouldn't happen
throw new PanicException("Bytes have already been cleared");
}
else
{
return $"Compressed Bytes: {_bytes.Length}";
}
}
}
}
public override string ToString() => DecompressString();
public static implicit operator string(LazyCompressedString l) => l.ToString();
}