コード例 #1
0
        public VirtualNode CreateFileNode(string name)
        {
            if (!IsDirectory)
            {
                throw new Exception("Must be a directory to create children!");
            }

            // read current list of children
            LoadChildren();

            // Find the first two FREE_SECTORs on the disk
            int[] freeSectors = drive.GetNextFreeSectors(2);

            // allocate a new FILE_NODE and DATA_SECTOR on the disk

            //FILE_NODE
            FILE_NODE fileSector = new FILE_NODE(drive.Disk.BytesPerSector, freeSectors[1], name, 0);

            drive.Disk.WriteSector(freeSectors[0], fileSector.RawBytes);

            //DATA_SECTOR
            DATA_SECTOR dataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, new byte[] { 0 });

            drive.Disk.WriteSector(freeSectors[1], dataSector.RawBytes);

            // Create a new virtual node
            VirtualNode newNode = new VirtualNode(drive, freeSectors[0], fileSector, this);

            // Add it to its parent
            children.Add(name, newNode);

            CommitChildren();

            return(newNode);
        }
コード例 #2
0
        public void Unmount(string mountPoint)
        {
            // look up the drive and remove it's mountPoint
            if (!drives.ContainsKey(mountPoint))
            {
                throw new Exception("Cannot unmount drive that has not been mounted!");
            }

            // Remove from the drive list
            VirtualDrive vd = drives[mountPoint];

            drives.Remove(mountPoint);

            // Check if this drive was the first mounted drive...
            if (mountPoint == FSConstants.ROOT_DIR_NAME)
            {
                // If mounted first drive, blank out the root node
                rootNode = null;
            }
            else
            {
                // else it;s a2nd, 3rd, etc...
                // TODO: extra credit
            }
        }
コード例 #3
0
        public void Move(VirtualNode destination)
        {
            // remove this node from it's current parent and attach it to the new one
            // update the directory information for both parents on disk

            // Don't try and move the root!
            if (parent == null)
            {
                throw new Exception("Can't Move the root!");
            }

            // Validate destination
            if (destination == null || !destination.IsDirectory)
            {
                throw new Exception("Invalid destination for Move!");
            }

            // Remove node from current parent
            parent.LoadChildren();
            parent.children.Remove(Name);
            parent.CommitChildren();

            // Set parent to new parent
            parent = destination;

            // Add node to new parent
            parent.LoadChildren();
            parent.children.Add(Name, this);
            parent.CommitChildren();
        }
コード例 #4
0
        public VirtualNode CreateFileNode(string name)
        {
            LoadChildren(); //insure child cached is full
            if (children.ContainsKey(name))
            {
                throw new Exception("Another child with that name already exists");
            }

            //where do we store new file? which sector?
            //find 2 free sectors

            int[] sectors             = drive.GetNextFreeSectors(2);
            int   newFileNodeSectorAt = sectors[0];
            int   newFileDataSectorAt = sectors[1];

            //creat new  on disk
            FILE_NODE newFileNodeSector = new FILE_NODE(drive.Disk.BytesPerSector, newFileDataSectorAt, name, 0);

            drive.Disk.WriteSector(newFileNodeSectorAt, newFileNodeSector.RawBytes);

            //creat a data sector for dir
            DATA_SECTOR newFileDataSector = new DATA_SECTOR(drive.Disk.BytesPerSector, 0, null);

            drive.Disk.WriteSector(newFileDataSectorAt, newFileDataSector.RawBytes);

            //creat virtual node
            VirtualNode newFile = new VirtualNode(drive, newFileNodeSectorAt, newFileNodeSector, this);

            //add dir to parent
            children.Add(name, newFile);
            CommitChildren();

            return(newFile);
        }
コード例 #5
0
 public void Delete()
 {
     node.Delete();
     node = null;
     // TODO: Deal with null nodes in the rest f the logial file systems objects
     // e.g. Move()
 }
