using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace BizHawk.Emulation.DiscSystem
{
///
/// Representation of a directory in the file system.
///
public class ISODirectoryNode : ISONode
{
#region Public Properties
///
/// The children in this directory.
///
public Dictionary Children;
#endregion
#region Construction
///
/// Constructor.
///
/// The node for this directory.
public ISODirectoryNode(ISONodeRecord record)
: base(record)
{
this.Children = new Dictionary();
}
#endregion
#region Parsing
///
/// Parse the children based on the data in this directory.
///
/// The stream to parse from.
/// The set of already handled
/// files/directories.
public void Parse(Stream s, Dictionary visited)
{
// Go to the beginning of the set of directories
s.Seek(this.Offset * ISOFile.SECTOR_SIZE, SeekOrigin.Begin);
List records = new List();
// Read the directory entries
while (s.Position < ((this.Offset * ISOFile.SECTOR_SIZE) + this.Length))
{
ISONode node;
ISONodeRecord record;
// Read the record
record = new ISONodeRecord();
if (ISOFile.Format == ISOFile.ISOFormat.CDInteractive)
record.ParseCDInteractive(s);
if (ISOFile.Format == ISOFile.ISOFormat.ISO9660)
record.ParseISO9660(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
if (!this.Children.ContainsKey(record.Name))
this.Children.Add(record.Name, node);
}
}
long currentPosition = s.Position;
// Iterate over directories...
foreach (KeyValuePair 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
///
/// Print out this node's children.
///
/// The number of "tabs" to indent this directory.
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
}
}