public void Append() { const int APPEND_LENGTH = 16; var stream = Bio.RandomStream(APPEND_LENGTH); concatenated.Position = stream1.Length; concatenated.Append(stream); Assert.AreEqual(combinedLength + APPEND_LENGTH, concatenated.Length); Assert.AreEqual(concatenated.Position, stream1.Length); Assert.IsTrue(stream.IsEqualTo(concatenated.ExtractFrom(combinedLength))); }
/// <inheritdoc/> public HashResult HashZippedBeatmap(string zipPath, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(zipPath)) { throw new ArgumentNullException(nameof(zipPath)); } if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } bool missingDiffs = false; string?message = null; if (!File.Exists(zipPath)) { return(new HashResult(null, $"File doesn't exist: '{zipPath}'", new FileNotFoundException($"File doesn't exist: '{zipPath}'"))); } ZipArchive?zip = null; try { try { zip = ZipFile.OpenRead(zipPath); } catch (Exception ex) { return(new HashResult(null, $"Unable to hash beatmap zip '{zipPath}': {ex.Message}", ex)); } ZipArchiveEntry?infoFile = zip.Entries.FirstOrDefault(e => e.FullName.Equals("info.dat", StringComparison.OrdinalIgnoreCase)); if (infoFile == null) { return(new HashResult(null, $"Could not find 'info.dat' file in '{zipPath}'", null)); } JObject?token = null; using (Stream info = infoFile.Open()) using (StreamReader reader = new StreamReader(info)) using (JsonTextReader jsonReader = new JsonTextReader(reader)) { token = JsonSerializer.Deserialize <JObject>(jsonReader); } if (token == null) { return(new HashResult(null, $"Could not read 'info.dat' file in '{zipPath}'", null)); } if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } using Stream infoStream = infoFile.Open(); string[] beatmapFiles = Utilities.GetDifficultyFileNames(token).ToArray(); using ConcatenatedStream streams = new ConcatenatedStream(beatmapFiles.Length + 1); streams.Append(infoStream); for (int i = 0; i < beatmapFiles.Length; i++) { if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } ZipArchiveEntry?diff = zip.Entries.FirstOrDefault(e => e.FullName.Equals(beatmapFiles[i], StringComparison.OrdinalIgnoreCase)); if (diff == null) { if (missingDiffs == false) { message = $"Could not find difficulty file '{beatmapFiles[i]}' in '{zipPath}'"; } else { message = $"Missing multiple difficulty files in '{zipPath}'"; } missingDiffs = true; continue; } streams.Append(diff.Open()); } if (cancellationToken.IsCancellationRequested) { return(HashResult.AsCanceled); } string?hash = null; if (streams.StreamCount > 0) { hash = Utilities.CreateSha1FromStream(streams); } return(new HashResult(hash, message, null)); } catch (Exception ex) { return(new HashResult(null, $"Error hashing '{zipPath}'", ex)); } finally { zip?.Dispose(); } }