// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; using System.IO; using osu.Game.Storyboards; namespace osu.Game.Beatmaps.Formats { public abstract class Decoder { private static readonly Dictionary beatmapDecoders = new Dictionary(); private static readonly Dictionary storyboardDecoders = new Dictionary(); static Decoder() { LegacyDecoder.Register(); } /// /// Retrieves a to parse s. /// /// A stream pointing to the to retrieve the version from. public static Decoder GetBeatmapDecoder(StreamReader stream) { string line = readFirstLine(stream); if (line == null || !beatmapDecoders.ContainsKey(line)) throw new IOException(@"Unknown file format"); return (Decoder)Activator.CreateInstance(beatmapDecoders[line], line); } /// /// Retrieves a to parse s. /// /// A stream pointing to the to retrieve the version from. public static Decoder GetStoryboardDecoder(StreamReader stream) { string line = readFirstLine(stream); if (line == null || !storyboardDecoders.ContainsKey(line)) throw new IOException(@"Unknown file format"); return (Decoder)Activator.CreateInstance(storyboardDecoders[line], line); } private static string readFirstLine(StreamReader stream) { if (stream == null) throw new ArgumentNullException(nameof(stream)); string line; do { line = stream.ReadLine()?.Trim(); } while (line != null && line.Length == 0); return line; } /// /// Adds the to the list of and decoder. /// /// Type to decode a with. /// /// Type to decode a with. /// A string representation of the version. protected static void AddDecoder(string version) where A : Decoder where B : Decoder { beatmapDecoders[version] = typeof(A); storyboardDecoders[version] = typeof(B); } /// /// Adds the to the list of decoder. /// /// Type to decode a with. /// A string representation of the version. protected static void AddBeatmapDecoder(string version) where T : Decoder { beatmapDecoders[version] = typeof(T); } /// /// Adds the to the list of decoder. /// /// Type to decode a with. /// A string representation of the version. protected static void AddStoryboardDecoder(string version) where T : Decoder { storyboardDecoders[version] = typeof(T); } public virtual Beatmap DecodeBeatmap(StreamReader stream) => ParseBeatmap(stream); protected virtual Beatmap ParseBeatmap(StreamReader stream) { var beatmap = new Beatmap { BeatmapInfo = new BeatmapInfo { Metadata = new BeatmapMetadata(), BaseDifficulty = new BeatmapDifficulty(), }, }; ParseBeatmap(stream, beatmap); return beatmap; } protected abstract void ParseBeatmap(StreamReader stream, Beatmap beatmap); public virtual Storyboard DecodeStoryboard(StreamReader stream) { var storyboard = new Storyboard(); ParseStoryboard(stream, storyboard); return storyboard; } protected abstract void ParseStoryboard(StreamReader stream, Storyboard storyboard); } }