示例#1
0
		/// <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);
			}
		}
示例#2
0
        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);
        }