private PFSDirectory parseDirectory(long dinode, PFSDirectory parent, string name) { if (dinodes == null) { throw new Exception("dinodes not set"); } var ret = new PFSDirectory(parent, name); foreach (long x in dinodes[dinode].db) { if (x <= 0) { continue; } _stream.Position = header.blocksz * x; while (_stream.Position < header.blocksz * (x + 1)) { var position = _stream.Position; var dirent = readDirent(); if (dirent.type == TYPE_FILE) { ret.AddFile(parseFile(dirent.ino, ret, dirent.name)); } else if (dirent.type == TYPE_DIR) { ret.AddDir(parseDirectory(dirent.ino, ret, dirent.name)); } else if (dirent.type == 0) { break; } _stream.Position = position + dirent.entsize; } } return(ret); }
private PFSFile parseFile(long dinode, PFSDirectory parent, string name) { return(new PFSFile(name, parent, _stream, dinodes[dinode].direct_blocks[0] * (long)header.blocksz, dinodes[dinode].size, dinode)); }
private PFSDirectory parseDirectory(long dinode, PFSDirectory parent, string name) { if (dinodes == null) { throw new Exception("dinodes not set"); } var ret = new PFSDirectory(parent, name); // TODO: In the future, if it turns out (in)direct blocks are used, // extract this to a method and use it for both files and dirs. IList <int> dataBlocks; if (dinodes[dinode].direct_blocks[1] == -1) { // PFS uses -1 to indicate that consecutive blocks are used. dataBlocks = new int[dinodes[dinode].blocks]; for (var i = 0; i < dataBlocks.Count; i++) { dataBlocks[i] = i + dinodes[dinode].direct_blocks[0]; } } else { dataBlocks = dinodes[dinode].direct_blocks; //TODO: Indirect blocks. I haven't seen these yet, maybe they would be // used if PFS is used for saves or something? } foreach (var x in dataBlocks) { if (x == 0) { break; } _stream.Position = header.blocksz * x; while (_stream.Position < header.blocksz * (x + 1)) { var position = _stream.Position; var dirent = readDirent(); if (dirent.type == TYPE_FILE) { ret.AddFile(parseFile(dirent.ino, ret, dirent.name)); } else if (dirent.type == TYPE_DIR) { ret.AddDir(parseDirectory(dirent.ino, ret, dirent.name)); } else if (dirent.type == 0) { break; } _stream.Position = position + dirent.entsize; } } return(ret); }