2014-10-21 10:16:19 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2017-09-27 16:12:39 +03:00
|
|
|
#include "cdm-test-storage.h"
|
2014-10-21 10:16:19 +04:00
|
|
|
#include <vector>
|
2014-10-29 01:43:18 +03:00
|
|
|
|
|
|
|
#include "mozilla/Assertions.h"
|
2014-10-21 10:16:19 +04:00
|
|
|
#include "mozilla/Attributes.h"
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
using namespace cdm;
|
|
|
|
|
|
|
|
class WriteRecordClient : public FileIOClient {
|
2014-10-21 10:16:19 +04:00
|
|
|
public:
|
2019-09-01 09:47:26 +03:00
|
|
|
WriteRecordClient(std::function<void()>&& aOnSuccess,
|
|
|
|
std::function<void()>&& aOnFailure, const uint8_t* aData,
|
2017-09-25 12:40:22 +03:00
|
|
|
uint32_t aDataSize)
|
|
|
|
: mOnSuccess(move(aOnSuccess)), mOnFailure(move(aOnFailure)) {
|
2014-10-21 10:16:19 +04:00
|
|
|
mData.insert(mData.end(), aData, aData + aDataSize);
|
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
void OnOpenComplete(Status aStatus) override {
|
|
|
|
// If we hit an error, fail.
|
|
|
|
if (aStatus != Status::kSuccess) {
|
|
|
|
Done(aStatus);
|
|
|
|
} else if (mFileIO) { // Otherwise, write our data to the file.
|
|
|
|
mFileIO->Write(mData.empty() ? nullptr : &mData.front(), mData.size());
|
2014-12-03 15:34:00 +03:00
|
|
|
}
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
void OnReadComplete(Status aStatus, const uint8_t* aData,
|
|
|
|
uint32_t aDataSize) override {}
|
2014-10-21 10:16:19 +04:00
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
void OnWriteComplete(Status aStatus) override { Done(aStatus); }
|
|
|
|
|
2019-09-01 09:47:26 +03:00
|
|
|
void Do(const std::string& aName, Host_10* aHost) {
|
2017-09-25 12:40:22 +03:00
|
|
|
// Initialize the FileIO.
|
|
|
|
mFileIO = aHost->CreateFileIO(this);
|
|
|
|
mFileIO->Open(aName.c_str(), aName.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void Done(cdm::FileIOClient::Status aStatus) {
|
2014-10-21 10:16:19 +04:00
|
|
|
// Note: Call Close() before running continuation, in case the
|
|
|
|
// continuation tries to open the same record; if we call Close()
|
|
|
|
// after running the continuation, the Close() call will arrive
|
|
|
|
// just after the Open() call succeeds, immediately closing the
|
|
|
|
// record we just opened.
|
2017-09-25 12:40:22 +03:00
|
|
|
if (mFileIO) {
|
|
|
|
// will delete mFileIO inside Close.
|
|
|
|
mFileIO->Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IO_SUCCEEDED(aStatus)) {
|
|
|
|
mOnSuccess();
|
2014-12-03 15:34:00 +03:00
|
|
|
} else {
|
2017-09-25 12:40:22 +03:00
|
|
|
mOnFailure();
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|
2017-09-25 12:40:22 +03:00
|
|
|
|
2014-10-21 10:16:19 +04:00
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
FileIO* mFileIO = nullptr;
|
2019-09-01 09:47:26 +03:00
|
|
|
std::function<void()> mOnSuccess;
|
|
|
|
std::function<void()> mOnFailure;
|
2014-10-21 10:16:19 +04:00
|
|
|
std::vector<uint8_t> mData;
|
|
|
|
};
|
|
|
|
|
2019-01-14 19:41:55 +03:00
|
|
|
void WriteRecord(Host_10* aHost, const std::string& aRecordName,
|
2014-10-21 10:16:19 +04:00
|
|
|
const uint8_t* aData, uint32_t aNumBytes,
|
2019-09-01 09:47:26 +03:00
|
|
|
std::function<void()>&& aOnSuccess,
|
|
|
|
std::function<void()>&& aOnFailure) {
|
2017-09-25 12:40:22 +03:00
|
|
|
// client will be delete in WriteRecordClient::Done
|
|
|
|
WriteRecordClient* client = new WriteRecordClient(
|
|
|
|
move(aOnSuccess), move(aOnFailure), aData, aNumBytes);
|
|
|
|
client->Do(aRecordName, aHost);
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|
|
|
|
|
2019-01-14 19:41:55 +03:00
|
|
|
void WriteRecord(Host_10* aHost, const std::string& aRecordName,
|
2019-09-01 09:47:26 +03:00
|
|
|
const std::string& aData, std::function<void()>&& aOnSuccess,
|
|
|
|
std::function<void()>&& aOnFailure) {
|
2014-10-21 10:16:19 +04:00
|
|
|
return WriteRecord(aHost, aRecordName, (const uint8_t*)aData.c_str(),
|
2017-09-25 12:40:22 +03:00
|
|
|
aData.size(), move(aOnSuccess), move(aOnFailure));
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
class ReadRecordClient : public FileIOClient {
|
2014-10-21 10:16:19 +04:00
|
|
|
public:
|
2017-09-25 12:40:22 +03:00
|
|
|
explicit ReadRecordClient(
|
2019-09-01 09:47:26 +03:00
|
|
|
std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete)
|
2017-09-25 12:40:22 +03:00
|
|
|
: mOnReadComplete(move(aOnReadComplete)) {}
|
|
|
|
|
|
|
|
void OnOpenComplete(Status aStatus) override {
|
|
|
|
auto err = aStatus;
|
|
|
|
if (aStatus != Status::kSuccess) {
|
|
|
|
Done(err, reinterpret_cast<const uint8_t*>(""), 0);
|
|
|
|
} else {
|
|
|
|
mFileIO->Read();
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
void OnReadComplete(Status aStatus, const uint8_t* aData,
|
|
|
|
uint32_t aDataSize) override {
|
|
|
|
Done(aStatus, aData, aDataSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OnWriteComplete(Status aStatus) override {}
|
|
|
|
|
2019-09-01 09:47:26 +03:00
|
|
|
void Do(const std::string& aName, Host_10* aHost) {
|
2017-09-25 12:40:22 +03:00
|
|
|
mFileIO = aHost->CreateFileIO(this);
|
|
|
|
mFileIO->Open(aName.c_str(), aName.size());
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void Done(cdm::FileIOClient::Status aStatus, const uint8_t* aData,
|
|
|
|
uint32_t aDataSize) {
|
2014-10-21 10:16:19 +04:00
|
|
|
// Note: Call Close() before running continuation, in case the
|
|
|
|
// continuation tries to open the same record; if we call Close()
|
|
|
|
// after running the continuation, the Close() call will arrive
|
|
|
|
// just after the Open() call succeeds, immediately closing the
|
|
|
|
// record we just opened.
|
2017-09-25 12:40:22 +03:00
|
|
|
if (mFileIO) {
|
|
|
|
// will delete mFileIO inside Close.
|
|
|
|
mFileIO->Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IO_SUCCEEDED(aStatus)) {
|
|
|
|
mOnReadComplete(true, aData, aDataSize);
|
|
|
|
} else {
|
|
|
|
mOnReadComplete(false, reinterpret_cast<const uint8_t*>(""), 0);
|
|
|
|
}
|
2014-10-21 10:16:19 +04:00
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
delete this;
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
FileIO* mFileIO = nullptr;
|
2019-09-01 09:47:26 +03:00
|
|
|
std::function<void(bool, const uint8_t*, uint32_t)> mOnReadComplete;
|
2014-10-21 10:16:19 +04:00
|
|
|
};
|
|
|
|
|
2017-11-23 11:51:23 +03:00
|
|
|
void ReadRecord(
|
2019-01-14 19:41:55 +03:00
|
|
|
Host_10* aHost, const std::string& aRecordName,
|
2019-09-01 09:47:26 +03:00
|
|
|
std::function<void(bool, const uint8_t*, uint32_t)>&& aOnReadComplete) {
|
2017-09-25 12:40:22 +03:00
|
|
|
// client will be delete in ReadRecordClient::Done
|
|
|
|
ReadRecordClient* client = new ReadRecordClient(move(aOnReadComplete));
|
|
|
|
client->Do(aRecordName, aHost);
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
class OpenRecordClient : public FileIOClient {
|
2014-10-21 10:16:19 +04:00
|
|
|
public:
|
2019-09-01 09:47:26 +03:00
|
|
|
explicit OpenRecordClient(std::function<void(bool)>&& aOpenComplete)
|
2017-09-25 12:40:22 +03:00
|
|
|
: mOpenComplete(move(aOpenComplete)) {}
|
2014-10-21 10:16:19 +04:00
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
void OnOpenComplete(Status aStatus) override { Done(aStatus); }
|
2014-10-21 10:16:19 +04:00
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
void OnReadComplete(Status aStatus, const uint8_t* aData,
|
|
|
|
uint32_t aDataSize) override {}
|
2014-10-21 10:16:19 +04:00
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
void OnWriteComplete(Status aStatus) override {}
|
|
|
|
|
2019-09-01 09:47:26 +03:00
|
|
|
void Do(const std::string& aName, Host_10* aHost) {
|
2017-09-25 12:40:22 +03:00
|
|
|
// Initialize the FileIO.
|
|
|
|
mFileIO = aHost->CreateFileIO(this);
|
|
|
|
mFileIO->Open(aName.c_str(), aName.size());
|
2015-02-10 20:19:00 +03:00
|
|
|
}
|
2014-10-21 10:16:19 +04:00
|
|
|
|
|
|
|
private:
|
2017-09-25 12:40:22 +03:00
|
|
|
void Done(cdm::FileIOClient::Status aStatus) {
|
|
|
|
// Note: Call Close() before running continuation, in case the
|
|
|
|
// continuation tries to open the same record; if we call Close()
|
|
|
|
// after running the continuation, the Close() call will arrive
|
|
|
|
// just after the Open() call succeeds, immediately closing the
|
|
|
|
// record we just opened.
|
|
|
|
if (mFileIO) {
|
|
|
|
// will delete mFileIO inside Close.
|
|
|
|
mFileIO->Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IO_SUCCEEDED(aStatus)) {
|
|
|
|
mOpenComplete(true);
|
|
|
|
} else {
|
|
|
|
mOpenComplete(false);
|
2015-02-10 20:19:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
delete this;
|
|
|
|
}
|
|
|
|
|
2017-09-25 12:40:22 +03:00
|
|
|
FileIO* mFileIO = nullptr;
|
2019-09-01 09:47:26 +03:00
|
|
|
std::function<void(bool)> mOpenComplete;
|
2018-11-19 16:25:37 +03:00
|
|
|
;
|
2014-10-21 10:16:19 +04:00
|
|
|
};
|
|
|
|
|
2019-01-14 19:41:55 +03:00
|
|
|
void OpenRecord(Host_10* aHost, const std::string& aRecordName,
|
2019-09-01 09:47:26 +03:00
|
|
|
std::function<void(bool)>&& aOpenComplete) {
|
2017-09-25 12:40:22 +03:00
|
|
|
// client will be delete in OpenRecordClient::Done
|
|
|
|
OpenRecordClient* client = new OpenRecordClient(move(aOpenComplete));
|
|
|
|
client->Do(aRecordName, aHost);
|
2014-10-21 10:16:19 +04:00
|
|
|
}
|