1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "cdm-test-storage.h"
7 #include <vector>
8
9 #include "mozilla/Assertions.h"
10 #include "mozilla/Attributes.h"
11
12 using namespace cdm;
13
14 class WriteRecordClient : public FileIOClient {
15 public:
WriteRecordClient(std::function<void ()> && aOnSuccess,std::function<void ()> && aOnFailure,const uint8_t * aData,uint32_t aDataSize)16 WriteRecordClient(std::function<void()>&& aOnSuccess,
17 std::function<void()>&& aOnFailure, const uint8_t* aData,
18 uint32_t aDataSize)
19 : mOnSuccess(move(aOnSuccess)), mOnFailure(move(aOnFailure)) {
20 mData.insert(mData.end(), aData, aData + aDataSize);
21 }
22
OnOpenComplete(Status aStatus)23 void OnOpenComplete(Status aStatus) override {
24 // If we hit an error, fail.
25 if (aStatus != Status::kSuccess) {
26 Done(aStatus);
27 } else if (mFileIO) { // Otherwise, write our data to the file.
28 mFileIO->Write(mData.empty() ? nullptr : &mData.front(), mData.size());
29 }
30 }
31
OnReadComplete(Status aStatus,const uint8_t * aData,uint32_t aDataSize)32 void OnReadComplete(Status aStatus, const uint8_t* aData,
33 uint32_t aDataSize) override {}
34
OnWriteComplete(Status aStatus)35 void OnWriteComplete(Status aStatus) override { Done(aStatus); }
36
Do(const std::string & aName,Host_10 * aHost)37 void Do(const std::string& aName, Host_10* aHost) {
38 // Initialize the FileIO.
39 mFileIO = aHost->CreateFileIO(this);
40 mFileIO->Open(aName.c_str(), aName.size());
41 }
42
43 private:
Done(cdm::FileIOClient::Status aStatus)44 void Done(cdm::FileIOClient::Status aStatus) {
45 // Note: Call Close() before running continuation, in case the
46 // continuation tries to open the same record; if we call Close()
47 // after running the continuation, the Close() call will arrive
48 // just after the Open() call succeeds, immediately closing the
49 // record we just opened.
50 if (mFileIO) {
51 // will delete mFileIO inside Close.
52 mFileIO->Close();
53 }
54
55 if (IO_SUCCEEDED(aStatus)) {
56 mOnSuccess();
57 } else {
58 mOnFailure();
59 }
60
61 delete this;
62 }
63
64 FileIO* mFileIO = nullptr;
65 std::function<void()> mOnSuccess;
66 std::function<void()> mOnFailure;
67 std::vector<uint8_t> mData;
68 };
69
WriteRecord(Host_10 * aHost,const std::string & aRecordName,const uint8_t * aData,uint32_t aNumBytes,std::function<void ()> && aOnSuccess,std::function<void ()> && aOnFailure)70 void WriteRecord(Host_10* aHost, const std::string& aRecordName,
71 const uint8_t* aData, uint32_t aNumBytes,
72 std::function<void()>&& aOnSuccess,
73 std::function<void()>&& aOnFailure) {
74 // client will be delete in WriteRecordClient::Done
75 WriteRecordClient* client = new WriteRecordClient(
76 move(aOnSuccess), move(aOnFailure), aData, aNumBytes);
77 client->Do(aRecordName, aHost);
78 }
79
WriteRecord(Host_10 * aHost,const std::string & aRecordName,const std::string & aData,std::function<void ()> && aOnSuccess,std::function<void ()> && aOnFailure)80 void WriteRecord(Host_10* aHost, const std::string& aRecordName,
81 const std::string& aData, std::function<void()>&& aOnSuccess,
82 std::function<void()>&& aOnFailure) {
83 return WriteRecord(aHost, aRecordName, (const uint8_t*)aData.c_str(),
84 aData.size(), move(aOnSuccess), move(aOnFailure));
85 }
86
87 class ReadRecordClient : public FileIOClient {
88 public:
ReadRecordClient(std::function<void (bool,const uint8_t *,uint32_t)> && aOnReadComplete)89 explicit ReadRecordClient(
90 std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
91 : mOnReadComplete(move(aOnReadComplete)) {}
92
OnOpenComplete(Status aStatus)93 void OnOpenComplete(Status aStatus) override {
94 auto err = aStatus;
95 if (aStatus != Status::kSuccess) {
96 Done(err, reinterpret_cast<const uint8_t*>(""), 0);
97 } else {
98 mFileIO->Read();
99 }
100 }
101
OnReadComplete(Status aStatus,const uint8_t * aData,uint32_t aDataSize)102 void OnReadComplete(Status aStatus, const uint8_t* aData,
103 uint32_t aDataSize) override {
104 Done(aStatus, aData, aDataSize);
105 }
106
OnWriteComplete(Status aStatus)107 void OnWriteComplete(Status aStatus) override {}
108
Do(const std::string & aName,Host_10 * aHost)109 void Do(const std::string& aName, Host_10* aHost) {
110 mFileIO = aHost->CreateFileIO(this);
111 mFileIO->Open(aName.c_str(), aName.size());
112 }
113
114 private:
Done(cdm::FileIOClient::Status aStatus,const uint8_t * aData,uint32_t aDataSize)115 void Done(cdm::FileIOClient::Status aStatus, const uint8_t* aData,
116 uint32_t aDataSize) {
117 // Note: Call Close() before running continuation, in case the
118 // continuation tries to open the same record; if we call Close()
119 // after running the continuation, the Close() call will arrive
120 // just after the Open() call succeeds, immediately closing the
121 // record we just opened.
122 if (mFileIO) {
123 // will delete mFileIO inside Close.
124 mFileIO->Close();
125 }
126
127 if (IO_SUCCEEDED(aStatus)) {
128 mOnReadComplete(true, aData, aDataSize);
129 } else {
130 mOnReadComplete(false, reinterpret_cast<const uint8_t*>(""), 0);
131 }
132
133 delete this;
134 }
135
136 FileIO* mFileIO = nullptr;
137 std::function<void(bool, const uint8_t*, uint32_t)> mOnReadComplete;
138 };
139
ReadRecord(Host_10 * aHost,const std::string & aRecordName,std::function<void (bool,const uint8_t *,uint32_t)> && aOnReadComplete)140 void ReadRecord(
141 Host_10* aHost, const std::string& aRecordName,
142 std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete) {
143 // client will be delete in ReadRecordClient::Done
144 ReadRecordClient* client = new ReadRecordClient(move(aOnReadComplete));
145 client->Do(aRecordName, aHost);
146 }
147
148 class OpenRecordClient : public FileIOClient {
149 public:
OpenRecordClient(std::function<void (bool)> && aOpenComplete)150 explicit OpenRecordClient(std::function<void(bool)>&& aOpenComplete)
151 : mOpenComplete(move(aOpenComplete)) {}
152
OnOpenComplete(Status aStatus)153 void OnOpenComplete(Status aStatus) override { Done(aStatus); }
154
OnReadComplete(Status aStatus,const uint8_t * aData,uint32_t aDataSize)155 void OnReadComplete(Status aStatus, const uint8_t* aData,
156 uint32_t aDataSize) override {}
157
OnWriteComplete(Status aStatus)158 void OnWriteComplete(Status aStatus) override {}
159
Do(const std::string & aName,Host_10 * aHost)160 void Do(const std::string& aName, Host_10* aHost) {
161 // Initialize the FileIO.
162 mFileIO = aHost->CreateFileIO(this);
163 mFileIO->Open(aName.c_str(), aName.size());
164 }
165
166 private:
Done(cdm::FileIOClient::Status aStatus)167 void Done(cdm::FileIOClient::Status aStatus) {
168 // Note: Call Close() before running continuation, in case the
169 // continuation tries to open the same record; if we call Close()
170 // after running the continuation, the Close() call will arrive
171 // just after the Open() call succeeds, immediately closing the
172 // record we just opened.
173 if (mFileIO) {
174 // will delete mFileIO inside Close.
175 mFileIO->Close();
176 }
177
178 if (IO_SUCCEEDED(aStatus)) {
179 mOpenComplete(true);
180 } else {
181 mOpenComplete(false);
182 }
183
184 delete this;
185 }
186
187 FileIO* mFileIO = nullptr;
188 std::function<void(bool)> mOpenComplete;
189 ;
190 };
191
OpenRecord(Host_10 * aHost,const std::string & aRecordName,std::function<void (bool)> && aOpenComplete)192 void OpenRecord(Host_10* aHost, const std::string& aRecordName,
193 std::function<void(bool)>&& aOpenComplete) {
194 // client will be delete in OpenRecordClient::Done
195 OpenRecordClient* client = new OpenRecordClient(move(aOpenComplete));
196 client->Do(aRecordName, aHost);
197 }
198