You're breathtaking!
This commit is contained in:
323
Source/Tools/Flax.Stats/CodeFrame.cs
Normal file
323
Source/Tools/Flax.Stats/CodeFrame.cs
Normal file
@@ -0,0 +1,323 @@
|
||||
// Copyright (c) 2012-2020 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user