// 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 } }