Пример #1
0
        public override void List(out List <File> files, out List <File> dirs)
        {
            files      = new List <File>();
            dirs       = new List <File>();
            this.files = files;
            this.dirs  = dirs;

            Ext fs = (Ext)filesystem;

            if (Type == FileType.Directory)
            {
                Ext.INode inode = fs.GetINode(inode_number);
                Byte[]    block = new Byte[fs.BlockSize];

                if ((inode.flags & 0x80000) == 0)     // old, indirect blocks
                {
                    IndirectBlockIterator it = new IndirectBlockIterator(fs, inode.block);
                    while (it.ReadNextBlock(block))
                    {
                        AddFilesFromLinearBlock(block, files, dirs);   // dir hash present: ( inode.flags & 0x1000 ) != 0
                    }
                }
                else // extents
                {
                    ExtentBlockIterator it = new ExtentBlockIterator(fs, inode.block);
                    while (it.ReadNextBlock(block))
                    {
                        AddFilesFromLinearBlock(block, files, dirs);   // dir hash present: ( inode.flags & 0x1000 ) != 0
                    }
                }
            }
        }
Пример #2
0
        public override void Save(string path, BackgroundWorker worker)
        {
            List <File> files;
            List <File> dirs;

            if (worker != null)
            {
                worker.ReportProgress(0, path + "\\" + name);
            }

            List(out files, out dirs);

            if (type == FileType.Directory)
            {
                Directory.CreateDirectory(path + "\\" + name);

                foreach (File file in dirs)
                {
                    file.Save(path + "\\" + name, worker);

                    if (worker != null && worker.CancellationPending)
                    {
                        return;
                    }
                }
                foreach (File file in files)
                {
                    file.Save(path + "\\" + name, worker);

                    if (worker != null && worker.CancellationPending)
                    {
                        return;
                    }
                }

                if (worker != null)
                {
                    worker.ReportProgress(100);
                }
            }
            else if (type == FileType.File || type == FileType.Link)
            {
                Ext fs = (Ext)filesystem;

                Ext.INode inode = fs.GetINode(inode_number);
                Byte[]    block = new Byte[fs.BlockSize];

                FileStream stream = new FileStream(path + "\\" + name, FileMode.Create);

                if (type == FileType.Link && inode.size < 60)   // fast symlink
                {
                    Byte[] raw_inode_blocks = new Byte[60];
                    Utils.LoadByteArrayFromUInt32Array(raw_inode_blocks, inode.block, 15);
                    stream.Write(raw_inode_blocks, 0, (int)inode.size);
                }
                else // files, slow symlinks
                {
                    Int64 size_remaining = inode.size;
                    if ((inode.flags & 0x80000) == 0)     // old, indirect blocks
                    {
                        IndirectBlockIterator it = new IndirectBlockIterator(fs, inode.block);
                        while (it.ReadNextBlock(block))
                        {
                            if (size_remaining < fs.BlockSize)
                            {
                                stream.Write(block, 0, (int)size_remaining);
                                size_remaining = 0;
                            }
                            else
                            {
                                stream.Write(block, 0, (int)fs.BlockSize);
                                size_remaining -= fs.BlockSize;
                            }

                            if (worker != null)
                            {
                                worker.ReportProgress(100 - (int)(100 * size_remaining / inode.size));
                                if (worker.CancellationPending)
                                {
                                    stream.Close();
                                    return;
                                }
                            }
                        }
                    }
                    else // extents
                    {
                        ExtentBlockIterator it = new ExtentBlockIterator(fs, inode.block);
                        while (it.ReadNextBlock(block))
                        {
                            if (size_remaining < fs.BlockSize)
                            {
                                stream.Write(block, 0, (int)size_remaining);
                                size_remaining = 0;
                            }
                            else
                            {
                                stream.Write(block, 0, (int)fs.BlockSize);
                                size_remaining -= fs.BlockSize;
                            }

                            if (worker != null)
                            {
                                worker.ReportProgress(100 - (int)(100 * size_remaining / inode.size));
                                if (worker.CancellationPending)
                                {
                                    stream.Close();
                                    return;
                                }
                            }
                        }
                    }
                }

                stream.Close();
            }
        }