ByteSize
Represents a byte size value.
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
namespace Relativity.DataExchange
{
[DebuggerNonUserCode]
internal struct ByteSize : IComparable<ByteSize>, IEquatable<ByteSize>
{
public const long BitsInByte = 8;
public const long BytesInKiloByte = 1024;
public const long BytesInMegaByte = 1048576;
public const long BytesInGigaByte = 1073741824;
public const long BytesInTeraByte = 1099511627776;
public const long BytesInPetaByte = 1125899906842624;
public const string BitSymbol = "b";
public const string ByteSymbol = "B";
public const string KiloByteSymbol = "KB";
public const string MegaByteSymbol = "MB";
public const string GigaByteSymbol = "GB";
public const string TeraByteSymbol = "TB";
public const string PetaByteSymbol = "PB";
public long Bits { get; }
public double Bytes { get; }
public double KiloBytes { get; }
public double MegaBytes { get; }
public double GigaBytes { get; }
public double TeraBytes { get; }
public double PetaBytes { get; }
public string LargestWholeNumberSymbol {
get {
if (Math.Abs(PetaBytes) >= 1)
return "PB";
if (Math.Abs(TeraBytes) >= 1)
return "TB";
if (Math.Abs(GigaBytes) >= 1)
return "GB";
if (Math.Abs(MegaBytes) >= 1)
return "MB";
if (Math.Abs(KiloBytes) >= 1)
return "KB";
if (Math.Abs(Bytes) >= 1)
return "B";
return "b";
}
}
public double LargestWholeNumberValue {
get {
if (Math.Abs(PetaBytes) >= 1)
return PetaBytes;
if (Math.Abs(TeraBytes) >= 1)
return TeraBytes;
if (Math.Abs(GigaBytes) >= 1)
return GigaBytes;
if (Math.Abs(MegaBytes) >= 1)
return MegaBytes;
if (Math.Abs(KiloBytes) >= 1)
return KiloBytes;
if (Math.Abs(Bytes) >= 1)
return Bytes;
return (double)Bits;
}
}
public ByteSize(double byteSize)
{
this = default(ByteSize);
Bits = (long)Math.Ceiling(byteSize * 8);
Bytes = byteSize;
KiloBytes = byteSize / 1024;
MegaBytes = byteSize / 1048576;
GigaBytes = byteSize / 1073741824;
TeraBytes = byteSize / 1099511627776;
PetaBytes = byteSize / 1125899906842624;
}
public static ByteSize FromBits(long value)
{
return new ByteSize((double)value / 8);
}
public static ByteSize FromBytes(double value)
{
return new ByteSize(value);
}
public static ByteSize FromKiloBytes(double value)
{
return new ByteSize(value * 1024);
}
public static ByteSize FromMegaBytes(double value)
{
return new ByteSize(value * 1048576);
}
public static ByteSize FromGigaBytes(double value)
{
return new ByteSize(value * 1073741824);
}
public static ByteSize FromTeraBytes(double value)
{
return new ByteSize(value * 1099511627776);
}
public static ByteSize FromPetaBytes(double value)
{
return new ByteSize(value * 1125899906842624);
}
public static ByteSize operator +(ByteSize b1, ByteSize b2)
{
return new ByteSize(b1.Bytes + b2.Bytes);
}
public static ByteSize operator ++(ByteSize b)
{
return new ByteSize(b.Bytes + 1);
}
public static ByteSize operator -(ByteSize b)
{
return new ByteSize(0 - b.Bytes);
}
public static ByteSize operator --(ByteSize b)
{
return new ByteSize(b.Bytes - 1);
}
public static bool operator ==(ByteSize b1, ByteSize b2)
{
return b1.Bits == b2.Bits;
}
public static bool operator !=(ByteSize b1, ByteSize b2)
{
return b1.Bits != b2.Bits;
}
public static bool operator <(ByteSize b1, ByteSize b2)
{
return b1.Bits < b2.Bits;
}
public static bool operator <=(ByteSize b1, ByteSize b2)
{
return b1.Bits <= b2.Bits;
}
public static bool operator >(ByteSize b1, ByteSize b2)
{
return b1.Bits > b2.Bits;
}
public static bool operator >=(ByteSize b1, ByteSize b2)
{
return b1.Bits >= b2.Bits;
}
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Preserve existing code from Github repo.")]
public static bool TryParse(string s, out ByteSize result)
{
if (string.IsNullOrWhiteSpace(s))
throw new ArgumentNullException("s", "String is null or whitespace");
result = default(ByteSize);
s = s.TrimStart(Array.Empty<char>());
bool flag = false;
int i;
for (i = 0; i < s.Length; i++) {
if (!char.IsDigit(s[i]) && s[i] != '.') {
flag = true;
break;
}
}
if (!flag)
return false;
int num = i;
string s2 = s.Substring(0, num).Trim();
string text = s.Substring(num, s.Length - num).Trim();
if (!double.TryParse(s2, NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite | NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands | NumberStyles.AllowExponent, NumberFormatInfo.InvariantInfo, out double result2))
return false;
switch (text) {
case "b":
if (result2 % 1 != 0)
return false;
result = FromBits((long)result2);
break;
case "B":
result = FromBytes(result2);
break;
case "KB":
case "kB":
case "kb":
result = FromKiloBytes(result2);
break;
case "MB":
case "mB":
case "mb":
result = FromMegaBytes(result2);
break;
case "GB":
case "gB":
case "gb":
result = FromGigaBytes(result2);
break;
case "TB":
case "tB":
case "tb":
result = FromTeraBytes(result2);
break;
case "PB":
case "pB":
case "pb":
result = FromPetaBytes(result2);
break;
}
return true;
}
public static ByteSize Parse(string s)
{
if (TryParse(s, out ByteSize result))
return result;
throw new FormatException("Value is not in the correct format");
}
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "{0} {1}", LargestWholeNumberValue, LargestWholeNumberSymbol);
}
public string ToString(string format)
{
if (!format.Contains("#") && !format.Contains("0"))
format = "#.## " + format;
Func<string, bool> func = (string s) => format.IndexOf(s, StringComparison.CurrentCultureIgnoreCase) != -1;
Func<double, string> func2 = (double n) => n.ToString(format, CultureInfo.InvariantCulture);
if (func("PB"))
return func2(PetaBytes);
if (func("TB"))
return func2(TeraBytes);
if (func("GB"))
return func2(GigaBytes);
if (func("MB"))
return func2(MegaBytes);
if (func("KB"))
return func2(KiloBytes);
if (format.IndexOf("B", StringComparison.OrdinalIgnoreCase) != -1)
return func2(Bytes);
if (format.IndexOf("b", StringComparison.OrdinalIgnoreCase) != -1)
return func2((double)Bits);
return LargestWholeNumberValue.ToString(format, CultureInfo.InvariantCulture) + " " + LargestWholeNumberSymbol;
}
public override bool Equals(object value)
{
if (value == null)
return false;
if (!(value is ByteSize))
return false;
ByteSize value2 = (ByteSize)value;
return Equals(value2);
}
public bool Equals(ByteSize value)
{
return Bits == value.Bits;
}
public override int GetHashCode()
{
return Bits.GetHashCode();
}
public int CompareTo(ByteSize other)
{
return Bits.CompareTo(other.Bits);
}
}
}