コード例 #6
0
        private void LoadChildren()
        {
            //test if we already have everything in cache?
            if (children != null)
            {
                return;
            }

            //create empty cache
            children = new Dictionary <string, VirtualNode>();

            //read this dir's data sector
            DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(DataSectorAt));

            //create virtual nodes for each child and add to children dictionary
            byte[] data = dataSector.DataBytes;

            for (int i = 0; i < ChildCount; i++)
            {
                int childAt = BitConverter.ToInt32(data, i * 4);

                NODE childNodeSector = NODE.CreateFromBytes(drive.Disk.ReadSector(childAt));

                VirtualNode childNode = new VirtualNode(drive, childAt, childNodeSector, this);
                children.Add(childNode.Name, childNode);
            }
        }
コード例 #7
0
        public FSEntry Find(string path)
        {
            // good:  /foo/bar, /foo/bar/
            // bad:  foo, foo/bar, //foo/bar, /foo//bar, /foo/../foo/bar
            VirtualNode current = virtualFileSystem.RootNode;

            string[] elements = path.Split(PATH_SEPARATOR);

            foreach (string element in elements.Skip(1))
            {
                VirtualNode child = current.GetChild(element);
                if (child != null)
                {
                    current = child;
                }
                else
                {
                    return(null);
                }
            }

            FSEntry result = null;

            if (current.IsDirectory)
            {
                result = new SimpleDirectory(current);
            }
            else
            {
                result = new SimpleFile(current);
            }

            return(result);
        }
コード例 #8
0
        public FSEntry Find(string path)
        {
            // good:  /foo/bar, /foo/bar/
            // bad:  foo, foo/bar, //foo/bar, /foo//bar, /foo/../foo/bar

            // Make sure path starts correctly
            if (path.Length <= 0 || path[0] != PATH_SEPARATOR)
            {
                //Console.WriteLine("invalid path");
                return(null);
            }
            if (path.Length == 1)
            {
                return(new SimpleDirectory(virtualFileSystem.RootNode));
            }
            try
            {
                string[]    elements    = path.Split(PATH_SEPARATOR);
                VirtualNode currentNode = virtualFileSystem.RootNode;

                for (int i = 1; i < elements.Length; i++)
                {
                    if (currentNode.IsFile)
                    {
                        //Console.WriteLine("File, not directory");
                        return(null);
                    }
                    else
                    {
                        if (elements[i].Length != 0)
                        {
                            // Check if valid child
                            currentNode = currentNode.GetChild(elements[i]);
                            if (currentNode == null)
                            {
                                //Console.WriteLine("can't find child...");
                                return(null);
                            }
                        }
                        else
                        {
                            // Allow trailing path separator
                            if (i < elements.Length - 1)
                            {
                                //Console.WriteLine("empty path element!");
                                return(null);
                            }
                        }
                    }
                }

                return(currentNode.IsDirectory ? (FSEntry) new SimpleDirectory(currentNode) : new SimpleFile(currentNode));
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught exception in simplefs.find(): " + ex.Message);
            }

            return(null);
        }
コード例 #9
0
        private List <VirtualBlock> blocks;                 // cache of file blocks

        public VirtualNode(VirtualDrive drive, int nodeSector, NODE sector, VirtualNode parent)
        {
            this.drive      = drive;
            this.nodeSector = nodeSector;
            this.sector     = sector;
            this.parent     = parent;
            this.children   = null;                         // initially empty cache
            this.blocks     = null;                         // initially empty cache
        }
コード例 #10
0
        public void Unmount(string mountPoint)
        {
            // remove drive mountPoint and root node

            drives.Remove(mountPoint);

            //rework for when multiples drives are mounted *look up by mount point
            rootNode = null;
        }
