// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System;
using System.IO;
using System.Text;
namespace Flax.Stats
{
///
/// Contains some useful functions
///
public static class Tools
{
///
/// Converts size of the file (in bytes) to the best fitting string
///
/// Size of the file in bytes
/// The best fitting string of the file size
public static string BytesToText(long bytes)
{
string[] s = { "B", "KB", "MB", "GB", "TB" };
int i = 0;
float dblSByte = bytes;
for (; (int)(bytes / 1024.0f) > 0; i++, bytes /= 1024)
dblSByte = bytes / 1024.0f;
return string.Format("{0:0.00} {1}", dblSByte, s[i]);
}
///
/// Returns date and time as 'good' for filenames string
///
/// Date and Time
public static string ToFilenameString(this DateTime dt)
{
StringBuilder sb = new StringBuilder();
sb.Append(dt.ToShortDateString().Replace(' ', '_').Replace('-', '_').Replace('/', '_').Replace('\\', '_'));
sb.Append('_');
sb.Append(dt.ToLongTimeString().Replace(':', '_').Replace(' ', '_'));
return sb.ToString();
}
#region Direct Write
///
/// Write new line to the stream
///
/// Stream
public static void WriteLine(this Stream fs)
{
fs.WriteByte((byte)'\n');
}
///
/// Write text to the stream without '\0' char
///
/// File stream
/// Data to write
public static void WriteText(this Stream fs, string data)
{
// Write all bytes
for (int i = 0; i < data.Length; i++)
{
// Write single byte
fs.WriteByte((byte)data[i]);
}
}
///
/// Write char to the stream
///
/// File stream
/// Data to write
public static void Write(this Stream fs, char data)
{
// Write single byte
fs.WriteByte((byte)data);
}
///
/// Write string in UTF-8 encoding to the stream
///
/// File stream
/// Data to write
public static void WriteUTF8(this Stream fs, string data)
{
// Check if string is null or empty
if (string.IsNullOrEmpty(data))
{
// Write 0
fs.Write(0);
}
else
{
// Get bytes
byte[] bytes = Encoding.UTF8.GetBytes(data);
// Write length
fs.Write(bytes.Length);
// Write all bytes
fs.Write(bytes, 0, bytes.Length);
}
}
///
/// Write string in UTF-8 encoding to the stream and offset data
///
/// File stream
/// Data to write
/// Offset to apply when writing data
public static void WriteUTF8(this Stream fs, string data, byte offset)
{
// Check if string is null or empty
if (string.IsNullOrEmpty(data))
{
// Write 0
fs.Write(0);
}
else
{
// Get bytes
byte[] bytes = Encoding.UTF8.GetBytes(data);
// Write length
int len = bytes.Length;
fs.Write(len);
// Offset data
for (int i = 0; i < len; i++)
{
bytes[i] += offset;
}
// Write all bytes
fs.Write(bytes, 0, len);
}
}
///
/// Write bool to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, bool value)
{
// Write single byte
fs.WriteByte((value) ? (byte)1 : (byte)0);
}
///
/// Write short to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, short value)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(value);
// Write bytes
fs.Write(bytes, 0, 2);
}
///
/// Write ushort to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, ushort value)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(value);
// Write bytes
fs.Write(bytes, 0, 2);
}
///
/// Write int to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, int value)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(value);
// Write bytes
fs.Write(bytes, 0, 4);
}
///
/// Write uint to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, uint value)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(value);
// Write bytes
fs.Write(bytes, 0, 4);
}
///
/// Write long to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, long value)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(value);
// Write bytes
fs.Write(bytes, 0, 8);
}
///
/// Write float to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, float value)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(value);
// Write bytes
fs.Write(bytes, 0, 4);
}
///
/// Write float array to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, float[] val)
{
// Write all floats
for (int i = 0; i < val.Length; i++)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(val[i]);
// Write bytes
fs.Write(bytes, 0, 4);
}
}
///
/// Write double to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, double val)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(val);
// Write bytes
fs.Write(bytes, 0, 8);
}
///
/// Write DateTime to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, DateTime val)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(val.ToBinary());
// Write bytes
fs.Write(bytes, 0, 8);
}
///
/// Write Guid to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, Guid val)
{
// Convert to bytes
byte[] bytes = val.ToByteArray();
// Write bytes
fs.Write(bytes, 0, 16);
}
///
/// Write array of Guids to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, Guid[] val)
{
// Check size
if (val == null || val.Length < 1)
{
// No Guids
fs.Write(0);
}
else
{
// Write length
fs.Write(val.Length);
// Write all Guids
for (int i = 0; i < val.Length; i++)
{
// Convert to bytes
byte[] bytes = val[i].ToByteArray();
// Write bytes
fs.Write(bytes, 0, 16);
}
}
}
///
/// Write TimeSpan to the stream
///
/// File stream
/// Value to write
public static void Write(this Stream fs, TimeSpan val)
{
// Convert to bytes
byte[] bytes = BitConverter.GetBytes(val.Ticks);
// Write bytes
fs.Write(bytes, 0, 8);
}
#endregion
#region Direct Read
///
/// Read string from the file
///
/// File stream
/// Length of the text
/// String
public static string ReadText(this Stream fs, int length)
{
// Read all bytes
string val = string.Empty;
while (fs.CanRead && length > 0)
{
// Read byte
int b = fs.ReadByte();
// Validate
if (b > 0)
{
// Add char to string
val += (char)b;
}
else
{
break;
}
length--;
}
// Return value
return val;
}
///
/// Read string(UTF-8) from the file
///
/// File stream
/// String
public static string ReadStringUTF8(this Stream fs)
{
// Read length
int len = fs.ReadInt();
// Check if no string
if (len == 0)
{
// Empty string
return string.Empty;
}
else
{
// Read all bytes
byte[] bytes = new byte[len];
fs.Read(bytes, 0, bytes.Length);
// Convert
return Encoding.UTF8.GetString(bytes);
}
}
///
/// Read string(UTF-8) from the file and restore offset
///
/// File stream
/// Offset to restore
/// String
public static string ReadStringUTF8(this Stream fs, byte offset)
{
// Read length
int len = fs.ReadInt();
// Check if no string
if (len <= 0)
{
// Empty string
return string.Empty;
}
else
{
// Read all bytes
byte[] bytes = new byte[len];
fs.Read(bytes, 0, bytes.Length);
// Restore offset
for (int i = 0; i < len; i++)
{
bytes[i] -= offset;
}
// Convert
return Encoding.UTF8.GetString(bytes);
}
}
///
/// Read bool from the file
///
/// File stream
/// bool
public static bool ReadBool(this Stream fs)
{
// Read byte
return fs.ReadByte() == 1;
}
///
/// Read short from the file
///
/// File stream
/// short
public static short ReadShort(this Stream fs)
{
// Read 2 bytes
byte[] bytes = new byte[2];
fs.Read(bytes, 0, 2);
// Return bytes converted
return BitConverter.ToInt16(bytes, 0);
}
///
/// Read ushort from the file
///
/// File stream
/// ushort
public static ushort ReadUShort(this Stream fs)
{
// Read 2 bytes
byte[] bytes = new byte[2];
fs.Read(bytes, 0, 2);
// Return bytes converted
return BitConverter.ToUInt16(bytes, 0);
}
///
/// Read int from the file
///
/// File stream
/// int
public static int ReadInt(this Stream fs)
{
// Read 4 bytes
byte[] bytes = new byte[4];
fs.Read(bytes, 0, 4);
// Return bytes converted
return BitConverter.ToInt32(bytes, 0);
}
///
/// Read uint from the file
///
/// File stream
/// uint
public static uint ReadUInt(this Stream fs)
{
// Read 4 bytes
byte[] bytes = new byte[4];
fs.Read(bytes, 0, 4);
// Return bytes converted
return BitConverter.ToUInt32(bytes, 0);
}
///
/// Read ulong from the file
///
/// File stream
/// ulong
public static ulong ReadULong(this Stream fs)
{
// Read 8 bytes
byte[] bytes = new byte[8];
fs.Read(bytes, 0, 8);
// Return bytes converted
return BitConverter.ToUInt64(bytes, 0);
}
///
/// Read long from the file
///
/// File stream
/// long
public static long ReadLong(this Stream fs)
{
// Read 8 bytes
byte[] bytes = new byte[8];
fs.Read(bytes, 0, 8);
// Return bytes converted
return BitConverter.ToInt64(bytes, 0);
}
///
/// Read float from the file
///
/// File stream
/// float
public static unsafe float ReadFloat(this Stream fs)
{
// Read 4 bytes
byte[] bytes = new byte[4];
fs.Read(bytes, 0, 4);
// Convert into float
fixed (byte* p = bytes)
{
return *((float*)p);
}
}
///
/// Read array of floats from the file
///
/// File stream
/// Array size
/// float array
public static unsafe float[] ReadFloats(this Stream fs, uint size)
{
// Create arrays
float[] val = new float[size];
byte[] bytes = new byte[4];
// Read all floats
for (int i = 0; i < size; i++)
{
// Read 4 bytes
fs.Read(bytes, 0, 4);
// Convert into float
fixed (byte* p = bytes)
{
val[i] = *((float*)p);
}
}
// Return
return val;
}
///
/// Read double from the file
///
/// File stream
/// double
public static double ReadDouble(this Stream fs)
{
// Read 8 bytes
byte[] bytes = new byte[8];
fs.Read(bytes, 0, 8);
// Return bytes converted
return BitConverter.ToDouble(bytes, 0);
}
///
/// Read DateTime from the file
///
/// File stream
/// DateTime
public static DateTime ReadDateTime(this Stream fs)
{
// Read 8 bytes
byte[] bytes = new byte[8];
fs.Read(bytes, 0, 8);
// Return bytes converted
return DateTime.FromBinary(BitConverter.ToInt64(bytes, 0));
}
///
/// Read Guid from the file
///
/// File stream
/// Guid
public static Guid ReadGuid(this Stream fs)
{
// Read 16 bytes
byte[] bytes = new byte[16];
fs.Read(bytes, 0, 16);
// Return created Guid
return new Guid(bytes);
}
///
/// Read array of Guids from the file
///
/// File stream
/// Guids
public static Guid[] ReadGuids(this Stream fs)
{
// Read size
int len = fs.ReadInt();
// Check if can read more
Guid[] res;
if (len > 0)
{
// Create array
res = new Guid[len];
// Read all
for (int i = 0; i < len; i++)
{
// Read 16 bytes
byte[] bytes = new byte[16];
fs.Read(bytes, 0, 16);
// Create Guid
res[i] = new Guid(bytes);
}
}
else
{
// No Guids
res = new Guid[0];
}
// Return
return res;
}
///
/// Read TimeSpan from the file
///
/// File stream
/// TimeSpan
public static TimeSpan ReadTimeSpan(this Stream fs)
{
// Read 8 bytes
byte[] bytes = new byte[8];
fs.Read(bytes, 0, 8);
// Return bytes converted
return new TimeSpan(BitConverter.ToInt64(bytes, 0));
}
#endregion
}
}