1 // Copyright 2020 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4
5 #include "DiscIO/ScrubbedBlob.h"
6
7 #include <algorithm>
8 #include <memory>
9 #include <string>
10 #include <utility>
11
12 #include "Common/Align.h"
13 #include "DiscIO/Blob.h"
14 #include "DiscIO/DiscScrubber.h"
15 #include "DiscIO/VolumeDisc.h"
16
17 namespace DiscIO
18 {
ScrubbedBlob(std::unique_ptr<BlobReader> blob_reader,DiscScrubber scrubber)19 ScrubbedBlob::ScrubbedBlob(std::unique_ptr<BlobReader> blob_reader, DiscScrubber scrubber)
20 : m_blob_reader(std::move(blob_reader)), m_scrubber(std::move(scrubber))
21 {
22 }
23
Create(const std::string & path)24 std::unique_ptr<ScrubbedBlob> ScrubbedBlob::Create(const std::string& path)
25 {
26 std::unique_ptr<VolumeDisc> disc = CreateDisc(path);
27 if (!disc)
28 return nullptr;
29
30 DiscScrubber scrubber;
31 if (!scrubber.SetupScrub(disc.get()))
32 return nullptr;
33
34 std::unique_ptr<BlobReader> blob = CreateBlobReader(path);
35 if (!blob)
36 return nullptr;
37
38 return std::unique_ptr<ScrubbedBlob>(new ScrubbedBlob(std::move(blob), std::move(scrubber)));
39 }
40
Read(u64 offset,u64 size,u8 * out_ptr)41 bool ScrubbedBlob::Read(u64 offset, u64 size, u8* out_ptr)
42 {
43 while (size > 0)
44 {
45 constexpr size_t CLUSTER_SIZE = DiscScrubber::CLUSTER_SIZE;
46 const u64 bytes_to_read =
47 std::min(Common::AlignDown(offset + CLUSTER_SIZE, CLUSTER_SIZE) - offset, size);
48
49 if (m_scrubber.CanBlockBeScrubbed(offset))
50 {
51 std::fill_n(out_ptr, bytes_to_read, 0);
52 }
53 else
54 {
55 if (!m_blob_reader->Read(offset, bytes_to_read, out_ptr))
56 return false;
57 }
58
59 offset += bytes_to_read;
60 size -= bytes_to_read;
61 out_ptr += bytes_to_read;
62 }
63
64 return true;
65 }
66
67 } // namespace DiscIO
68