/// <summary> /// Constructor. /// </summary> /// <param name="name">The entry Name.</param> /// <param name="length">The stream length.</param> /// <param name="dataOffset">Data offset.</param> /// <param name="sectors">The sectors.</param> /// <param name="fat">The FAT.</param> public StreamEntry(string name, long length, Sect dataOffset, SectorCollection sectors, Sect[] fat) : base(name) { _length = length; _data = new byte[length]; if(!dataOffset.IsEndOfChain) { int left = (int)length; MemoryStream stream = new MemoryStream(_data); Sect sect = dataOffset; do { try { StorageSector sector = (StorageSector)sectors[sect]; int toWrite = Math.Min(sector.Data.Length, left); Debug.Assert(toWrite <= 512); stream.Write(sector.Data, 0, toWrite); left -= toWrite; sect = fat[sect.ToInt()]; } catch(Exception err) { Debug.WriteLine("Stream name is " + name); Debug.WriteLine(err.Message); Debug.WriteLine(err.StackTrace); return; } } while(!sect.IsEndOfChain); Debug.Assert(left == 0); Debug.Assert(stream.Length == stream.Position); } }
private void Init(Stream stream) { // stream size sanity checker // compound files are always blocks of 512 bytes Debug.Assert((stream.Length % 512) == 0); // read in the first sector StorageSector sector = new StorageSector(stream); // interpret sector as header sector HeaderSector header = new HeaderSector(sector.GetStream()); // read in all remaining sectors SectorCollection sectors = new SectorCollection((int)(stream.Length / Constants.SECTOR_SIZE)); while (stream.Position != stream.Length) { sector = new StorageSector(stream); sectors.Add(sector); } // build the fat index List <Sect> index = new List <Sect>((int)(Constants.MAX_SECT * header.SectFatCount)); // read first 109 fat entries for (int i = 0; i < header.SectFat.Length; ++i) { Sect fatSect = header.SectFat[i]; if (!fatSect.IsFree) { FatSector fat = new FatSector(((StorageSector)sectors[fatSect]).GetStream()); index.AddRange(fat.SectFat); sectors[fatSect] = fat; } } // read remaining fat entries int difCount; Sect difIndex; for (difIndex = header.SectDifStart, difCount = 0; !difIndex.IsEndOfChain && difCount < header.SectDifCount; ++difCount) { DifSector dif = new DifSector(((StorageSector)sectors[difIndex]).GetStream()); sectors[difIndex] = dif; for (int i = 0; i < dif.SectFat.Length; ++i) { Sect fatSect = dif.SectFat[i]; if (!fatSect.IsFree) { FatSector fat = new FatSector(((StorageSector)sectors[fatSect]).GetStream()); index.AddRange(fat.SectFat); sectors[fatSect] = fat; } } difIndex = dif.NextDif; } Debug.Assert(difCount == header.SectDifCount); // read in mini fat sectors Debug.Assert(index.Count == (header.SectFatCount * Constants.MAX_SECT)); Debug.Assert(index.Capacity == index.Count); Sect[] fatSects = index.ToArray(); Sect miniFatSect; int miniFatCount; for (miniFatSect = header.SectMiniFatStart, miniFatCount = 0; !miniFatSect.IsEndOfChain && miniFatCount < header.SectMiniFatCount; miniFatSect = fatSects[miniFatSect.ToInt()], ++miniFatCount) { MiniFatSector miniFat = new MiniFatSector(((StorageSector)sectors[miniFatSect]).GetStream()); sectors[miniFatSect] = miniFat; } Debug.Assert(miniFatCount == header.SectMiniFatCount); // read in directory sectors DirectorySectorEntryCollection dirs = new DirectorySectorEntryCollection(); for (Sect dirSect = header.SectDirStart; !dirSect.IsEndOfChain; dirSect = fatSects[dirSect.ToInt()]) { DirectorySector dir = new DirectorySector(((StorageSector)sectors[dirSect]).GetStream()); foreach (DirectorySectorEntry entry in dir.Entries) { dirs.Add(entry); } sectors[dirSect] = dir; } _directory = new Directory(dirs, sectors, fatSects); }