diff --git a/OpenRA.Game/FileFormats/AudLoader.cs b/OpenRA.Game/FileFormats/AudLoader.cs index 847223a85d..311b2a165f 100644 --- a/OpenRA.Game/FileFormats/AudLoader.cs +++ b/OpenRA.Game/FileFormats/AudLoader.cs @@ -125,12 +125,12 @@ namespace OpenRA.FileFormats sampleRate = s.ReadUInt16(); var dataSize = s.ReadInt32(); var outputSize = s.ReadInt32(); - var readFlag = s.ReadByte(); - var readFormat = s.ReadByte(); + var readFlag = s.ReadByte(); if (!Enum.IsDefined(typeof(SoundFlags), readFlag)) return false; + var readFormat = s.ReadByte(); if (!Enum.IsDefined(typeof(SoundFormat), readFormat)) return false; @@ -170,6 +170,7 @@ namespace OpenRA.FileFormats out int sampleRate) { channels = sampleBits = sampleRate = 0; + var position = stream.Position; try { @@ -182,11 +183,15 @@ namespace OpenRA.FileFormats // If not, it will simply return false so we know we can't use it. If it is, it will start // parsing the data without any further failsafes, which means that it will crash on corrupted files // (that end prematurely or otherwise don't conform to the specifications despite the headers being OK). - Log.Write("debug", "Failed to parse AUD file {0}. Error message:".F(fileName)); - Log.Write("debug", e.ToString()); + Log.Write("sound", "Failed to parse AUD file {0}. Error message:".F(fileName)); + Log.Write("sound", e.ToString()); rawData = null; return false; } + finally + { + stream.Position = position; + } channels = 1; sampleBits = 16; diff --git a/OpenRA.Game/FileFormats/VocLoader.cs b/OpenRA.Game/FileFormats/VocLoader.cs index a7c19f6235..2810dff310 100644 --- a/OpenRA.Game/FileFormats/VocLoader.cs +++ b/OpenRA.Game/FileFormats/VocLoader.cs @@ -19,6 +19,8 @@ namespace OpenRA.FileFormats { bool ISoundLoader.TryParseSound(Stream stream, string fileName, out byte[] rawData, out int channels, out int sampleBits, out int sampleRate) { + var position = stream.Position; + try { var vocStream = new VocStream(stream); @@ -33,6 +35,10 @@ namespace OpenRA.FileFormats channels = sampleBits = sampleRate = 0; return false; } + finally + { + stream.Position = position; + } return true; } diff --git a/OpenRA.Game/FileFormats/WavLoader.cs b/OpenRA.Game/FileFormats/WavLoader.cs index 3f7d3fba2a..c9e740c3ff 100644 --- a/OpenRA.Game/FileFormats/WavLoader.cs +++ b/OpenRA.Game/FileFormats/WavLoader.cs @@ -43,7 +43,6 @@ namespace OpenRA.FileFormats Format = s.ReadASCII(4); if (Format != "WAVE") return false; - while (s.Position < s.Length) { if ((s.Position & 1) == 1) @@ -57,8 +56,8 @@ namespace OpenRA.FileFormats AudioFormat = s.ReadInt16(); Type = (WaveType)AudioFormat; - if (Type != WaveType.Pcm && Type != WaveType.ImaAdpcm) - throw new NotSupportedException("Compression type is not supported."); + if (!Enum.IsDefined(typeof(WaveType), Type)) + throw new NotSupportedException("Compression type {0} is not supported.".F(AudioFormat)); Channels = s.ReadInt16(); SampleRate = s.ReadInt32(); @@ -69,24 +68,17 @@ namespace OpenRA.FileFormats s.ReadBytes(FmtChunkSize - 16); break; case "fact": - { - var chunkSize = s.ReadInt32(); - UncompressedSize = s.ReadInt32(); - s.ReadBytes(chunkSize - 4); - } - + var chunkSize = s.ReadInt32(); + UncompressedSize = s.ReadInt32(); + s.ReadBytes(chunkSize - 4); break; case "data": DataSize = s.ReadInt32(); RawOutput = s.ReadBytes(DataSize); break; default: - // Ignore unknown chunks - { - var chunkSize = s.ReadInt32(); - s.ReadBytes(chunkSize); - } - + var unknownChunkSize = s.ReadInt32(); + s.ReadBytes(unknownChunkSize); break; } } @@ -189,6 +181,7 @@ namespace OpenRA.FileFormats { rawData = null; channels = sampleBits = sampleRate = 0; + var position = stream.Position; try { @@ -201,10 +194,14 @@ namespace OpenRA.FileFormats // If not, it will simply return false so we know we can't use it. If it is, it will start // parsing the data without any further failsafes, which means that it will crash on corrupted files // (that end prematurely or otherwise don't conform to the specifications despite the headers being OK). - Log.Write("debug", "Failed to parse WAV file {0}. Error message:".F(fileName)); - Log.Write("debug", e.ToString()); + Log.Write("sound", "Failed to parse WAV file {0}. Error message:".F(fileName)); + Log.Write("sound", e.ToString()); return false; } + finally + { + stream.Position = position; + } rawData = RawOutput; channels = Channels; diff --git a/OpenRA.Game/Primitives/MergedStream.cs b/OpenRA.Game/Primitives/MergedStream.cs index e196af559e..72bb2a5e65 100644 --- a/OpenRA.Game/Primitives/MergedStream.cs +++ b/OpenRA.Game/Primitives/MergedStream.cs @@ -18,6 +18,7 @@ namespace OpenRA.Primitives public Stream Stream2 { get; set; } long VirtualLength { get; set; } + long position; public MergedStream(Stream stream1, Stream stream2) { @@ -35,8 +36,6 @@ namespace OpenRA.Primitives public override long Seek(long offset, SeekOrigin origin) { - var position = Position; - switch (origin) { case SeekOrigin.Begin: @@ -52,9 +51,9 @@ namespace OpenRA.Primitives } if (position >= Stream1.Length) - Position = Stream1.Length + Stream2.Seek(offset - Stream1.Length, SeekOrigin.Begin); + position = Stream1.Length + Stream2.Seek(offset - Stream1.Length, SeekOrigin.Begin); else - Position = Stream1.Seek(offset, SeekOrigin.Begin); + position = Stream1.Seek(offset, SeekOrigin.Begin); return position; } @@ -68,7 +67,7 @@ namespace OpenRA.Primitives { int bytesRead; - if (Position >= Stream1.Length) + if (position >= Stream1.Length) bytesRead = Stream2.Read(buffer, offset, count); else if (count > Stream1.Length) { @@ -78,14 +77,14 @@ namespace OpenRA.Primitives else bytesRead = Stream1.Read(buffer, offset, count); - Position += bytesRead; + position += bytesRead; return bytesRead; } public override void Write(byte[] buffer, int offset, int count) { - if (Position >= Stream1.Length) + if (position >= Stream1.Length) Stream2.Write(buffer, offset - (int)Stream1.Length, count); else Stream1.Write(buffer, offset, count); @@ -111,6 +110,10 @@ namespace OpenRA.Primitives get { return VirtualLength; } } - public override long Position { get; set; } + public override long Position + { + get { return position; } + set { Seek(value, SeekOrigin.Begin); } + } } } diff --git a/OpenRA.Game/Sound/Sound.cs b/OpenRA.Game/Sound/Sound.cs index c78e03b00b..2904219415 100644 --- a/OpenRA.Game/Sound/Sound.cs +++ b/OpenRA.Game/Sound/Sound.cs @@ -63,11 +63,8 @@ namespace OpenRA int sampleBits; int sampleRate; foreach (var loader in Game.ModData.SoundLoaders) - { - stream.Position = 0; if (loader.TryParseSound(stream, filename, out rawData, out channels, out sampleBits, out sampleRate)) return soundEngine.AddSoundSourceFromMemory(rawData, channels, sampleBits, sampleRate); - } throw new InvalidDataException(filename + " is not a valid sound file!"); }