コード例 #11
0
        public FSEntry Find(string path)
        {
            // Follow the path down and return a ne directory or file
            // wrapping the node
            // Path must be an absolute path, including the root /
            // Simplifying assumption... not allowing ".." or "." in our paths
            // good:  /foo/bar, /foo/bar/
            // bad:  foo, foo/bar, //foo/bar, /foo//bar, /foo/../foo/bar
            if (String.IsNullOrEmpty(path) || path[0] != '/')
            {
                throw new Exception("Hey! Invalid path!");
            }

            // If path ends in a trailing slash, then...
            bool mustBeDirectory = false;

            if (path.EndsWith(PATH_SEPARATOR.ToString()))
            {
                // Remove the trailing slash and remember that we expect a directory
                path            = path.Substring(0, path.Length - 1);
                mustBeDirectory = true;
            }

            // Walk through path and find the result
            string[]    elements = path.Split(PATH_SEPARATOR);
            VirtualNode current  = virtualFileSystem.RootNode;

            foreach (string element in elements.Skip(1))    // Skips the first blank
            {
                // We need to dig deeper, but we do not have a directory, so return null
                if (!current.IsDirectory)
                {
                    return(null);
                }

                try
                {
                    // Get the named child from the directory
                    VirtualNode child = current.GetChild(element);
                    current = child;
                }
                catch (Exception)
                {
                    // If we can't find the child, return null
                    return(null);
                }
            }

            if (mustBeDirectory && !current.IsDirectory)
            {
                return(null);
            }

            return(current.IsDirectory ? new SimpleDirectory(current) as FSEntry : new SimpleFile(current));
        }
コード例 #12
0
        public void Move(VirtualNode destination)
        {
            // remove this node from it's current parent and attach it to it's new parent
            // update the directory information for both parents on disk
            VirtualNode currentParent = parent;

            parent.LoadChildren();
            parent.children.Remove(Name);
            destination.LoadChildren();
            destination.children.Add(Name, this);

            parent = destination;
            currentParent.CommitChildren();
            destination.CommitChildren();
        }
コード例 #13
0
        private void LoadChildren()
        {
            // Ensure that the children cache is correctly put in memory (i.e. reflects what's on the disk)
            // Assume if the cache exsists, it is correct at the moment
            // So, we need to call CommitChildren()
            if (children == null)
            {
                // Create the cache itself
                children = new Dictionary <string, VirtualNode>();

                // Read the list of children for this directory from disk
                // Instantiate a VirtualNode for each [child?] and add them to the children cache.
                // Read the data sector for this directory
                DATA_SECTOR dataSector = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(sector.FirstDataAt));
                // Extract the list of children from the sata sector
                byte[] rawList = dataSector.DataBytes;

                // Foreach child in the list...
                for (int i = 0; i < ChildCount; i++)
                {
                    // Getthe child's sector address
                    int childSectorAt = BitConverter.ToInt32(rawList, i * 4);

                    // Read its sector from disk
                    // Check if it's a file or directory
                    byte[] childNodeBytes = drive.Disk.ReadSector(childSectorAt);
                    NODE   childSector;
                    if (SECTOR.GetTypeFromBytes(childNodeBytes) == SECTOR.SectorType.DIR_NODE)
                    {
                        childSector = DIR_NODE.CreateFromBytes(drive.Disk.ReadSector(childSectorAt));
                    }
                    else if (SECTOR.GetTypeFromBytes(childNodeBytes) == SECTOR.SectorType.FILE_NODE)
                    {
                        childSector = FILE_NODE.CreateFromBytes(drive.Disk.ReadSector(childSectorAt));
                    }
                    else
                    {
                        throw new Exception("Unexpected sector type whe reading directory's children!");
                    }

                    // Construct a VirtualNode
                    VirtualNode childNode = new VirtualNode(drive, childSectorAt, childSector, this);

                    // Add the VirtualNode to the children cache
                    children.Add(childNode.Name, childNode);
                }
            }
        }
