public Directory(Context context, Inode inode, MetadataRef inodeRef) : base(context, inode, inodeRef) { _dirInode = inode as IDirectoryInode; if (_dirInode == null) { throw new ArgumentException("Inode is not a directory", "inode"); } }
protected override File ConvertDirEntryToFile(DirectoryEntry dirEntry) { MetadataRef inodeRef = dirEntry.InodeReference; _context.InodeReader.SetPosition(inodeRef); Inode inode = Inode.Read(_context.InodeReader); if (dirEntry.IsSymlink) { return(new Symlink(_context, inode, inodeRef)); } else if (dirEntry.IsDirectory) { return(new Directory(_context, inode, inodeRef)); } else { return(new File(_context, inode, inodeRef)); } }
public int ReadFrom(byte[] buffer, int offset) { Magic = Utilities.ToUInt32LittleEndian(buffer, offset + 0); InodesCount = Utilities.ToUInt32LittleEndian(buffer, offset + 4); CreationTime = Utilities.DateTimeFromUnix(Utilities.ToUInt32LittleEndian(buffer, offset + 8)); BlockSize = Utilities.ToUInt32LittleEndian(buffer, offset + 12); FragmentsCount = Utilities.ToUInt32LittleEndian(buffer, offset + 16); Compression = Utilities.ToUInt16LittleEndian(buffer, offset + 20); BlockSizeLog2 = Utilities.ToUInt16LittleEndian(buffer, offset + 22); Flags = Utilities.ToUInt16LittleEndian(buffer, offset + 24); UidGidCount = Utilities.ToUInt16LittleEndian(buffer, offset + 26); MajorVersion = Utilities.ToUInt16LittleEndian(buffer, offset + 28); MinorVersion = Utilities.ToUInt16LittleEndian(buffer, offset + 30); RootInode = new MetadataRef(Utilities.ToInt64LittleEndian(buffer, offset + 32)); BytesUsed = Utilities.ToInt64LittleEndian(buffer, offset + 40); UidGidTableStart = Utilities.ToInt64LittleEndian(buffer, offset + 48); ExtendedAttrsTableStart = Utilities.ToInt64LittleEndian(buffer, offset + 56); InodeTableStart = Utilities.ToInt64LittleEndian(buffer, offset + 64); DirectoryTableStart = Utilities.ToInt64LittleEndian(buffer, offset + 72); FragmentTableStart = Utilities.ToInt64LittleEndian(buffer, offset + 80); LookupTableStart = Utilities.ToInt64LittleEndian(buffer, offset + 88); return(Size); }
public FileContentBuffer(Context context, RegularInode inode, MetadataRef inodeRef) { _context = context; _inode = inode; context.InodeReader.SetPosition(inodeRef); context.InodeReader.Skip(_inode.Size); int numBlocks = (int)(_inode.FileSize / _context.SuperBlock.BlockSize); if (_inode.FileSize % _context.SuperBlock.BlockSize != 0 && _inode.FragmentKey == InvalidFragmentKey) { ++numBlocks; } byte[] lengthData = new byte[numBlocks * 4]; context.InodeReader.Read(lengthData, 0, lengthData.Length); _blockLengths = new int[numBlocks]; for (int i = 0; i < numBlocks; ++i) { _blockLengths[i] = Utilities.ToInt32LittleEndian(lengthData, i * 4); } }
public File(Context context, Inode inode, MetadataRef inodeRef) { _context = context; _inode = inode; _inodeRef = inodeRef; }
public Symlink(Context context, Inode inode, MetadataRef inodeRef) : base(context, inode, inodeRef) { }
public void SetPosition(MetadataRef position) { SetPosition(position.Block, position.Offset); }
private void WriteDirectory(BuilderContext context) { MetadataRef startPos = context.DirectoryWriter.Position; int currentChild = 0; int numDirs = 0; while (currentChild < _children.Count) { long thisBlock = _children[currentChild].Node.InodeRef.Block; int firstInode = _children[currentChild].Node.InodeNumber; int count = 1; while (currentChild + count < _children.Count && _children[currentChild + count].Node.InodeRef.Block == thisBlock && _children[currentChild + count].Node.InodeNumber - firstInode < 0x7FFF) { ++count; } DirectoryHeader hdr = new DirectoryHeader() { Count = count - 1, InodeNumber = firstInode, StartBlock = (int)thisBlock }; hdr.WriteTo(context.IoBuffer, 0); context.DirectoryWriter.Write(context.IoBuffer, 0, hdr.Size); for (int i = 0; i < count; ++i) { Entry child = _children[currentChild + i]; DirectoryRecord record = new DirectoryRecord() { Offset = (ushort)child.Node.InodeRef.Offset, InodeNumber = (short)(child.Node.InodeNumber - firstInode), Type = child.Node.Inode.Type, Name = child.Name }; record.WriteTo(context.IoBuffer, 0); context.DirectoryWriter.Write(context.IoBuffer, 0, record.Size); if (child.Node.Inode.Type == InodeType.Directory || child.Node.Inode.Type == InodeType.ExtendedDirectory) { ++numDirs; } } currentChild += count; } long size = context.DirectoryWriter.DistanceFrom(startPos); if (size > uint.MaxValue) { throw new NotImplementedException("Writing large directories"); } NumLinks = numDirs + 2; // +1 for self, +1 for parent _inode.StartBlock = (uint)startPos.Block; _inode.Offset = (ushort)startPos.Offset; _inode.FileSize = (uint)size + 3; // For some reason, always +3 }
internal long DistanceFrom(MetadataRef startPos) { return(((_currentBlockNum - startPos.Block) * VfsSquashFileSystemReader.MetadataBufferSize) + (_currentOffset - startPos.Offset)); }