157 lines
3.6 KiB
C#
157 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.IO;
|
|
|
|
namespace BizHawk.Emulation.DiscSystem
|
|
{
|
|
/// <summary>
|
|
/// Representation of a directory in the file system.
|
|
/// </summary>
|
|
public class ISODirectoryNode : ISONode
|
|
{
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// The children in this directory.
|
|
/// </summary>
|
|
public Dictionary<string, ISONode> Children;
|
|
|
|
#endregion
|
|
|
|
#region Construction
|
|
|
|
/// <summary>
|
|
/// Constructor.
|
|
/// </summary>
|
|
/// <param name="record">The node for this directory.</param>
|
|
public ISODirectoryNode(ISONodeRecord record)
|
|
: base(record)
|
|
{
|
|
this.Children = new Dictionary<string, ISONode>();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Parsing
|
|
|
|
/// <summary>
|
|
/// Parse the children based on the data in this directory.
|
|
/// </summary>
|
|
/// <param name="s">The stream to parse from.</param>
|
|
/// <param name="visited">The set of already handled
|
|
/// files/directories.</param>
|
|
public void Parse(Stream s, Dictionary<long, ISONode> visited)
|
|
{
|
|
// Go to the beginning of the set of directories
|
|
s.Seek(this.Offset * ISOFile.SECTOR_SIZE, SeekOrigin.Begin);
|
|
|
|
List<ISONodeRecord> records = new List<ISONodeRecord>();
|
|
|
|
// Read the directory entries
|
|
while (s.Position < ((this.Offset * ISOFile.SECTOR_SIZE) + this.Length))
|
|
{
|
|
ISONode node;
|
|
ISONodeRecord record;
|
|
|
|
// Read the record
|
|
record = new ISONodeRecord();
|
|
record.Parse(s);
|
|
|
|
|
|
//zero 24-jun-2013 - improved validity checks
|
|
//theres nothing here!
|
|
if (record.Length == 0)
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// Check if we already have this node
|
|
if (visited.ContainsKey(record.OffsetOfData))
|
|
{
|
|
// Get the node
|
|
node = visited[record.OffsetOfData];
|
|
}
|
|
else
|
|
{
|
|
// Create the node from the record
|
|
if (record.IsFile())
|
|
{
|
|
node = new ISOFileNode(record);
|
|
}
|
|
else if (record.IsDirectory())
|
|
{
|
|
node = new ISODirectoryNode(record);
|
|
}
|
|
else
|
|
{
|
|
node = new ISONode(record);
|
|
}
|
|
|
|
// Keep track that we've now seen the node and are parsing it
|
|
visited.Add(node.Offset, node);
|
|
}
|
|
|
|
// Add the node as a child
|
|
this.Children.Add(record.Name, node);
|
|
}
|
|
}
|
|
|
|
long currentPosition = s.Position;
|
|
|
|
// Iterate over directories...
|
|
foreach (KeyValuePair<string, ISONode> child in this.Children)
|
|
{
|
|
// Parse this node
|
|
if (child.Key != ISONodeRecord.CURRENT_DIRECTORY &&
|
|
child.Key != ISONodeRecord.PARENT_DIRECTORY &&
|
|
child.Value is ISODirectoryNode)
|
|
{
|
|
((ISODirectoryNode)child.Value).Parse(s, visited);
|
|
}
|
|
}
|
|
|
|
s.Seek(currentPosition, SeekOrigin.Begin);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Printing
|
|
|
|
/// <summary>
|
|
/// Print out this node's children.
|
|
/// </summary>
|
|
/// <param name="depth">The number of "tabs" to indent this directory.</param>
|
|
public void Print(int depth)
|
|
{
|
|
// Get the tabs string
|
|
string tabs = "";
|
|
for (int i = 0; i < depth; i++)
|
|
{
|
|
tabs += " ";
|
|
}
|
|
|
|
// Get the names and sort
|
|
string[] names = this.Children.Keys.ToArray();
|
|
Array.Sort(names);
|
|
|
|
// Print the directory names recursively
|
|
foreach (string s in names)
|
|
{
|
|
ISONode n = this.Children[s];
|
|
Console.WriteLine(tabs + s);
|
|
if (s != ISONodeRecord.CURRENT_DIRECTORY &&
|
|
s != ISONodeRecord.PARENT_DIRECTORY &&
|
|
n is ISODirectoryNode)
|
|
{
|
|
((ISODirectoryNode)n).Print(depth + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|