static void TestVirtualFileSystem() { try { Random r = new Random(); SlowDisk disk = new SlowDisk(1); disk.TurnOn(); VirtualFS vfs = new VirtualFS(); vfs.Format(disk); vfs.Mount(disk, "/"); VirtualNode root = vfs.RootNode; VirtualNode dir1 = root.CreateDirectoryNode("dir1"); VirtualNode dir2 = root.CreateDirectoryNode("dir2"); VirtualNode file1 = dir1.CreateFileNode("file1"); TestFileWriteRead(file1, r, 0, 100); TestFileWriteRead(file1, r, 0, 500); TestFileWriteRead(file1, r, 250, 100); vfs.Unmount("/"); vfs.Mount(disk, "/"); RescursivelyPrintNodes(vfs.RootNode); disk.TurnOff(); } catch (Exception ex) { Console.WriteLine("VFS test failed: " + ex.Message); } }
public void Move(VirtualNode destination) { if (destination != null) { if (destination.mParent == null) { throw new Exception("Can't move root node"); } if (destination.mSector.Type == SECTOR.SectorType.DIR_NODE) { //move this node to destination destination.LoadChildren(); destination.mChildren[Name] = this; destination.CommitChildren(); //remove this node from old mParent.LoadChildren(); mParent.mChildren.Remove(Name); mParent.CommitChildren(); //set new parent this.mParent = destination; } else { throw new Exception("Cannot move to not dir node"); } } else { throw new Exception("Cannot move to null VirtualNode"); } }
public FSEntry Find(string path) { //parse the path string[] source = path.TrimEnd(new char[] { PathSeparator }).Split(new char[] { PathSeparator }); //get root node VirtualNode matchNode = mVirtualFileSystem.RootNode; //loop over each path element searching for it in each virtualnode. Return null if not found at one step. foreach (string current in source.Skip(1)) { matchNode = matchNode.GetChild(current); if (matchNode == null) { //doesnt exist return(null); } } FSEntry result; if (matchNode.IsDirectory) { result = new SimpleDirectory(matchNode); } else { result = new SimpleFile(matchNode); } return(result); }
public VirtualNode(VirtualDrive drive, int nodeSector, NODE sector, VirtualNode parent) { mDrive = drive; mNodeSector = nodeSector; mSector = sector; mParent = parent; mChildren = null; mBlocks = null; }
private static void TestFileWriteRead(VirtualNode file, Random r, int index, int length) { byte[] towrite = CreateTestBytes(r, length); file.Write(index, towrite); byte[] toread = file.Read(index, length); if (!Compare(towrite, toread)) { throw new Exception("File read/write at " + index + " for " + length + " bytes, failed for file " + file.Name); } }
public void Unmount(string mountPoint) { if (!mDrives.ContainsKey(mountPoint)) { throw new Exception("No drive mounted at mountpoint " + mountPoint); } VirtualDrive virtualDrive = mDrives[mountPoint]; if (mRootNode.Drive == virtualDrive) { mRootNode = null; } mDrives.Remove(mountPoint); }
private static void RescursivelyPrintNodes(VirtualNode node, string indent = "") { Console.Write(indent + node.Name); if (node.IsFile) { Console.WriteLine(" <file, len=" + node.FileLength.ToString() + ">"); } else if (node.IsDirectory) { Console.WriteLine(" <directory>"); foreach (VirtualNode child in node.GetChildren()) { RescursivelyPrintNodes(child, indent + " "); } } }
private VirtualNode CommonMake(string name, bool makeFile = true) { if (mSector.Type != SECTOR.SectorType.DIR_NODE) { throw new Exception($"Cannot create Dir/File under node type " + mSector.Type.ToString()); } LoadChildren(); if (mChildren.ContainsKey(name)) { throw new Exception("Name already in use!"); } int[] nextFreeSectors = mDrive.GetNextFreeSectors(2); int nodeAddr = nextFreeSectors[0]; int dataAddr = nextFreeSectors[1]; NODE newNode = null; if (makeFile) { newNode = new FILE_NODE(mDrive.Disk.BytesPerSector, dataAddr, name, 0); } else { newNode = new DIR_NODE(mDrive.Disk.BytesPerSector, dataAddr, name, 0); } DATA_SECTOR dirdata = new DATA_SECTOR(mDrive.Disk.BytesPerSector, 0, null); mDrive.Disk.WriteSector(nodeAddr, newNode.RawBytes); mDrive.Disk.WriteSector(dataAddr, dirdata.RawBytes); VirtualNode child = new VirtualNode(mDrive, nodeAddr, newNode, this); mChildren[name] = child; CommitChildren(); return(child); }
public void Mount(DiskDriver disk, string mountPoint) { if (mDrives.Count == 0 && mountPoint.Length != 1 && mountPoint[0] != '/') { throw new Exception("First disk must be mounted at the root"); } //add virtual drive DRIVE_INFO driveInfo = DRIVE_INFO.CreateFromBytes(disk.ReadSector(Constants.DRIVE_INFO_SECTOR)); VirtualDrive newDrive = new VirtualDrive(disk, Constants.DRIVE_INFO_SECTOR, driveInfo); mDrives.Add(mountPoint, newDrive); //add root dir, make node, add it int rootNodeAt = driveInfo.RootNodeAt; DIR_NODE newDriveRootDir = DIR_NODE.CreateFromBytes(disk.ReadSector(rootNodeAt)); VirtualNode virtualNode = new VirtualNode(newDrive, rootNodeAt, newDriveRootDir, null); if (mDrives.Count == 1) { mRootNode = virtualNode; } }
private void LoadChildren() { if (mChildren == null) { mChildren = new Dictionary <string, VirtualNode>(); DATA_SECTOR dirData = DATA_SECTOR.CreateFromBytes(mDrive.Disk.ReadSector(mSector.FirstDataAt)); int nChildren = (mSector as DIR_NODE).EntryCount; for (int i = 0; i < nChildren; i++) { //fetch address int childNodeAddress = BitConverter.ToInt32(dirData.DataBytes, i * 4); //read in child byte[] childRaw = Drive.Disk.ReadSector(childNodeAddress); NODE childNode = NODE.CreateFromBytes(childRaw); //store the node as virutal node child VirtualNode virtualNode = new VirtualNode(mDrive, childNodeAddress, childNode, this); mChildren[virtualNode.Name] = virtualNode; } } }
protected SimpleEntry(VirtualNode node) { this.mNode = node; }
public VirtualFS() { mDrives = new Dictionary <string, VirtualDrive>(); mRootNode = null; }
public SimpleDirectory(VirtualNode node) : base(node) { }