コード例 #14
0
        private VirtualNode CreateNode(string name, SECTOR.SectorType type)
        {
            // Create a new file, both on disk and in memory
            // type may be DIR_NODE or FILE_NODE

            if (type != SECTOR.SectorType.DIR_NODE && type != SECTOR.SectorType.FILE_NODE)
            {
                throw new Exception("Illegal type, CreateNode only take DIR_NODE and FILE_NODE types!");
            }

            // Get 2 free sectors
            // First Sector: NODE, containing metadata
            // Second Sector: DATA_SECTOR, containing the new node's data
            int[] freeSectors = drive.GetNextFreeSectors(2);
            if (freeSectors == null || freeSectors.Length != 2)
            {
                throw new Exception("Can't find 2 free sectors for a new " +
                                    (type == SECTOR.SectorType.DIR_NODE ? "directory" : "file") + "!");
            }
            int newNodeAt       = freeSectors[0];
            int newDataSectorAt = freeSectors[1];

            // Create the node sector on disk, initially empty
            int  bps     = drive.Disk.BytesPerSector;
            NODE newNode = (type == SECTOR.SectorType.DIR_NODE
                ? new DIR_NODE(bps, newDataSectorAt, name, 0) as NODE
                : new FILE_NODE(bps, newDataSectorAt, name, 0) as NODE);

            //Create the DATA_SECTOR sector on disk for the new directory
            // initially empty data sector for this new directory
            DATA_SECTOR dataSector = new DATA_SECTOR(bps, 0, null);

            // Write sectors to disk
            drive.Disk.WriteSector(newNodeAt, newNode.RawBytes);
            drive.Disk.WriteSector(newDataSectorAt, dataSector.RawBytes);

            // Create a new VirtualNode instance
            VirtualNode newVirtualNode = new VirtualNode(drive, newNodeAt, newNode, this);

            // Add this to the in-memory cache of this directory's children
            LoadChildren();
            children.Add(name, newVirtualNode);
            CommitChildren();

            // Return the new VirtualNode instace
            return(newVirtualNode);
        }
コード例 #15
0
        private void LoadChildren()
        {
            if (children == null)
            {
                children = new Dictionary <string, VirtualNode>();
                DATA_SECTOR data = DATA_SECTOR.CreateFromBytes(drive.Disk.ReadSector(sector.FirstDataAt));

                for (int i = 0; i < ChildCount; i++)
                {
                    int childAddress = BitConverter.ToInt32(data.DataBytes, i * 4);

                    NODE childSector = NODE.CreateFromBytes(drive.Disk.ReadSector(childAddress));

                    VirtualNode vn = new VirtualNode(drive, childAddress, childSector, this);
                    children.Add(childSector.Name, vn);
                }
            }
        }
コード例 #16
0
        public void Unmount(string mountPoint)
        {
            // look up the drive and remove it's mountPoint
            if (!drives.ContainsKey(mountPoint))
            {
                throw new Exception("No drive mounted at mount point: " + mountPoint);
            }

            // Unset root node if needed
            VirtualDrive drive = drives.Where(x => x.Key == mountPoint).FirstOrDefault().Value;

            if (rootNode.Drive == drive)
            {
                rootNode = null;
            }

            drives.Remove(mountPoint);
        }
コード例 #17
0
        public void Mount(DiskDriver disk, string mountPoint)
        {
            // for the first mounted drive, expect mountPoint to be named FSConstants.PATH_SEPARATOR as the root
            if (drives.Count == 0 && mountPoint != FSConstants.PATH_SEPARATOR.ToString())
            {
                throw new Exception("Expected first mounted dist to be at root directory!");
            }

            // read drive info from disk, load root node and connect to mountPoint

            DRIVE_INFO   driveInfo = DRIVE_INFO.CreateFromBytes(disk.ReadSector(DRIVE_INFO_SECTOR));
            VirtualDrive drive     = new VirtualDrive(disk, DRIVE_INFO_SECTOR, driveInfo);

            DIR_NODE rootSector = DIR_NODE.CreateFromBytes(disk.ReadSector(ROOT_DIR_SECTOR));

            rootNode = new VirtualNode(drive, ROOT_DIR_SECTOR, rootSector, null);

            drives.Add(mountPoint, drive);
        }
