Remove Flax.Stats project
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
@@ -1,323 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Flax.Stats
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents single Code Frame captured to the file
|
||||
/// </summary>
|
||||
public sealed class CodeFrame : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Root node for code frames
|
||||
/// </summary>
|
||||
public CodeFrameNode Root;
|
||||
|
||||
/// <summary>
|
||||
/// Code frame date
|
||||
/// </summary>
|
||||
public DateTime Date;
|
||||
|
||||
/// <summary>
|
||||
/// Capture code stats in current working directory
|
||||
/// </summary>
|
||||
/// <param name="directory">Directory path to capture</param>
|
||||
/// <returns>Created code frame</returns>
|
||||
public static CodeFrame Capture(string directory)
|
||||
{
|
||||
// Create code frame
|
||||
var frame = new CodeFrame();
|
||||
|
||||
// Create root node and all children
|
||||
frame.Root = CodeFrameNode.Capture(new DirectoryInfo(directory));
|
||||
|
||||
// Save capture time
|
||||
frame.Date = DateTime.Now;
|
||||
|
||||
// Return result
|
||||
return frame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load code frame from the file
|
||||
/// </summary>
|
||||
/// <param name="path">Path of the file to load</param>
|
||||
/// <returns>Loaded code frame</returns>
|
||||
public static CodeFrame Load(string path)
|
||||
{
|
||||
// Create and load
|
||||
var frame = new CodeFrame();
|
||||
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
frame.load(fs);
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
private void load(Stream stream)
|
||||
{
|
||||
// Clear state
|
||||
if (Root != null)
|
||||
{
|
||||
Root.Dispose();
|
||||
Root = null;
|
||||
}
|
||||
|
||||
// Header
|
||||
if (stream.ReadInt() != 1032)
|
||||
{
|
||||
throw new FileLoadException("Invalid Code Frame file.");
|
||||
}
|
||||
|
||||
// Version
|
||||
int version = stream.ReadInt();
|
||||
|
||||
// Switch version
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
// Read root node
|
||||
Root = loadNode1(stream);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2:
|
||||
{
|
||||
// Read date
|
||||
Date = stream.ReadDateTime();
|
||||
|
||||
// Read root node
|
||||
Root = loadNode1(stream);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
// Read date
|
||||
Date = stream.ReadDateTime();
|
||||
|
||||
// Read root node
|
||||
Root = loadNode3(stream);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
// Read date
|
||||
Date = stream.ReadDateTime();
|
||||
|
||||
// Read root node
|
||||
Root = loadNode4(stream);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new FileLoadException("Unknown Code Frame file version.");
|
||||
}
|
||||
|
||||
// Ending char
|
||||
if(stream.ReadByte() != 99)
|
||||
{
|
||||
throw new FileLoadException("Code Frame file. is corrupted");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save to the file
|
||||
/// </summary>
|
||||
/// <param name="path">File path</param>
|
||||
public void Save(string path)
|
||||
{
|
||||
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||
{
|
||||
Save(fs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save to the stream
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream to write to</param>
|
||||
private void Save(Stream stream)
|
||||
{
|
||||
// Header
|
||||
stream.Write(1032);
|
||||
|
||||
// Version
|
||||
stream.Write(4);
|
||||
|
||||
// Date
|
||||
stream.Write(Date);
|
||||
|
||||
// Write root node
|
||||
saveNode4(stream, Root);
|
||||
|
||||
// Ending char
|
||||
stream.WriteByte(99);
|
||||
}
|
||||
|
||||
#region Version 1 and 2
|
||||
|
||||
private void saveNode1(Stream stream, CodeFrameNode node)
|
||||
{
|
||||
// Save node data
|
||||
stream.Write(node.FilesCount);
|
||||
stream.Write(node.LinesOfCode[0]);
|
||||
stream.Write(node.LinesOfCode[1]);
|
||||
stream.WriteUTF8(node.ShortName, 13);
|
||||
stream.Write(node.SizeOnDisk);
|
||||
stream.Write(node.Children.Length);
|
||||
|
||||
// Save all child nodes
|
||||
for (int i = 0; i < node.Children.Length; i++)
|
||||
{
|
||||
saveNode1(stream, node.Children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private CodeFrameNode loadNode1(Stream stream)
|
||||
{
|
||||
// Load node data
|
||||
int files = stream.ReadInt();
|
||||
long[] lines =
|
||||
{
|
||||
stream.ReadLong(),
|
||||
stream.ReadLong(),
|
||||
0,
|
||||
0
|
||||
};
|
||||
string name = stream.ReadStringUTF8(13);
|
||||
long size = stream.ReadLong();
|
||||
int childrenCount = stream.ReadInt();
|
||||
|
||||
// Load all child nodes
|
||||
CodeFrameNode[] children = new CodeFrameNode[childrenCount];
|
||||
for (int i = 0; i < childrenCount; i++)
|
||||
{
|
||||
children[i] = loadNode1(stream);
|
||||
}
|
||||
|
||||
// Create node
|
||||
return new CodeFrameNode(name, files, lines, size, children);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Version 3
|
||||
|
||||
private void saveNode3(Stream stream, CodeFrameNode node)
|
||||
{
|
||||
// Save node data
|
||||
stream.Write(node.FilesCount);
|
||||
stream.Write(node.LinesOfCode[0]);
|
||||
stream.Write(node.LinesOfCode[1]);
|
||||
stream.Write(node.LinesOfCode[2]);
|
||||
stream.WriteUTF8(node.ShortName, 13);
|
||||
stream.Write(node.SizeOnDisk);
|
||||
stream.Write(node.Children.Length);
|
||||
|
||||
// Save all child nodes
|
||||
for (int i = 0; i < node.Children.Length; i++)
|
||||
{
|
||||
saveNode3(stream, node.Children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private CodeFrameNode loadNode3(Stream stream)
|
||||
{
|
||||
// Load node data
|
||||
int files = stream.ReadInt();
|
||||
long[] lines =
|
||||
{
|
||||
stream.ReadLong(),
|
||||
stream.ReadLong(),
|
||||
stream.ReadLong(),
|
||||
0,
|
||||
};
|
||||
string name = stream.ReadStringUTF8(13);
|
||||
long size = stream.ReadLong();
|
||||
int childrenCount = stream.ReadInt();
|
||||
|
||||
// Load all child nodes
|
||||
CodeFrameNode[] children = new CodeFrameNode[childrenCount];
|
||||
for (int i = 0; i < childrenCount; i++)
|
||||
{
|
||||
children[i] = loadNode3(stream);
|
||||
}
|
||||
|
||||
// Create node
|
||||
return new CodeFrameNode(name, files, lines, size, children);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Version 4
|
||||
|
||||
private void saveNode4(Stream stream, CodeFrameNode node)
|
||||
{
|
||||
// Save node data
|
||||
stream.Write(node.FilesCount);
|
||||
stream.Write(node.LinesOfCode[0]);
|
||||
stream.Write(node.LinesOfCode[1]);
|
||||
stream.Write(node.LinesOfCode[2]);
|
||||
stream.Write(node.LinesOfCode[3]);
|
||||
stream.WriteUTF8(node.ShortName, 13);
|
||||
stream.Write(node.SizeOnDisk);
|
||||
stream.Write(node.Children.Length);
|
||||
|
||||
// Save all child nodes
|
||||
for (int i = 0; i < node.Children.Length; i++)
|
||||
{
|
||||
saveNode3(stream, node.Children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private CodeFrameNode loadNode4(Stream stream)
|
||||
{
|
||||
// Load node data
|
||||
int files = stream.ReadInt();
|
||||
long[] lines =
|
||||
{
|
||||
stream.ReadLong(),
|
||||
stream.ReadLong(),
|
||||
stream.ReadLong(),
|
||||
stream.ReadLong()
|
||||
};
|
||||
string name = stream.ReadStringUTF8(13);
|
||||
long size = stream.ReadLong();
|
||||
int childrenCount = stream.ReadInt();
|
||||
|
||||
// Load all child nodes
|
||||
CodeFrameNode[] children = new CodeFrameNode[childrenCount];
|
||||
for (int i = 0; i < childrenCount; i++)
|
||||
{
|
||||
children[i] = loadNode3(stream);
|
||||
}
|
||||
|
||||
// Create node
|
||||
return new CodeFrameNode(name, files, lines, size, children);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Clean all data
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
// Dispose root
|
||||
if (Root != null)
|
||||
{
|
||||
Root.Dispose();
|
||||
Root = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Flax.Stats
|
||||
{
|
||||
/// <summary>
|
||||
/// Single code frame data
|
||||
/// </summary>
|
||||
public sealed class CodeFrameNode : IDisposable
|
||||
{
|
||||
private static string[] ignoredFolders = new[]
|
||||
{
|
||||
".vs",
|
||||
".git",
|
||||
"obj",
|
||||
"bin",
|
||||
"packages",
|
||||
"thirdparty",
|
||||
"3rdparty",
|
||||
"flaxdeps",
|
||||
"platforms",
|
||||
"flaxapi",
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Array with all child nodes
|
||||
/// </summary>
|
||||
public CodeFrameNode[] Children;
|
||||
|
||||
/// <summary>
|
||||
/// Amount of lines of code
|
||||
/// </summary>
|
||||
public long[] LinesOfCode;
|
||||
|
||||
/// <summary>
|
||||
/// Size of the node on the hard drive
|
||||
/// </summary>
|
||||
public long SizeOnDisk;
|
||||
|
||||
/// <summary>
|
||||
/// Amount of files
|
||||
/// </summary>
|
||||
public int FilesCount;
|
||||
|
||||
/// <summary>
|
||||
/// Short directory name
|
||||
/// </summary>
|
||||
public string ShortName;
|
||||
|
||||
/// <summary>
|
||||
/// Gets total amount of lines of code in that node and all child nodes
|
||||
/// </summary>
|
||||
public long TotalLinesOfCode
|
||||
{
|
||||
get
|
||||
{
|
||||
long result = 0;
|
||||
for (int i = 0; i < (int)Languages.Max; i++)
|
||||
{
|
||||
result += LinesOfCode[i];
|
||||
}
|
||||
for (int i = 0; i < Children.Length; i++)
|
||||
{
|
||||
result += Children[i].TotalLinesOfCode;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets total amount of memory used by that node and all child nodes
|
||||
/// </summary>
|
||||
public long TotalSizeOnDisk
|
||||
{
|
||||
get
|
||||
{
|
||||
long result = SizeOnDisk;
|
||||
for (int i = 0; i < Children.Length; i++)
|
||||
{
|
||||
result += Children[i].TotalSizeOnDisk;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets total amount of files used by that node and all child nodes
|
||||
/// </summary>
|
||||
public long TotalFiles
|
||||
{
|
||||
get
|
||||
{
|
||||
long result = FilesCount;
|
||||
for (int i = 0; i < Children.Length; i++)
|
||||
{
|
||||
result += Children[i].TotalFiles;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets code frame node with given index
|
||||
/// </summary>
|
||||
/// <param name="index">Code frame node index</param>
|
||||
/// <returns>Code frame node</returns>
|
||||
public CodeFrameNode this[int index]
|
||||
{
|
||||
get { return Children[index]; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets code frame node with given name
|
||||
/// </summary>
|
||||
/// <param name="name">Code frame node index</param>
|
||||
/// <returns>Code frame node</returns>
|
||||
public CodeFrameNode this[string name]
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int i = 0; i < Children.Length; i++)
|
||||
if (Children[i].ShortName == name)
|
||||
return Children[i];
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Init
|
||||
/// </summary>
|
||||
/// <param name="name">Directory name</param>
|
||||
/// <param name="filesCnt">Amount of files</param>
|
||||
/// <param name="lines">Lines of code</param>
|
||||
/// <param name="size">Size on disk</param>
|
||||
/// <param name="children">Child nodes</param>
|
||||
public CodeFrameNode(string name, int filesCnt, long[] lines, long size, CodeFrameNode[] children)
|
||||
{
|
||||
if(lines == null || lines.Length != (int)Languages.Max)
|
||||
throw new InvalidDataException();
|
||||
|
||||
ShortName = name;
|
||||
FilesCount = filesCnt;
|
||||
Children = children;
|
||||
LinesOfCode = lines;
|
||||
SizeOnDisk = size;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets total amount of lines of code per language
|
||||
/// </summary>
|
||||
/// <param name="language">Language</param>
|
||||
/// <returns>Result amount of lines</returns>
|
||||
public long GetTotalLinesOfCode(Languages language)
|
||||
{
|
||||
long result = 0;
|
||||
result += LinesOfCode[(int)language];
|
||||
for (int i = 0; i < Children.Length; i++)
|
||||
{
|
||||
result += Children[i].GetTotalLinesOfCode(language);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Capture data from the folder
|
||||
/// </summary>
|
||||
/// <param name="folder">Folder path to capture</param>
|
||||
/// <returns>Created code frame of null if cannot create that</returns>
|
||||
public static CodeFrameNode Capture(DirectoryInfo folder)
|
||||
{
|
||||
// Get all files from that folder
|
||||
FileInfo[] files;
|
||||
try
|
||||
{
|
||||
files = folder.GetFiles("*.*");
|
||||
}
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
MessageBox.Show(exception.Message);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Count data
|
||||
long[] lines = new long[(int)Languages.Max];
|
||||
for (int i = 0; i < (int)Languages.Max; i++)
|
||||
{
|
||||
lines[i] = 0;
|
||||
}
|
||||
long size = 0;
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
// Count files size
|
||||
size += files[i].Length;
|
||||
|
||||
// Get file type index
|
||||
int index = -1;
|
||||
switch (files[i].Extension)
|
||||
{
|
||||
// C++
|
||||
case ".h":
|
||||
case ".cpp":
|
||||
case ".cxx":
|
||||
case ".hpp":
|
||||
case ".hxx":
|
||||
case ".c":
|
||||
index = (int)Languages.Cpp;
|
||||
break;
|
||||
|
||||
// C#
|
||||
case ".cs":
|
||||
index = (int)Languages.CSharp;
|
||||
break;
|
||||
|
||||
// HLSL
|
||||
case ".hlsl":
|
||||
case ".shader":
|
||||
index = (int)Languages.Hlsl;
|
||||
break;
|
||||
}
|
||||
if (index == -1)
|
||||
continue;
|
||||
|
||||
// Count lines in the source file
|
||||
long ll = 1;
|
||||
using (StreamReader streamReader = new StreamReader(files[i].FullName))
|
||||
{
|
||||
while (streamReader.ReadLine() != null)
|
||||
{
|
||||
ll++;
|
||||
}
|
||||
}
|
||||
lines[index] += ll;
|
||||
}
|
||||
|
||||
// Get all directories
|
||||
DirectoryInfo[] directories = folder.GetDirectories();
|
||||
if (directories.Length == 0 && files.Length == 0)
|
||||
{
|
||||
// Empty folder
|
||||
return null;
|
||||
}
|
||||
|
||||
// Process child nodes
|
||||
List<CodeFrameNode> children = new List<CodeFrameNode>(directories.Length);
|
||||
for (int i = 0; i < directories.Length; i++)
|
||||
{
|
||||
// Validate name
|
||||
if(ignoredFolders.Contains(directories[i].Name.ToLower()))
|
||||
continue;
|
||||
|
||||
var child = Capture(directories[i]);
|
||||
if (child != null)
|
||||
{
|
||||
children.Add(child);
|
||||
}
|
||||
}
|
||||
|
||||
// Create node
|
||||
return new CodeFrameNode(folder.Name, files.Length, lines, size, children.ToArray());
|
||||
}
|
||||
|
||||
public void CleanupDirectories()
|
||||
{
|
||||
var child = Children.ToList();
|
||||
child.RemoveAll(e => ignoredFolders.Contains(e.ShortName.ToLower()));
|
||||
Children = child.ToArray();
|
||||
|
||||
foreach (var a in Children)
|
||||
{
|
||||
a.CleanupDirectories();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clean all data
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (Children != null)
|
||||
{
|
||||
// Clear
|
||||
for (int i = 0; i < Children.Length; i++)
|
||||
{
|
||||
Children[i].Dispose();
|
||||
}
|
||||
Children = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To string
|
||||
/// </summary>
|
||||
/// <returns>String</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ShortName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using Flax.Build;
|
||||
|
||||
/// <summary>
|
||||
/// Flax.Stats tool project build configuration.
|
||||
/// </summary>
|
||||
public class FlaxStatsTarget : Target
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public FlaxStatsTarget()
|
||||
{
|
||||
Name = ProjectName = OutputName = "Flax.Stats";
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
|
||||
Type = TargetType.DotNet;
|
||||
OutputType = TargetOutputType.Library;
|
||||
Platforms = new[]
|
||||
{
|
||||
TargetPlatform.Windows,
|
||||
TargetPlatform.Linux,
|
||||
TargetPlatform.Mac,
|
||||
};
|
||||
Configurations = new[]
|
||||
{
|
||||
TargetConfiguration.Debug,
|
||||
TargetConfiguration.Release,
|
||||
};
|
||||
CustomExternalProjectFilePath = System.IO.Path.Combine(FolderPath, "Flax.Stats.csproj");
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{E9B47E88-802C-45E4-BFF4-F05A6F991BC9}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Flax.Stats</RootNamespace>
|
||||
<AssemblyName>Flax.Stats</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<OutputPath>..\..\..\Binaries\Tools\</OutputPath>
|
||||
<DocumentationFile>..\..\..\Binaries\Tools\Flax.Stats.xml</DocumentationFile>
|
||||
<IntermediateOutputPath>..\..\..\Cache\Intermediate\Flax.Stats\Debug</IntermediateOutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>1</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<OutputPath>..\..\..\Binaries\Tools\</OutputPath>
|
||||
<DocumentationFile>..\..\..\Binaries\Tools\Flax.Stats.xml</DocumentationFile>
|
||||
<IntermediateOutputPath>..\..\..\Cache\Intermediate\Flax.Stats\Release</IntermediateOutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Windows.Forms.DataVisualization" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CodeFrame.cs" />
|
||||
<Compile Include="CodeFrameNode.cs" />
|
||||
<Compile Include="Form1.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Languages.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TaskType.cs" />
|
||||
<Compile Include="Tools.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
73
Source/Tools/Flax.Stats/Form1.Designer.cs
generated
73
Source/Tools/Flax.Stats/Form1.Designer.cs
generated
@@ -1,73 +0,0 @@
|
||||
namespace Flax.Stats
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
|
||||
System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
|
||||
System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
|
||||
this.chart1 = new System.Windows.Forms.DataVisualization.Charting.Chart();
|
||||
((System.ComponentModel.ISupportInitialize)(this.chart1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// chart1
|
||||
//
|
||||
chartArea1.Name = "ChartArea1";
|
||||
this.chart1.ChartAreas.Add(chartArea1);
|
||||
this.chart1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
legend1.Name = "Legend1";
|
||||
this.chart1.Legends.Add(legend1);
|
||||
this.chart1.Location = new System.Drawing.Point(0, 0);
|
||||
this.chart1.Name = "chart1";
|
||||
series1.ChartArea = "ChartArea1";
|
||||
series1.Legend = "Legend1";
|
||||
series1.Name = "TotalLines";
|
||||
this.chart1.Series.Add(series1);
|
||||
this.chart1.Size = new System.Drawing.Size(932, 508);
|
||||
this.chart1.TabIndex = 0;
|
||||
this.chart1.Text = "chart1";
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(932, 508);
|
||||
this.Controls.Add(this.chart1);
|
||||
this.Name = "Form1";
|
||||
this.Text = "Form1";
|
||||
((System.ComponentModel.ISupportInitialize)(this.chart1)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.DataVisualization.Charting.Chart chart1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.DataVisualization.Charting;
|
||||
|
||||
namespace Flax.Stats
|
||||
{
|
||||
internal partial class Form1 : Form
|
||||
{
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void SetSourceCode(List<CodeFrame> codeFrames, List<CodeFrame> apiCodeFrames)
|
||||
{
|
||||
var set = chart1.Series["TotalLines"];
|
||||
set.ChartType = SeriesChartType.Line;
|
||||
var firstApiFrame = apiCodeFrames.Count > 0 ? apiCodeFrames[0].Date : DateTime.MaxValue;
|
||||
|
||||
for (int i = 0; i < codeFrames.Count; i++)
|
||||
{
|
||||
var frame = codeFrames[i];
|
||||
var root = frame.Root;
|
||||
long total = 0;
|
||||
|
||||
// All frames before 2016-08-05 have Source folder named to Celelej in a project dir
|
||||
if (frame.Date < new DateTime(2016, 8, 5))
|
||||
{
|
||||
var sourceDir = root["Celelej"];
|
||||
total = sourceDir.TotalLinesOfCode;
|
||||
}
|
||||
else
|
||||
{
|
||||
var sourceDir = root["Source"];
|
||||
|
||||
// Check if frame is from Source
|
||||
if (sourceDir != null)
|
||||
{
|
||||
total = sourceDir.TotalLinesOfCode + root["Development"].TotalLinesOfCode +
|
||||
root["Tools"].TotalLinesOfCode;
|
||||
}
|
||||
|
||||
// Check if there was SourceAPI frame at that frame
|
||||
/*if (frame.Date >= firstApiFrame)
|
||||
{
|
||||
var apiFrame = apiCodeFrames.Find(e => Math.Abs((e.Date - frame.Date).TotalMinutes) < 2);
|
||||
if (apiFrame != null)
|
||||
total += apiFrame.Root.TotalLinesOfCode;
|
||||
}*/
|
||||
}
|
||||
|
||||
set.Points.AddXY(codeFrames[i].Date, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace Flax.Stats
|
||||
{
|
||||
/// <summary>
|
||||
/// Array with all source code languages
|
||||
/// </summary>
|
||||
public enum Languages : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// C++
|
||||
/// </summary>
|
||||
Cpp = 0,
|
||||
|
||||
/// <summary>
|
||||
/// C#
|
||||
/// </summary>
|
||||
CSharp = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Hlsl
|
||||
/// </summary>
|
||||
Hlsl = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Amount of languages
|
||||
/// </summary>
|
||||
Max = 4
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Flax.Stats
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
private const string ProjectRoot = @"C:\Flax\"; // TODO: could we detect it?
|
||||
|
||||
private struct StatsTarget
|
||||
{
|
||||
public string SourceFolder;
|
||||
public string StatsFolder;
|
||||
|
||||
public StatsTarget(string source, string stats)
|
||||
{
|
||||
SourceFolder = ProjectRoot + source;
|
||||
StatsFolder = ProjectRoot + @"Source\" + stats;
|
||||
|
||||
if (!Directory.Exists(SourceFolder))
|
||||
Directory.CreateDirectory(SourceFolder);
|
||||
if (!Directory.Exists(StatsFolder))
|
||||
Directory.CreateDirectory(StatsFolder);
|
||||
}
|
||||
}
|
||||
|
||||
private static StatsTarget Source = new StatsTarget("Source", @"Development\CodeStats");
|
||||
private static StatsTarget SourceAPI = new StatsTarget("Source\\FlaxAPI", @"Development\CodeStatsAPI");
|
||||
|
||||
private static string formatNum(long num)
|
||||
{
|
||||
return num.ToString("# ### ### ##0");
|
||||
}
|
||||
|
||||
private static string getLangStatsText(out long totalLines, params CodeFrame[] frames)
|
||||
{
|
||||
long linesCpp = 0, linesCSharp = 0, linesHlsl = 0;
|
||||
|
||||
for (int i = 0; i < frames.Length; i++)
|
||||
{
|
||||
var root = frames[i].Root;
|
||||
|
||||
linesCpp += root.GetTotalLinesOfCode(Languages.Cpp);
|
||||
linesCSharp += root.GetTotalLinesOfCode(Languages.CSharp);
|
||||
linesHlsl += root.GetTotalLinesOfCode(Languages.Hlsl);
|
||||
}
|
||||
|
||||
totalLines = linesCpp + linesCSharp + linesHlsl;
|
||||
|
||||
return string.Format(
|
||||
@"C++: {0}
|
||||
C#: {1}
|
||||
HLSL: {2}",
|
||||
formatNum(linesCpp),
|
||||
formatNum(linesCSharp),
|
||||
formatNum(linesHlsl)
|
||||
);
|
||||
}
|
||||
|
||||
private static void saveStatsInfo(CodeFrame source, CodeFrame sourceApi)
|
||||
{
|
||||
long totalLines;
|
||||
|
||||
string sourceStats = getLangStatsText(out totalLines, source);
|
||||
string sourceApiStats = getLangStatsText(out totalLines, sourceApi);
|
||||
string totalStats = getLangStatsText(out totalLines, source, sourceApi);
|
||||
|
||||
string path = Path.Combine(ProjectRoot, "Source\\Development", "Code Stats Summary.txt");
|
||||
File.WriteAllText(path,
|
||||
string.Format(
|
||||
@"Source:
|
||||
{0}
|
||||
|
||||
SourceAPI:
|
||||
{1}
|
||||
|
||||
Total:
|
||||
{2}
|
||||
|
||||
Total lines of code: {3}
|
||||
",
|
||||
sourceStats,
|
||||
sourceApiStats,
|
||||
totalStats,
|
||||
formatNum(totalLines)
|
||||
));
|
||||
}
|
||||
|
||||
public static int CompareFrames(CodeFrame x, CodeFrame y)
|
||||
{
|
||||
return x.Date.CompareTo(y.Date);
|
||||
}
|
||||
|
||||
private static void Peek()
|
||||
{
|
||||
// Peek code frames
|
||||
Environment.CurrentDirectory = Source.SourceFolder;
|
||||
CodeFrame sourceFrame = CodeFrame.Capture(Source.SourceFolder);
|
||||
CodeFrame sourceApiFrame = CodeFrame.Capture(SourceAPI.SourceFolder);
|
||||
|
||||
// Save frames
|
||||
var filename = "Stats_" + DateTime.Now.ToFilenameString() + ".dat";
|
||||
sourceFrame.Save(Path.Combine(Source.StatsFolder, filename));
|
||||
sourceApiFrame.Save(Path.Combine(SourceAPI.StatsFolder, filename));
|
||||
|
||||
// Update stats
|
||||
saveStatsInfo(sourceFrame, sourceApiFrame);
|
||||
}
|
||||
|
||||
private static void Clear()
|
||||
{
|
||||
}
|
||||
|
||||
private static void Show()
|
||||
{
|
||||
// Load all code frames
|
||||
const string filesFilter = "Stats_*.dat";
|
||||
string[] files = Directory.GetFiles(Source.StatsFolder, filesFilter);
|
||||
string[] filesApi = Directory.GetFiles(SourceAPI.StatsFolder, filesFilter);
|
||||
//
|
||||
List<CodeFrame> sourceCodeFrames = new List<CodeFrame>(files.Length);
|
||||
List<CodeFrame> sourceApiCodeFrames = new List<CodeFrame>(filesApi.Length);
|
||||
//
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
sourceCodeFrames.Add(CodeFrame.Load(files[i]));
|
||||
for (int i = 0; i < filesApi.Length; i++)
|
||||
sourceApiCodeFrames.Add(CodeFrame.Load(filesApi[i]));
|
||||
|
||||
// Sort frames
|
||||
sourceCodeFrames.Sort(CompareFrames);
|
||||
sourceApiCodeFrames.Sort(CompareFrames);
|
||||
|
||||
// Show window
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Form1 f = new Form1();
|
||||
f.SetSourceCode(sourceCodeFrames, sourceApiCodeFrames);
|
||||
Application.Run(f);
|
||||
|
||||
// Clean data
|
||||
for (int i = 0; i < sourceCodeFrames.Count; i++)
|
||||
sourceCodeFrames[i].Dispose();
|
||||
for (int i = 0; i < sourceApiCodeFrames.Count; i++)
|
||||
sourceApiCodeFrames[i].Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The main entry point for the application
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
// Parse input arguments
|
||||
TaskType task = TaskType.Show;
|
||||
foreach (var s in args)
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case "peek":
|
||||
task = TaskType.Peek;
|
||||
break;
|
||||
case "clear":
|
||||
task = TaskType.Clear;
|
||||
break;
|
||||
default:
|
||||
MessageBox.Show("Unknown argument: " + s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Switch task
|
||||
switch (task)
|
||||
{
|
||||
case TaskType.Peek:
|
||||
Peek();
|
||||
break;
|
||||
case TaskType.Clear:
|
||||
Clear();
|
||||
break;
|
||||
default:
|
||||
Show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("Flax.Stats")]
|
||||
[assembly: AssemblyDescription("Code metrics tool")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Flax.Stats")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015-2017 Wojciech Figat")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: Guid("e9b47e88-802c-45e4-bff4-f05a6f991bc9")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace Flax.Stats
|
||||
{
|
||||
/// <summary>
|
||||
/// Code statistics app task types
|
||||
/// </summary>
|
||||
internal enum TaskType
|
||||
{
|
||||
/// <summary>
|
||||
/// By default just show code statistics
|
||||
/// </summary>
|
||||
Show = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Peek code stats to the database
|
||||
/// </summary>
|
||||
Peek,
|
||||
|
||||
/// <summary>
|
||||
/// Clear whole code statistics
|
||||
/// </summary>
|
||||
Clear,
|
||||
}
|
||||
}
|
||||
@@ -1,683 +0,0 @@
|
||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Flax.Stats
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains some useful functions
|
||||
/// </summary>
|
||||
public static class Tools
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts size of the file (in bytes) to the best fitting string
|
||||
/// </summary>
|
||||
/// <param name="bytes">Size of the file in bytes</param>
|
||||
/// <returns>The best fitting string of the file size</returns>
|
||||
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]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns date and time as 'good' for filenames string
|
||||
/// </summary>
|
||||
/// <returns>Date and Time</returns>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Write new line to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">Stream</param>
|
||||
public static void WriteLine(this Stream fs)
|
||||
{
|
||||
fs.WriteByte((byte)'\n');
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write text to the stream without '\0' char
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="data">Data to write</param>
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write char to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="data">Data to write</param>
|
||||
public static void Write(this Stream fs, char data)
|
||||
{
|
||||
// Write single byte
|
||||
fs.WriteByte((byte)data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string in UTF-8 encoding to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="data">Data to write</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write string in UTF-8 encoding to the stream and offset data
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="data">Data to write</param>
|
||||
/// <param name="offset">Offset to apply when writing data</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write bool to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="value">Value to write</param>
|
||||
public static void Write(this Stream fs, bool value)
|
||||
{
|
||||
// Write single byte
|
||||
fs.WriteByte((value) ? (byte)1 : (byte)0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write short to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="value">Value to write</param>
|
||||
public static void Write(this Stream fs, short value)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write ushort to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="value">Value to write</param>
|
||||
public static void Write(this Stream fs, ushort value)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write int to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="value">Value to write</param>
|
||||
public static void Write(this Stream fs, int value)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write uint to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="value">Value to write</param>
|
||||
public static void Write(this Stream fs, uint value)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write long to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="value">Value to write</param>
|
||||
public static void Write(this Stream fs, long value)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write float to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="value">Value to write</param>
|
||||
public static void Write(this Stream fs, float value)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write float array to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="val">Value to write</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write double to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="val">Value to write</param>
|
||||
public static void Write(this Stream fs, double val)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = BitConverter.GetBytes(val);
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 8);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write DateTime to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="val">Value to write</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write Guid to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="val">Value to write</param>
|
||||
public static void Write(this Stream fs, Guid val)
|
||||
{
|
||||
// Convert to bytes
|
||||
byte[] bytes = val.ToByteArray();
|
||||
|
||||
// Write bytes
|
||||
fs.Write(bytes, 0, 16);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write array of Guids to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="val">Value to write</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write TimeSpan to the stream
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="val">Value to write</param>
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
/// Read string from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="length">Length of the text</param>
|
||||
/// <returns>String</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string(UTF-8) from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>String</returns>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read string(UTF-8) from the file and restore offset
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="offset">Offset to restore</param>
|
||||
/// <returns>String</returns>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read bool from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>bool</returns>
|
||||
public static bool ReadBool(this Stream fs)
|
||||
{
|
||||
// Read byte
|
||||
return fs.ReadByte() == 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read short from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>short</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read ushort from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>ushort</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read int from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>int</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read uint from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>uint</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read ulong from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>ulong</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read long from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>long</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read float from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>float</returns>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read array of floats from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <param name="size">Array size</param>
|
||||
/// <returns>float array</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read double from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>double</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read DateTime from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>DateTime</returns>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read Guid from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>Guid</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read array of Guids from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>Guids</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read TimeSpan from the file
|
||||
/// </summary>
|
||||
/// <param name="fs">File stream</param>
|
||||
/// <returns>TimeSpan</returns>
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user