public bool WriteStream(Stream fs, int StartCluster, int Filesize) { Log.Info("StartCluster:" + StartCluster.ToString()); int Size = Filesize; int c = StartCluster; while (true) { var s = c * ClusterPerSector; var LastSector = 0; for (var sc = 0; sc < ClusterPerSector; sc++, s++) { var Length = Size < DefaultSectorBytes ? Size : DefaultSectorBytes; DiskImage.GetSector(s).Fill(0x00); if (Size == 0) { continue; } var SectorBuffer = DiskImage.GetSectorDataForWrite(s); fs.Read(SectorBuffer, 0, Length); Size -= Length; if (Length > 0) { LastSector = sc; } } if (Size == 0) { if (Setting.X1SMode && LastSector > 0) { LastSector--; if ((Filesize & 0xff) == 0) { LastSector++; } } SetClusterValue(c, LastSector, true); break; } var next = GetNextFreeCluster(2); if (next < 0) { Log.Error($"Too big filesize!: LastClaster={c}"); SetClusterValue(c, LastSector, true); return(false); } SetClusterValue(c, next); c = next; } return(true); }
/// <summary> /// ファイル展開 /// </summary> public void ExtractFile(Stream fs, HuFileEntry fe) { int StartCluster = fe.StartCluster; int Size = fe.Size; bool AsciiMode = fe.IsAscii; int c = StartCluster; int LeftSize = Size; int TotalOutputBytes = 0; bool SectorWriteMode = Size == 0; if (Setting.ForceAsciiMode) { AsciiMode = true; } if (Setting.ForceBinaryMode) { AsciiMode = false; } while (true) { var end = IsEndCluster(c); var next = GetClusterValue(c); if (next == 0x00) { Log.Warning("WARNING: Wrong cluster chain!!"); break; } // セクタ数 var SectorCount = end ? (next & 0x0f) + 1 : ClusterPerSector; for (var i = 0; i < SectorCount; i++) { var CurrentSector = (c * ClusterPerSector) + i; var Sector = DiskImage.GetSector(CurrentSector); var Data = Sector.Data; var Eof = false; if (AsciiMode) { var AsciiData = ConvertAscii(Sector.Data); Eof = AsciiData.Eof; Data = AsciiData.Data; } Log.Verbose($"Cluster:{c} Sector:{CurrentSector} Position:0x{Sector.Position:X}"); var OutputBytes = Data.Length; // セクタ書き込みモード if (!SectorWriteMode) { // セクタサイズか残りのバイト数を書き出す if (LeftSize < OutputBytes) { OutputBytes = LeftSize; } LeftSize -= OutputBytes; } fs.Write(Data, 0, OutputBytes); TotalOutputBytes += OutputBytes; // 次のクラスタに進む if (Eof) { break; } } if (end) { break; } c = next; } }