static void Main(string[] args) { var child = ListenerFactory.CreateListener(ListenerFactory.ListenerType.Child); var zooKeper = ListenerFactory.CreateListener(ListenerFactory.ListenerType.ZooKeper); var enclosureBuilder1 = new EnclosureBuilder().AddAnimal(AnimalFactory.AnimalType.Bird, "Jaszczomp"); var enclosureBuilder2 = new EnclosureBuilder() .AddAnimal(AnimalFactory.AnimalType.Mammal, "Dzik") .AddAnimal(AnimalFactory.AnimalType.Reptile, "Wonsz"); var sectorBuilder1 = new SectorBuilder().AddEnclosure(enclosureBuilder1).AddEnclosure(enclosureBuilder2); var enclosure3 = new EnclosureBuilder().AddAnimal(AnimalFactory.AnimalType.Amphibia, "Aksolotl") .AddAnimal(AnimalFactory.AnimalType.Fish, "Halibut"); var enclosure4 = new EnclosureBuilder(); var sectorBuilder2 = new SectorBuilder().AddEnclosure(enclosure3).AddEnclosure(enclosure4); var zoo = new ZooBuilder().AddSector(sectorBuilder1).AddSector(sectorBuilder2).Build(); zoo.Humans.Add(child); zoo.Humans.Add(zooKeper); var animals = zoo.GetAnimals(); var visitor = new EmptyPartVisitor(); zoo.AcceptVisitor(visitor); var result = visitor.GetResult(); result.ForEach(r => Console.WriteLine(r.GetName() + " is empty")); animals.ForEach(a => a.AddListener(zooKeper)); animals.ForEach(z => { Console.WriteLine(z.Name); z.Eat(); z.Move(); }); Console.ReadLine(); }
public bool Open(IFilter imageFilter) { if (imageFilter == null) { return(false); } try { imageFilter.GetDataForkStream().Seek(0, SeekOrigin.Begin); _gdiStream = new StreamReader(imageFilter.GetDataForkStream()); int lineNumber = 0; bool highDensity = false; // Initialize all RegExs var regexTrack = new Regex(REGEX_TRACK); // Initialize all RegEx matches // Initialize disc _discImage = new GdiDisc { Sessions = new List <Session>(), Tracks = new List <GdiTrack>() }; ulong currentStart = 0; _offsetMap = new Dictionary <uint, ulong>(); _densitySeparationSectors = 0; while (_gdiStream.Peek() >= 0) { lineNumber++; string line = _gdiStream.ReadLine(); if (lineNumber == 1) { if (!int.TryParse(line, out _)) { throw new ImageNotSupportedException("Not a correct Dreamcast GDI image"); } } else { Match trackMatch = regexTrack.Match(line ?? throw new InvalidOperationException()); if (!trackMatch.Success) { throw new ImageNotSupportedException($"Unknown line \"{line}\" at line {lineNumber}"); } AaruConsole.DebugWriteLine("GDI plugin", "Found track {0} starts at {1} flags {2} type {3} file {4} offset {5} at line {6}", trackMatch.Groups["track"].Value, trackMatch.Groups["start"].Value, trackMatch.Groups["flags"].Value, trackMatch.Groups["type"].Value, trackMatch.Groups["filename"].Value, trackMatch.Groups["offset"].Value, lineNumber); var filtersList = new FiltersList(); var currentTrack = new GdiTrack { Bps = ushort.Parse(trackMatch.Groups["type"].Value), Flags = byte.Parse(trackMatch.Groups["flags"].Value), Offset = long.Parse(trackMatch.Groups["offset"].Value), Sequence = uint.Parse(trackMatch.Groups["track"].Value), StartSector = ulong.Parse(trackMatch.Groups["start"].Value), TrackFilter = filtersList.GetFilter(Path.Combine(imageFilter.GetParentFolder(), trackMatch.Groups["filename"].Value. Replace("\\\"", "\"").Trim('"'))) }; currentTrack.TrackFile = currentTrack.TrackFilter.GetFilename(); if (currentTrack.StartSector - currentStart > 0) { if (currentTrack.StartSector == 45000) { highDensity = true; _offsetMap.Add(0, currentStart); _densitySeparationSectors = currentTrack.StartSector - currentStart; currentStart = currentTrack.StartSector; } else { currentTrack.Pregap = currentTrack.StartSector - currentStart; currentTrack.StartSector -= currentTrack.StartSector - currentStart; } } if ((currentTrack.TrackFilter.GetDataForkLength() - currentTrack.Offset) % currentTrack.Bps != 0) { throw new ImageNotSupportedException("Track size not a multiple of sector size"); } currentTrack.Sectors = (ulong)((currentTrack.TrackFilter.GetDataForkLength() - currentTrack.Offset) / currentTrack.Bps); currentTrack.Sectors += currentTrack.Pregap; currentStart += currentTrack.Sectors; currentTrack.HighDensity = highDensity; currentTrack.TrackType = (currentTrack.Flags & 0x4) == 0x4 ? TrackType.CdMode1 : TrackType.Audio; _discImage.Tracks.Add(currentTrack); } } Session[] sessions = new Session[2]; for (int s = 0; s < sessions.Length; s++) { if (s == 0) { sessions[s].SessionSequence = 1; foreach (GdiTrack trk in _discImage.Tracks.Where(trk => !trk.HighDensity)) { if (sessions[s].StartTrack == 0) { sessions[s].StartTrack = trk.Sequence; } else if (sessions[s].StartTrack > trk.Sequence) { sessions[s].StartTrack = trk.Sequence; } if (sessions[s].EndTrack < trk.Sequence) { sessions[s].EndTrack = trk.Sequence; } if (sessions[s].StartSector > trk.StartSector) { sessions[s].StartSector = trk.StartSector; } if (sessions[s].EndSector < (trk.Sectors + trk.StartSector) - 1) { sessions[s].EndSector = (trk.Sectors + trk.StartSector) - 1; } } } else { sessions[s].SessionSequence = 2; foreach (GdiTrack trk in _discImage.Tracks.Where(trk => trk.HighDensity)) { if (sessions[s].StartTrack == 0) { sessions[s].StartTrack = trk.Sequence; } else if (sessions[s].StartTrack > trk.Sequence) { sessions[s].StartTrack = trk.Sequence; } if (sessions[s].EndTrack < trk.Sequence) { sessions[s].EndTrack = trk.Sequence; } if (sessions[s].StartSector > trk.StartSector) { sessions[s].StartSector = trk.StartSector; } if (sessions[s].EndSector < (trk.Sectors + trk.StartSector) - 1) { sessions[s].EndSector = (trk.Sectors + trk.StartSector) - 1; } } } } _discImage.Sessions.Add(sessions[0]); _discImage.Sessions.Add(sessions[1]); _discImage.Disktype = MediaType.GDROM; // DEBUG information AaruConsole.DebugWriteLine("GDI plugin", "Disc image parsing results"); AaruConsole.DebugWriteLine("GDI plugin", "Session information:"); AaruConsole.DebugWriteLine("GDI plugin", "\tDisc contains {0} sessions", _discImage.Sessions.Count); for (int i = 0; i < _discImage.Sessions.Count; i++) { AaruConsole.DebugWriteLine("GDI plugin", "\tSession {0} information:", i + 1); AaruConsole.DebugWriteLine("GDI plugin", "\t\tStarting track: {0}", _discImage.Sessions[i].StartTrack); AaruConsole.DebugWriteLine("GDI plugin", "\t\tStarting sector: {0}", _discImage.Sessions[i].StartSector); AaruConsole.DebugWriteLine("GDI plugin", "\t\tEnding track: {0}", _discImage.Sessions[i].EndTrack); AaruConsole.DebugWriteLine("GDI plugin", "\t\tEnding sector: {0}", _discImage.Sessions[i].EndSector); } AaruConsole.DebugWriteLine("GDI plugin", "Track information:"); AaruConsole.DebugWriteLine("GDI plugin", "\tDisc contains {0} tracks", _discImage.Tracks.Count); for (int i = 0; i < _discImage.Tracks.Count; i++) { AaruConsole.DebugWriteLine("GDI plugin", "\tTrack {0} information:", _discImage.Tracks[i].Sequence); AaruConsole.DebugWriteLine("GDI plugin", "\t\t{0} bytes per sector", _discImage.Tracks[i].Bps); AaruConsole.DebugWriteLine("GDI plugin", "\t\tPregap: {0} sectors", _discImage.Tracks[i].Pregap); if ((_discImage.Tracks[i].Flags & 0x8) == 0x8) { AaruConsole.DebugWriteLine("GDI plugin", "\t\tTrack is flagged as quadraphonic"); } if ((_discImage.Tracks[i].Flags & 0x4) == 0x4) { AaruConsole.DebugWriteLine("GDI plugin", "\t\tTrack is data"); } if ((_discImage.Tracks[i].Flags & 0x2) == 0x2) { AaruConsole.DebugWriteLine("GDI plugin", "\t\tTrack allows digital copy"); } if ((_discImage.Tracks[i].Flags & 0x1) == 0x1) { AaruConsole.DebugWriteLine("GDI plugin", "\t\tTrack has pre-emphasis applied"); } AaruConsole.DebugWriteLine("GDI plugin", "\t\tTrack resides in file {0}, type defined as {1}, starting at byte {2}", _discImage.Tracks[i].TrackFilter, _discImage.Tracks[i].TrackType, _discImage.Tracks[i].Offset); } AaruConsole.DebugWriteLine("GDI plugin", "Building offset map"); Partitions = new List <Partition>(); ulong byteOffset = 0; for (int i = 0; i < _discImage.Tracks.Count; i++) { if (_discImage.Tracks[i].Sequence == 1 && i != 0) { throw new ImageNotSupportedException("Unordered tracks"); } // Index 01 var partition = new Partition { Description = $"Track {_discImage.Tracks[i].Sequence}.", Name = null, Start = _discImage.Tracks[i].StartSector, Size = _discImage.Tracks[i].Sectors * _discImage.Tracks[i].Bps, Length = _discImage.Tracks[i].Sectors, Sequence = _discImage.Tracks[i].Sequence, Offset = byteOffset, Type = _discImage.Tracks[i].TrackType.ToString() }; byteOffset += partition.Size; _offsetMap.Add(_discImage.Tracks[i].Sequence, partition.Start); Partitions.Add(partition); } foreach (GdiTrack track in _discImage.Tracks) { _imageInfo.ImageSize += track.Bps * track.Sectors; } foreach (GdiTrack track in _discImage.Tracks) { _imageInfo.Sectors += track.Sectors; } _imageInfo.Sectors += _densitySeparationSectors; _imageInfo.SectorSize = 2352; // All others foreach (GdiTrack unused in _discImage.Tracks.Where(track => (track.Flags & 0x4) == 0x4 && track.Bps == 2352)) { _imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSync); _imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorHeader); _imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorSubHeader); _imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEcc); _imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEccP); _imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEccQ); _imageInfo.ReadableSectorTags.Add(SectorTagType.CdSectorEdc); } _imageInfo.CreationTime = imageFilter.GetCreationTime(); _imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); _imageInfo.MediaType = _discImage.Disktype; _imageInfo.ReadableSectorTags.Add(SectorTagType.CdTrackFlags); _imageInfo.XmlMediaType = XmlMediaType.OpticalDisc; AaruConsole.VerboseWriteLine("GDI image describes a disc of type {0}", _imageInfo.MediaType); _sectorBuilder = new SectorBuilder(); return(true); } catch (Exception ex) { AaruConsole.ErrorWriteLine("Exception trying to identify image file {0}", imageFilter.GetBasePath()); AaruConsole.ErrorWriteLine("Exception: {0}", ex.Message); AaruConsole.ErrorWriteLine("Stack trace: {0}", ex.StackTrace); return(false); } }