コード例 #18
0
        public void Move(VirtualNode destination)
        {
            // remove this node from it's current parent and attach it to it's new parent
            // update the directory information for both parents on disk

            if (!destination.IsDirectory)
            {
                throw new Exception("Destination must be a directory!");
            }

            destination.LoadChildren();
            destination.children.Add(Name, this);
            destination.CommitChildren();

            parent.LoadChildren();
            parent.children.Remove(Name);
            parent.CommitChildren();

            parent = destination;
        }
コード例 #19
0
        public void Mount(DiskDriver disk, string mountPoint)
        {
            // read drive info from disk, load root node and connect to mountPoint
            // for the first mounted drive, expect mountPoint to be named FSConstants.ROOT_DIR_NAME as the root

            //read drive info for disk to determin what sector contains its root node
            DRIVE_INFO diSector = DRIVE_INFO.CreateFromBytes(disk.ReadSector(DRIVE_INFO_SECTOR));

            int rootNodeAt = diSector.RootNodeAt;

            VirtualDrive drive = new VirtualDrive(disk, DRIVE_INFO_SECTOR, diSector);

            DIR_NODE rootNodeSector = DIR_NODE.CreateFromBytes(disk.ReadSector(rootNodeAt));

            if (rootNode == null)
            {
                rootNode = new VirtualNode(drive, rootNodeAt, rootNodeSector, null);
            }

            drives.Add(mountPoint, drive);
        }
コード例 #20
0
        public void Mount(DiskDriver disk, string mountPoint)
        {
            // read drive info from disk, load root node and connect to mountPoint
            // for the first mounted drive, expect mountPoint to be named "/", FSConstants.ROOT_DIR_NAME, as the root

            try
            {
                // Step 1: Read infor from the disk to understand it's directory structure
                // Read DRIVE_INFO from FRIVE_INFO_SECTOR
                DRIVE_INFO  di = DRIVE_INFO.CreateFromBytes(disk.ReadSector(DRIVE_INFO_SECTOR));
                DIR_NODE    dn = DIR_NODE.CreateFromBytes(disk.ReadSector(di.RootNodeAt));
                DATA_SECTOR ds = DATA_SECTOR.CreateFromBytes(disk.ReadSector(dn.FirstDataAt));


                // Step 2: Join th new disk into the virtual file system structure, at the mount point.
                // Create a VistualDrive for the disk
                VirtualDrive vd = new VirtualDrive(disk, DRIVE_INFO_SECTOR, di);


                if (rootNode == null)
                {
                    // Create a VirtualNode to represent the root dictionaru, at the mount point.
                    // Set the VFS's root node, if this is the first disk to be mounted.
                    rootNode = new VirtualNode(vd, di.RootNodeAt, dn, null);
                }
                else
                {
                    // TODO: Extra Credit:  Handle 2nd dick mounted to exsisting VFS
                    // Create a virtual node for this new disk's root
                    // "join" the new node to the exsisting node structure at the mount point
                }

                // Add a new VirtualDrive to drives dictionary, using te mountPoint as the key
                drives.Add(mountPoint, vd);
            }
            catch (Exception ex)
            {
                throw new Exception("Failed to mount disk");
            }
        }
コード例 #21
0
 public void Close()
 {
     // Detatch the stream from the underlying file VirtualNode
     node = null;
 }
コード例 #22
0
 public VirtualFS()
 {
     this.drives   = new Dictionary <string, VirtualDrive>();
     this.rootNode = null;
 }
コード例 #23
0
 protected SimpleEntry(VirtualNode node)
 {
     this.node = node;
 }
コード例 #24
0
 public SimpleDirectory(VirtualNode node) : base(node)
 {
 }
コード例 #25
0
 public void Close()
 {
     //remove access to file node, prevent future read/write calls on this stream
     node = null;
 }
コード例 #26
0
 public SimpleStream(VirtualNode node)
 {
     this.node = node;
 }
コード例 #27
0
 public SimpleFile(VirtualNode node) : base(node)
 {
 }