зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 8 changesets (bug 1617170) for build bustages at nsTArray.h on a CLOSED TREE
Backed out changeset ed7eaba53757 (bug 1617170) Backed out changeset 0021ab4bcf77 (bug 1617170) Backed out changeset 92f4ef8809ec (bug 1617170) Backed out changeset c9561cb90821 (bug 1617170) Backed out changeset 739dafac70bc (bug 1617170) Backed out changeset 51c699b06d04 (bug 1617170) Backed out changeset 2ae6b424f492 (bug 1617170) Backed out changeset 6acafdd56175 (bug 1617170)
This commit is contained in:
Родитель
7f9b896113
Коммит
110347c99a
|
@ -2942,8 +2942,8 @@ mozilla::ipc::IPCResult BackgroundRequestChild::RecvPreprocess(
|
||||||
nsresult BackgroundRequestChild::PreprocessHelper::Init(
|
nsresult BackgroundRequestChild::PreprocessHelper::Init(
|
||||||
const StructuredCloneFile& aFile) {
|
const StructuredCloneFile& aFile) {
|
||||||
AssertIsOnOwningThread();
|
AssertIsOnOwningThread();
|
||||||
MOZ_ASSERT(aFile.HasBlob());
|
MOZ_ASSERT(aFile.mBlob);
|
||||||
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eStructuredClone);
|
MOZ_ASSERT(aFile.mType == StructuredCloneFile::eStructuredClone);
|
||||||
MOZ_ASSERT(mState == State::Initial);
|
MOZ_ASSERT(mState == State::Initial);
|
||||||
|
|
||||||
// The stream transport service is used for asynchronous processing. It has a
|
// The stream transport service is used for asynchronous processing. It has a
|
||||||
|
@ -2962,8 +2962,7 @@ nsresult BackgroundRequestChild::PreprocessHelper::Init(
|
||||||
ErrorResult errorResult;
|
ErrorResult errorResult;
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
nsCOMPtr<nsIInputStream> stream;
|
||||||
// XXX After Bug 1620560, MutableBlob is not needed here anymore.
|
aFile.mBlob->CreateInputStream(getter_AddRefs(stream), errorResult);
|
||||||
aFile.MutableBlob().CreateInputStream(getter_AddRefs(stream), errorResult);
|
|
||||||
if (NS_WARN_IF(errorResult.Failed())) {
|
if (NS_WARN_IF(errorResult.Failed())) {
|
||||||
return errorResult.StealNSResult();
|
return errorResult.StealNSResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4956,8 +4956,8 @@ class DatabaseConnection::UpdateRefcountFunction::FileInfoEntry final {
|
||||||
int32_t mSavepointDelta;
|
int32_t mSavepointDelta;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit FileInfoEntry(RefPtr<FileInfo> aFileInfo)
|
explicit FileInfoEntry(FileInfo* aFileInfo)
|
||||||
: mFileInfo(std::move(aFileInfo)), mDelta(0), mSavepointDelta(0) {
|
: mFileInfo(aFileInfo), mDelta(0), mSavepointDelta(0) {
|
||||||
MOZ_COUNT_CTOR(DatabaseConnection::UpdateRefcountFunction::FileInfoEntry);
|
MOZ_COUNT_CTOR(DatabaseConnection::UpdateRefcountFunction::FileInfoEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5533,13 +5533,12 @@ class DatabaseOperationBase : public Runnable,
|
||||||
|
|
||||||
bool HasFailed() const { return NS_FAILED(mResultCode); }
|
bool HasFailed() const { return NS_FAILED(mResultCode); }
|
||||||
|
|
||||||
static Result<StructuredCloneReadInfo, nsresult>
|
static nsresult GetStructuredCloneReadInfoFromStatement(
|
||||||
GetStructuredCloneReadInfoFromStatement(mozIStorageStatement* aStatement,
|
mozIStorageStatement* aStatement, uint32_t aDataIndex,
|
||||||
uint32_t aDataIndex,
|
uint32_t aFileIdsIndex, const FileManager& aFileManager,
|
||||||
uint32_t aFileIdsIndex,
|
StructuredCloneReadInfo* aInfo) {
|
||||||
const FileManager& aFileManager) {
|
return GetStructuredCloneReadInfoFromSource(
|
||||||
return GetStructuredCloneReadInfoFromSource(aStatement, aDataIndex,
|
aStatement, aDataIndex, aFileIdsIndex, aFileManager, aInfo);
|
||||||
aFileIdsIndex, aFileManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -5570,13 +5569,12 @@ class DatabaseOperationBase : public Runnable,
|
||||||
|
|
||||||
static uint64_t ReinterpretDoubleAsUInt64(double aDouble);
|
static uint64_t ReinterpretDoubleAsUInt64(double aDouble);
|
||||||
|
|
||||||
static Result<StructuredCloneReadInfo, nsresult>
|
static nsresult GetStructuredCloneReadInfoFromValueArray(
|
||||||
GetStructuredCloneReadInfoFromValueArray(mozIStorageValueArray* aValues,
|
mozIStorageValueArray* aValues, uint32_t aDataIndex,
|
||||||
uint32_t aDataIndex,
|
uint32_t aFileIdsIndex, const FileManager& aFileManager,
|
||||||
uint32_t aFileIdsIndex,
|
StructuredCloneReadInfo* aInfo) {
|
||||||
const FileManager& aFileManager) {
|
return GetStructuredCloneReadInfoFromSource(
|
||||||
return GetStructuredCloneReadInfoFromSource(aValues, aDataIndex,
|
aValues, aDataIndex, aFileIdsIndex, aFileManager, aInfo);
|
||||||
aFileIdsIndex, aFileManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static nsresult BindKeyRangeToStatement(const SerializedKeyRange& aKeyRange,
|
static nsresult BindKeyRangeToStatement(const SerializedKeyRange& aKeyRange,
|
||||||
|
@ -5620,21 +5618,18 @@ class DatabaseOperationBase : public Runnable,
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static Result<StructuredCloneReadInfo, nsresult>
|
static nsresult GetStructuredCloneReadInfoFromSource(
|
||||||
GetStructuredCloneReadInfoFromSource(T* aSource, uint32_t aDataIndex,
|
T* aSource, uint32_t aDataIndex, uint32_t aFileIdsIndex,
|
||||||
uint32_t aFileIdsIndex,
|
const FileManager& aFileManager, StructuredCloneReadInfo* aInfo);
|
||||||
const FileManager& aFileManager);
|
|
||||||
|
|
||||||
static Result<StructuredCloneReadInfo, nsresult>
|
static nsresult GetStructuredCloneReadInfoFromBlob(
|
||||||
GetStructuredCloneReadInfoFromBlob(const uint8_t* aBlobData,
|
const uint8_t* aBlobData, uint32_t aBlobDataLength,
|
||||||
uint32_t aBlobDataLength,
|
const FileManager& aFileManager, const nsAString& aFileIds,
|
||||||
const FileManager& aFileManager,
|
StructuredCloneReadInfo* aInfo);
|
||||||
const nsAString& aFileIds);
|
|
||||||
|
|
||||||
static Result<StructuredCloneReadInfo, nsresult>
|
static nsresult GetStructuredCloneReadInfoFromExternalBlob(
|
||||||
GetStructuredCloneReadInfoFromExternalBlob(uint64_t aIntData,
|
uint64_t aIntData, const FileManager& aFileManager,
|
||||||
const FileManager& aFileManager,
|
const nsAString& aFileIds, StructuredCloneReadInfo* aInfo);
|
||||||
const nsAString& aFileIds);
|
|
||||||
|
|
||||||
template <typename KeyTransformation>
|
template <typename KeyTransformation>
|
||||||
static nsresult MaybeBindKeyToStatement(
|
static nsresult MaybeBindKeyToStatement(
|
||||||
|
@ -6008,7 +6003,7 @@ class Database final
|
||||||
|
|
||||||
void SetActorAlive();
|
void SetActorAlive();
|
||||||
|
|
||||||
void MapBlob(const IPCBlob& aIPCBlob, RefPtr<FileInfo> aFileInfo);
|
void MapBlob(const IPCBlob& aIPCBlob, FileInfo* aFileInfo);
|
||||||
|
|
||||||
bool IsActorAlive() const {
|
bool IsActorAlive() const {
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
|
@ -6668,7 +6663,7 @@ class MutableFile : public BackgroundMutableFileParentBase {
|
||||||
public:
|
public:
|
||||||
static MOZ_MUST_USE RefPtr<MutableFile> Create(nsIFile* aFile,
|
static MOZ_MUST_USE RefPtr<MutableFile> Create(nsIFile* aFile,
|
||||||
Database* aDatabase,
|
Database* aDatabase,
|
||||||
RefPtr<FileInfo> aFileInfo);
|
FileInfo* aFileInfo);
|
||||||
|
|
||||||
const Database& GetDatabase() const {
|
const Database& GetDatabase() const {
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
|
@ -6693,8 +6688,7 @@ class MutableFile : public BackgroundMutableFileParentBase {
|
||||||
already_AddRefed<BlobImpl> CreateBlobImpl() override;
|
already_AddRefed<BlobImpl> CreateBlobImpl() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MutableFile(nsIFile* aFile, RefPtr<Database> aDatabase,
|
MutableFile(nsIFile* aFile, Database* aDatabase, FileInfo* aFileInfo);
|
||||||
RefPtr<FileInfo> aFileInfo);
|
|
||||||
|
|
||||||
~MutableFile() override;
|
~MutableFile() override;
|
||||||
|
|
||||||
|
@ -9158,9 +9152,11 @@ class MOZ_STACK_CLASS FileHelper final {
|
||||||
|
|
||||||
bool TokenizerIgnoreNothing(char16_t /* aChar */) { return false; }
|
bool TokenizerIgnoreNothing(char16_t /* aChar */) { return false; }
|
||||||
|
|
||||||
Result<StructuredCloneFile, nsresult> DeserializeStructuredCloneFile(
|
nsresult DeserializeStructuredCloneFile(const FileManager& aFileManager,
|
||||||
const FileManager& aFileManager, const nsDependentSubstring& aText) {
|
const nsDependentSubstring& aText,
|
||||||
|
StructuredCloneFile* aFile) {
|
||||||
MOZ_ASSERT(!aText.IsEmpty());
|
MOZ_ASSERT(!aText.IsEmpty());
|
||||||
|
MOZ_ASSERT(aFile);
|
||||||
|
|
||||||
StructuredCloneFile::FileType type;
|
StructuredCloneFile::FileType type;
|
||||||
|
|
||||||
|
@ -9196,7 +9192,7 @@ Result<StructuredCloneFile, nsresult> DeserializeStructuredCloneFile(
|
||||||
id = text.ToInteger(&rv);
|
id = text.ToInteger(&rv);
|
||||||
}
|
}
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<FileInfo> fileInfo = aFileManager.GetFileInfo(id);
|
RefPtr<FileInfo> fileInfo = aFileManager.GetFileInfo(id);
|
||||||
|
@ -9210,35 +9206,39 @@ Result<StructuredCloneFile, nsresult> DeserializeStructuredCloneFile(
|
||||||
"database request. Bug 1519859 will address this problem.");
|
"database request. Bug 1519859 will address this problem.");
|
||||||
Telemetry::ScalarAdd(Telemetry::ScalarID::IDB_FAILURE_FILEINFO_ERROR, 1);
|
Telemetry::ScalarAdd(Telemetry::ScalarID::IDB_FAILURE_FILEINFO_ERROR, 1);
|
||||||
|
|
||||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StructuredCloneFile{type, std::move(fileInfo)};
|
aFile->mFileInfo = std::move(fileInfo);
|
||||||
|
aFile->mType = type;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<nsTArray<StructuredCloneFile>, nsresult> DeserializeStructuredCloneFiles(
|
nsresult DeserializeStructuredCloneFiles(
|
||||||
const FileManager& aFileManager, const nsAString& aText) {
|
const FileManager& aFileManager, const nsAString& aText,
|
||||||
|
nsTArray<StructuredCloneFile>& aResult) {
|
||||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||||
|
|
||||||
nsCharSeparatedTokenizerTemplate<TokenizerIgnoreNothing> tokenizer(aText,
|
nsCharSeparatedTokenizerTemplate<TokenizerIgnoreNothing> tokenizer(aText,
|
||||||
' ');
|
' ');
|
||||||
|
|
||||||
nsTArray<StructuredCloneFile> result;
|
nsresult rv;
|
||||||
|
|
||||||
while (tokenizer.hasMoreTokens()) {
|
while (tokenizer.hasMoreTokens()) {
|
||||||
const auto& token = tokenizer.nextToken();
|
const auto& token = tokenizer.nextToken();
|
||||||
MOZ_ASSERT(!token.IsEmpty());
|
MOZ_ASSERT(!token.IsEmpty());
|
||||||
|
|
||||||
auto structuredCloneFileOrErr =
|
auto* const file = aResult.EmplaceBack(StructuredCloneFile::eBlob);
|
||||||
DeserializeStructuredCloneFile(aFileManager, token);
|
MOZ_ASSERT(file);
|
||||||
if (NS_WARN_IF(structuredCloneFileOrErr.isErr())) {
|
|
||||||
// XXX Can't this be written in a simpler way?
|
|
||||||
return Err(structuredCloneFileOrErr.unwrapErr());
|
|
||||||
}
|
|
||||||
|
|
||||||
result.EmplaceBack(structuredCloneFileOrErr.unwrap());
|
rv = DeserializeStructuredCloneFile(aFileManager, token, file);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetBaseFilename(const nsAString& aFilename, const nsAString& aSuffix,
|
bool GetBaseFilename(const nsAString& aFilename, const nsAString& aSuffix,
|
||||||
|
@ -9287,12 +9287,11 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const StructuredCloneFile& file : aFiles) {
|
for (const StructuredCloneFile& file : aFiles) {
|
||||||
if (aForPreprocess &&
|
if (aForPreprocess && file.mType != StructuredCloneFile::eStructuredClone) {
|
||||||
file.Type() != StructuredCloneFile::eStructuredClone) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int64_t fileId = file.FileInfo().Id();
|
const int64_t fileId = file.mFileInfo->Id();
|
||||||
MOZ_ASSERT(fileId > 0);
|
MOZ_ASSERT(fileId > 0);
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> nativeFile =
|
nsCOMPtr<nsIFile> nativeFile =
|
||||||
|
@ -9303,10 +9302,10 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
|
||||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (file.Type()) {
|
switch (file.mType) {
|
||||||
case StructuredCloneFile::eBlob: {
|
case StructuredCloneFile::eBlob: {
|
||||||
RefPtr<FileBlobImpl> impl = new FileBlobImpl(nativeFile);
|
RefPtr<FileBlobImpl> impl = new FileBlobImpl(nativeFile);
|
||||||
impl->SetFileId(file.FileInfo().Id());
|
impl->SetFileId(file.mFileInfo->Id());
|
||||||
|
|
||||||
IPCBlob ipcBlob;
|
IPCBlob ipcBlob;
|
||||||
nsresult rv = IPCBlobUtils::Serialize(impl, aBackgroundActor, ipcBlob);
|
nsresult rv = IPCBlobUtils::Serialize(impl, aBackgroundActor, ipcBlob);
|
||||||
|
@ -9318,7 +9317,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
|
||||||
|
|
||||||
result.EmplaceBack(ipcBlob, StructuredCloneFile::eBlob);
|
result.EmplaceBack(ipcBlob, StructuredCloneFile::eBlob);
|
||||||
|
|
||||||
aDatabase->MapBlob(ipcBlob, file.FileInfoPtr());
|
aDatabase->MapBlob(ipcBlob, file.mFileInfo);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9327,7 +9326,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
|
||||||
result.EmplaceBack(null_t(), StructuredCloneFile::eMutableFile);
|
result.EmplaceBack(null_t(), StructuredCloneFile::eMutableFile);
|
||||||
} else {
|
} else {
|
||||||
RefPtr<MutableFile> actor =
|
RefPtr<MutableFile> actor =
|
||||||
MutableFile::Create(nativeFile, aDatabase, file.FileInfoPtr());
|
MutableFile::Create(nativeFile, aDatabase, file.mFileInfo);
|
||||||
if (!actor) {
|
if (!actor) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
return Err(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
@ -9354,7 +9353,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
|
||||||
result.EmplaceBack(null_t(), StructuredCloneFile::eStructuredClone);
|
result.EmplaceBack(null_t(), StructuredCloneFile::eStructuredClone);
|
||||||
} else {
|
} else {
|
||||||
RefPtr<FileBlobImpl> impl = new FileBlobImpl(nativeFile);
|
RefPtr<FileBlobImpl> impl = new FileBlobImpl(nativeFile);
|
||||||
impl->SetFileId(file.FileInfo().Id());
|
impl->SetFileId(file.mFileInfo->Id());
|
||||||
|
|
||||||
IPCBlob ipcBlob;
|
IPCBlob ipcBlob;
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
|
@ -9367,7 +9366,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
|
||||||
|
|
||||||
result.EmplaceBack(ipcBlob, StructuredCloneFile::eStructuredClone);
|
result.EmplaceBack(ipcBlob, StructuredCloneFile::eStructuredClone);
|
||||||
|
|
||||||
aDatabase->MapBlob(ipcBlob, file.FileInfoPtr());
|
aDatabase->MapBlob(ipcBlob, file.mFileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -9380,7 +9379,7 @@ SerializeStructuredCloneFiles(PBackgroundParent* aBackgroundActor,
|
||||||
// WebAssembly.Modules modules has been removed in bug 1561876. Full
|
// WebAssembly.Modules modules has been removed in bug 1561876. Full
|
||||||
// removal is tracked in bug 1487479.
|
// removal is tracked in bug 1487479.
|
||||||
|
|
||||||
result.EmplaceBack(null_t(), file.Type());
|
result.EmplaceBack(null_t(), file.mType);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10141,15 +10140,13 @@ struct ValuePopulateResponseHelper {
|
||||||
|
|
||||||
constexpr auto offset = StatementHasIndexKeyBindings ? 2 : 0;
|
constexpr auto offset = StatementHasIndexKeyBindings ? 2 : 0;
|
||||||
|
|
||||||
auto cloneInfoOrErr =
|
const nsresult rv =
|
||||||
DatabaseOperationBase::GetStructuredCloneReadInfoFromStatement(
|
DatabaseOperationBase::GetStructuredCloneReadInfoFromStatement(
|
||||||
aStmt, 2 + offset, 1 + offset, *aCursor.mFileManager);
|
aStmt, 2 + offset, 1 + offset, *aCursor.mFileManager, &mCloneInfo);
|
||||||
if (NS_WARN_IF(cloneInfoOrErr.isErr())) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return cloneInfoOrErr.unwrapErr();
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCloneInfo = cloneInfoOrErr.unwrap();
|
|
||||||
|
|
||||||
if (mCloneInfo.mHasPreprocessInfo) {
|
if (mCloneInfo.mHasPreprocessInfo) {
|
||||||
IDB_WARNING("Preprocessing for cursors not yet implemented!");
|
IDB_WARNING("Preprocessing for cursors not yet implemented!");
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
@ -11390,17 +11387,18 @@ nsresult DatabaseConnection::UpdateRefcountFunction::ProcessValue(
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto filesOrErr = DeserializeStructuredCloneFiles(*mFileManager, ids);
|
nsTArray<StructuredCloneFile> files;
|
||||||
if (NS_WARN_IF(filesOrErr.isErr())) {
|
rv = DeserializeStructuredCloneFiles(*mFileManager, ids, files);
|
||||||
return filesOrErr.unwrapErr();
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
for (const StructuredCloneFile& file : filesOrErr.inspect()) {
|
for (const StructuredCloneFile& file : files) {
|
||||||
const int64_t id = file.FileInfo().Id();
|
const int64_t id = file.mFileInfo->Id();
|
||||||
MOZ_ASSERT(id > 0);
|
MOZ_ASSERT(id > 0);
|
||||||
|
|
||||||
FileInfoEntry* entry;
|
FileInfoEntry* entry;
|
||||||
if (!mFileInfoEntries.Get(id, &entry)) {
|
if (!mFileInfoEntries.Get(id, &entry)) {
|
||||||
entry = new FileInfoEntry(file.FileInfoPtr());
|
entry = new FileInfoEntry(file.mFileInfo);
|
||||||
mFileInfoEntries.Put(id, entry);
|
mFileInfoEntries.Put(id, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13619,7 +13617,7 @@ void Database::SetActorAlive() {
|
||||||
AddRef();
|
AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::MapBlob(const IPCBlob& aIPCBlob, RefPtr<FileInfo> aFileInfo) {
|
void Database::MapBlob(const IPCBlob& aIPCBlob, FileInfo* aFileInfo) {
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
const IPCBlobStream& stream = aIPCBlob.inputStream();
|
const IPCBlobStream& stream = aIPCBlob.inputStream();
|
||||||
|
@ -13629,7 +13627,7 @@ void Database::MapBlob(const IPCBlob& aIPCBlob, RefPtr<FileInfo> aFileInfo) {
|
||||||
stream.get_PIPCBlobInputStreamParent());
|
stream.get_PIPCBlobInputStreamParent());
|
||||||
|
|
||||||
MOZ_ASSERT(!mMappedBlobs.GetWeak(actor->ID()));
|
MOZ_ASSERT(!mMappedBlobs.GetWeak(actor->ID()));
|
||||||
mMappedBlobs.Put(actor->ID(), std::move(aFileInfo));
|
mMappedBlobs.Put(actor->ID(), RefPtr{aFileInfo});
|
||||||
|
|
||||||
RefPtr<UnmapBlobCallback> callback = new UnmapBlobCallback(this);
|
RefPtr<UnmapBlobCallback> callback = new UnmapBlobCallback(this);
|
||||||
actor->SetCallback(callback);
|
actor->SetCallback(callback);
|
||||||
|
@ -16723,14 +16721,6 @@ nsresult FileManager::GetUsage(nsIFile* aDirectory, uint64_t& aUsage) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManager::RemoveFileInfo(const int64_t aId,
|
|
||||||
const MutexAutoLock& aFilesMutexLock) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
aFilesMutexLock.AssertOwns(IndexedDatabaseManager::FileMutex());
|
|
||||||
#endif
|
|
||||||
mFileInfos.Remove(aId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* QuotaClient
|
* QuotaClient
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -17251,7 +17241,7 @@ void QuotaClient::StopIdleMaintenance() {
|
||||||
mCurrentMaintenance->Abort();
|
mCurrentMaintenance->Abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& maintenance : mMaintenanceQueue) {
|
for (RefPtr<Maintenance>& maintenance : mMaintenanceQueue) {
|
||||||
maintenance->Abort();
|
maintenance->Abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19107,17 +19097,11 @@ UpgradeFileIdsFunction::OnFunctionCall(mozIStorageValueArray* aArguments,
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cloneInfoOrError =
|
StructuredCloneReadInfo cloneInfo(JS::StructuredCloneScope::DifferentProcess);
|
||||||
DatabaseOperationBase::GetStructuredCloneReadInfoFromValueArray(
|
DatabaseOperationBase::GetStructuredCloneReadInfoFromValueArray(
|
||||||
aArguments, 1, 0, *mFileManager);
|
aArguments, 1, 0, *mFileManager, &cloneInfo);
|
||||||
if (NS_WARN_IF(cloneInfoOrError.isErr())) {
|
|
||||||
return cloneInfoOrError.unwrapErr();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cloneInfo = cloneInfoOrError.unwrap();
|
|
||||||
|
|
||||||
nsAutoString fileIds;
|
nsAutoString fileIds;
|
||||||
// XXX does this really need non-const cloneInfo?
|
|
||||||
rv = IDBObjectStore::DeserializeUpgradeValueToFileIds(cloneInfo, fileIds);
|
rv = IDBObjectStore::DeserializeUpgradeValueToFileIds(cloneInfo, fileIds);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||||
|
@ -19188,17 +19172,17 @@ uint64_t DatabaseOperationBase::ReinterpretDoubleAsUInt64(double aDouble) {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Result<StructuredCloneReadInfo, nsresult>
|
nsresult DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
|
||||||
DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
|
|
||||||
T* aSource, uint32_t aDataIndex, uint32_t aFileIdsIndex,
|
T* aSource, uint32_t aDataIndex, uint32_t aFileIdsIndex,
|
||||||
const FileManager& aFileManager) {
|
const FileManager& aFileManager, StructuredCloneReadInfo* aInfo) {
|
||||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||||
MOZ_ASSERT(aSource);
|
MOZ_ASSERT(aSource);
|
||||||
|
MOZ_ASSERT(aInfo);
|
||||||
|
|
||||||
int32_t columnType;
|
int32_t columnType;
|
||||||
nsresult rv = aSource->GetTypeOfIndex(aDataIndex, &columnType);
|
nsresult rv = aSource->GetTypeOfIndex(aDataIndex, &columnType);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(columnType == mozIStorageStatement::VALUE_TYPE_BLOB ||
|
MOZ_ASSERT(columnType == mozIStorageStatement::VALUE_TYPE_BLOB ||
|
||||||
|
@ -19207,7 +19191,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
|
||||||
bool isNull;
|
bool isNull;
|
||||||
rv = aSource->GetIsNull(aFileIdsIndex, &isNull);
|
rv = aSource->GetIsNull(aFileIdsIndex, &isNull);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsString fileIds;
|
nsString fileIds;
|
||||||
|
@ -19217,7 +19201,7 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
|
||||||
} else {
|
} else {
|
||||||
rv = aSource->GetString(aFileIdsIndex, fileIds);
|
rv = aSource->GetString(aFileIdsIndex, fileIds);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
return rv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19225,30 +19209,36 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromSource(
|
||||||
uint64_t intData;
|
uint64_t intData;
|
||||||
rv = aSource->GetInt64(aDataIndex, reinterpret_cast<int64_t*>(&intData));
|
rv = aSource->GetInt64(aDataIndex, reinterpret_cast<int64_t*>(&intData));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetStructuredCloneReadInfoFromExternalBlob(intData, aFileManager,
|
rv = GetStructuredCloneReadInfoFromExternalBlob(intData, aFileManager,
|
||||||
fileIds);
|
fileIds, aInfo);
|
||||||
}
|
} else {
|
||||||
|
const uint8_t* blobData;
|
||||||
|
uint32_t blobDataLength;
|
||||||
|
rv = aSource->GetSharedBlob(aDataIndex, &blobDataLength, &blobData);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t* blobData;
|
rv = GetStructuredCloneReadInfoFromBlob(blobData, blobDataLength,
|
||||||
uint32_t blobDataLength;
|
aFileManager, fileIds, aInfo);
|
||||||
rv = aSource->GetSharedBlob(aDataIndex, &blobDataLength, &blobData);
|
}
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetStructuredCloneReadInfoFromBlob(blobData, blobDataLength,
|
return NS_OK;
|
||||||
aFileManager, fileIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Result<StructuredCloneReadInfo, nsresult>
|
nsresult DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
|
||||||
DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
|
|
||||||
const uint8_t* aBlobData, uint32_t aBlobDataLength,
|
const uint8_t* aBlobData, uint32_t aBlobDataLength,
|
||||||
const FileManager& aFileManager, const nsAString& aFileIds) {
|
const FileManager& aFileManager, const nsAString& aFileIds,
|
||||||
|
StructuredCloneReadInfo* aInfo) {
|
||||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||||
|
MOZ_ASSERT(aInfo);
|
||||||
|
|
||||||
AUTO_PROFILER_LABEL(
|
AUTO_PROFILER_LABEL(
|
||||||
"DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob", DOM);
|
"DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob", DOM);
|
||||||
|
@ -19259,12 +19249,12 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
|
||||||
size_t uncompressedLength;
|
size_t uncompressedLength;
|
||||||
if (NS_WARN_IF(!snappy::GetUncompressedLength(compressed, compressedLength,
|
if (NS_WARN_IF(!snappy::GetUncompressedLength(compressed, compressedLength,
|
||||||
&uncompressedLength))) {
|
&uncompressedLength))) {
|
||||||
return Err(NS_ERROR_FILE_CORRUPTED);
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
AutoTArray<uint8_t, 512> uncompressed;
|
AutoTArray<uint8_t, 512> uncompressed;
|
||||||
if (NS_WARN_IF(!uncompressed.SetLength(uncompressedLength, fallible))) {
|
if (NS_WARN_IF(!uncompressed.SetLength(uncompressedLength, fallible))) {
|
||||||
return Err(NS_ERROR_OUT_OF_MEMORY);
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* const uncompressedBuffer =
|
char* const uncompressedBuffer =
|
||||||
|
@ -19272,76 +19262,71 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromBlob(
|
||||||
|
|
||||||
if (NS_WARN_IF(!snappy::RawUncompress(compressed, compressedLength,
|
if (NS_WARN_IF(!snappy::RawUncompress(compressed, compressedLength,
|
||||||
uncompressedBuffer))) {
|
uncompressedBuffer))) {
|
||||||
return Err(NS_ERROR_FILE_CORRUPTED);
|
return NS_ERROR_FILE_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredCloneReadInfo info(JS::StructuredCloneScope::DifferentProcess);
|
if (!aInfo->mData.AppendBytes(uncompressedBuffer, uncompressed.Length())) {
|
||||||
if (!info.mData.AppendBytes(uncompressedBuffer, uncompressed.Length())) {
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
return Err(NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!aFileIds.IsVoid()) {
|
if (!aFileIds.IsVoid()) {
|
||||||
auto filesOrErr = DeserializeStructuredCloneFiles(aFileManager, aFileIds);
|
nsresult rv =
|
||||||
if (NS_WARN_IF(filesOrErr.isErr())) {
|
DeserializeStructuredCloneFiles(aFileManager, aFileIds, aInfo->mFiles);
|
||||||
return Err(filesOrErr.unwrapErr());
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.mFiles = filesOrErr.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Result<StructuredCloneReadInfo, nsresult>
|
nsresult DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob(
|
||||||
DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob(
|
|
||||||
uint64_t aIntData, const FileManager& aFileManager,
|
uint64_t aIntData, const FileManager& aFileManager,
|
||||||
const nsAString& aFileIds) {
|
const nsAString& aFileIds, StructuredCloneReadInfo* aInfo) {
|
||||||
MOZ_ASSERT(!IsOnBackgroundThread());
|
MOZ_ASSERT(!IsOnBackgroundThread());
|
||||||
|
MOZ_ASSERT(aInfo);
|
||||||
|
|
||||||
AUTO_PROFILER_LABEL(
|
AUTO_PROFILER_LABEL(
|
||||||
"DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob", DOM);
|
"DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob", DOM);
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
||||||
StructuredCloneReadInfo info(JS::StructuredCloneScope::DifferentProcess);
|
|
||||||
|
|
||||||
if (!aFileIds.IsVoid()) {
|
if (!aFileIds.IsVoid()) {
|
||||||
auto filesOrErr = DeserializeStructuredCloneFiles(aFileManager, aFileIds);
|
rv = DeserializeStructuredCloneFiles(aFileManager, aFileIds, aInfo->mFiles);
|
||||||
if (NS_WARN_IF(filesOrErr.isErr())) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(filesOrErr.unwrapErr());
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.mFiles = filesOrErr.unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Higher and lower 32 bits described
|
// Higher and lower 32 bits described
|
||||||
// in ObjectStoreAddOrPutRequestOp::DoDatabaseWork.
|
// in ObjectStoreAddOrPutRequestOp::DoDatabaseWork.
|
||||||
const uint32_t index = uint32_t(aIntData & 0xFFFFFFFF);
|
const uint32_t index = uint32_t(aIntData & 0xFFFFFFFF);
|
||||||
|
|
||||||
if (index >= info.mFiles.Length()) {
|
if (index >= aInfo->mFiles.Length()) {
|
||||||
MOZ_ASSERT(false, "Bad index value!");
|
MOZ_ASSERT(false, "Bad index value!");
|
||||||
return Err(NS_ERROR_UNEXPECTED);
|
return NS_ERROR_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IndexedDatabaseManager::PreprocessingEnabled()) {
|
if (IndexedDatabaseManager::PreprocessingEnabled()) {
|
||||||
info.mHasPreprocessInfo = true;
|
aInfo->mHasPreprocessInfo = true;
|
||||||
return info;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
StructuredCloneFile& file = info.mFiles[index];
|
StructuredCloneFile& file = aInfo->mFiles[index];
|
||||||
MOZ_ASSERT(file.Type() == StructuredCloneFile::eStructuredClone);
|
MOZ_ASSERT(file.mFileInfo);
|
||||||
|
MOZ_ASSERT(file.mType == StructuredCloneFile::eStructuredClone);
|
||||||
|
|
||||||
const nsCOMPtr<nsIFile> nativeFile =
|
const nsCOMPtr<nsIFile> nativeFile =
|
||||||
FileInfo::GetFileForFileInfo(file.FileInfo());
|
FileInfo::GetFileForFileInfo(*file.mFileInfo);
|
||||||
if (NS_WARN_IF(!nativeFile)) {
|
if (NS_WARN_IF(!nativeFile)) {
|
||||||
return Err(NS_ERROR_FAILURE);
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> fileInputStream;
|
nsCOMPtr<nsIInputStream> fileInputStream;
|
||||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), nativeFile);
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), nativeFile);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto snappyInputStream =
|
const auto snappyInputStream =
|
||||||
|
@ -19353,19 +19338,20 @@ DatabaseOperationBase::GetStructuredCloneReadInfoFromExternalBlob(
|
||||||
uint32_t numRead;
|
uint32_t numRead;
|
||||||
rv = snappyInputStream->Read(buffer, sizeof(buffer), &numRead);
|
rv = snappyInputStream->Read(buffer, sizeof(buffer), &numRead);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(rv);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!numRead) {
|
if (!numRead) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(!info.mData.AppendBytes(buffer, numRead))) {
|
if (NS_WARN_IF(!aInfo->mData.AppendBytes(buffer, numRead))) {
|
||||||
return Err(NS_ERROR_OUT_OF_MEMORY);
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
return info;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
@ -20050,25 +20036,25 @@ void DatabaseOperationBase::AutoSetProgressHandler::Unregister() {
|
||||||
mConnection = nullptr;
|
mConnection = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableFile::MutableFile(nsIFile* aFile, RefPtr<Database> aDatabase,
|
MutableFile::MutableFile(nsIFile* aFile, Database* aDatabase,
|
||||||
RefPtr<FileInfo> aFileInfo)
|
FileInfo* aFileInfo)
|
||||||
: BackgroundMutableFileParentBase(FILE_HANDLE_STORAGE_IDB, aDatabase->Id(),
|
: BackgroundMutableFileParentBase(FILE_HANDLE_STORAGE_IDB, aDatabase->Id(),
|
||||||
IntString(aFileInfo->Id()), aFile),
|
IntString(aFileInfo->Id()), aFile),
|
||||||
mDatabase(std::move(aDatabase)),
|
mDatabase(aDatabase),
|
||||||
mFileInfo(std::move(aFileInfo)) {
|
mFileInfo(aFileInfo) {
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
MOZ_ASSERT(mDatabase);
|
MOZ_ASSERT(aDatabase);
|
||||||
MOZ_ASSERT(mFileInfo);
|
MOZ_ASSERT(aFileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableFile::~MutableFile() { mDatabase->UnregisterMutableFile(this); }
|
MutableFile::~MutableFile() { mDatabase->UnregisterMutableFile(this); }
|
||||||
|
|
||||||
RefPtr<MutableFile> MutableFile::Create(nsIFile* aFile, Database* aDatabase,
|
RefPtr<MutableFile> MutableFile::Create(nsIFile* aFile, Database* aDatabase,
|
||||||
RefPtr<FileInfo> aFileInfo) {
|
FileInfo* aFileInfo) {
|
||||||
AssertIsOnBackgroundThread();
|
AssertIsOnBackgroundThread();
|
||||||
|
|
||||||
RefPtr<MutableFile> newMutableFile =
|
RefPtr<MutableFile> newMutableFile =
|
||||||
new MutableFile(aFile, aDatabase, std::move(aFileInfo));
|
new MutableFile(aFile, aDatabase, aFileInfo);
|
||||||
|
|
||||||
if (!aDatabase->RegisterMutableFile(newMutableFile)) {
|
if (!aDatabase->RegisterMutableFile(newMutableFile)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -23090,7 +23076,7 @@ void TransactionBase::CommitOp::CommitOrRollbackAutoIncrementCounts() {
|
||||||
mTransaction->GetMode() == IDBTransaction::Mode::Cleanup ||
|
mTransaction->GetMode() == IDBTransaction::Mode::Cleanup ||
|
||||||
mTransaction->GetMode() == IDBTransaction::Mode::VersionChange);
|
mTransaction->GetMode() == IDBTransaction::Mode::VersionChange);
|
||||||
|
|
||||||
const auto& metadataArray =
|
nsTArray<RefPtr<FullObjectStoreMetadata>>& metadataArray =
|
||||||
mTransaction->mModifiedAutoIncrementObjectStoreMetadataArray;
|
mTransaction->mModifiedAutoIncrementObjectStoreMetadataArray;
|
||||||
|
|
||||||
if (!metadataArray.IsEmpty()) {
|
if (!metadataArray.IsEmpty()) {
|
||||||
|
@ -24109,22 +24095,20 @@ CreateIndexOp::UpdateIndexDataValuesFunction::OnFunctionCall(
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto cloneInfoOrErr = GetStructuredCloneReadInfoFromValueArray(
|
StructuredCloneReadInfo cloneInfo(JS::StructuredCloneScope::DifferentProcess);
|
||||||
|
nsresult rv = GetStructuredCloneReadInfoFromValueArray(
|
||||||
aValues,
|
aValues,
|
||||||
/* aDataIndex */ 3,
|
/* aDataIndex */ 3,
|
||||||
/* aFileIdsIndex */ 2, *mOp->mFileManager);
|
/* aFileIdsIndex */ 2, *mOp->mFileManager, &cloneInfo);
|
||||||
if (NS_WARN_IF(cloneInfoOrErr.isErr())) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return Err(cloneInfoOrErr.unwrapErr());
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cloneInfo = cloneInfoOrErr.unwrap();
|
|
||||||
|
|
||||||
const IndexMetadata& metadata = mOp->mMetadata;
|
const IndexMetadata& metadata = mOp->mMetadata;
|
||||||
const IndexOrObjectStoreId& objectStoreId = mOp->mObjectStoreId;
|
const IndexOrObjectStoreId& objectStoreId = mOp->mObjectStoreId;
|
||||||
|
|
||||||
AutoTArray<IndexUpdateInfo, 32> updateInfos;
|
AutoTArray<IndexUpdateInfo, 32> updateInfos;
|
||||||
ErrorResult errorResult;
|
ErrorResult errorResult;
|
||||||
// XXX does this really need a non-const cloneInfo?
|
|
||||||
IDBObjectStore::DeserializeIndexValueToUpdateInfos(
|
IDBObjectStore::DeserializeIndexValueToUpdateInfos(
|
||||||
metadata.id(), metadata.keyPath(), metadata.multiEntry(),
|
metadata.id(), metadata.keyPath(), metadata.multiEntry(),
|
||||||
metadata.locale(), cloneInfo, updateInfos, errorResult);
|
metadata.locale(), cloneInfo, updateInfos, errorResult);
|
||||||
|
@ -24139,7 +24123,7 @@ CreateIndexOp::UpdateIndexDataValuesFunction::OnFunctionCall(
|
||||||
|
|
||||||
// No changes needed, just return the original value.
|
// No changes needed, just return the original value.
|
||||||
int32_t valueType;
|
int32_t valueType;
|
||||||
nsresult rv = aValues->GetTypeOfIndex(1, &valueType);
|
rv = aValues->GetTypeOfIndex(1, &valueType);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -24179,7 +24163,7 @@ CreateIndexOp::UpdateIndexDataValuesFunction::OnFunctionCall(
|
||||||
}
|
}
|
||||||
|
|
||||||
Key key;
|
Key key;
|
||||||
nsresult rv = key.SetFromValueArray(aValues, 0);
|
rv = key.SetFromValueArray(aValues, 0);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -25599,19 +25583,20 @@ nsresult ObjectStoreGetRequestOp::DoDatabaseWork(
|
||||||
|
|
||||||
bool hasResult;
|
bool hasResult;
|
||||||
while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||||
auto cloneInfoOrErr = GetStructuredCloneReadInfoFromStatement(
|
StructuredCloneReadInfo* cloneInfo = mResponse.AppendElement(fallible);
|
||||||
&*stmt, 1, 0, *mDatabase->GetFileManager());
|
if (NS_WARN_IF(!cloneInfo)) {
|
||||||
if (NS_WARN_IF(cloneInfoOrErr.isErr())) {
|
|
||||||
return Err(cloneInfoOrErr.unwrapErr());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cloneInfoOrErr.inspect().mHasPreprocessInfo) {
|
|
||||||
mPreprocessInfoCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_WARN_IF(!mResponse.EmplaceBack(fallible, cloneInfoOrErr.unwrap()))) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = GetStructuredCloneReadInfoFromStatement(
|
||||||
|
&*stmt, 1, 0, *mDatabase->GetFileManager(), cloneInfo);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cloneInfo->mHasPreprocessInfo) {
|
||||||
|
mPreprocessInfoCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
@ -26184,20 +26169,21 @@ nsresult IndexGetRequestOp::DoDatabaseWork(DatabaseConnection* aConnection) {
|
||||||
|
|
||||||
bool hasResult;
|
bool hasResult;
|
||||||
while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
while (NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||||
auto cloneInfoOrErr = GetStructuredCloneReadInfoFromStatement(
|
StructuredCloneReadInfo* cloneInfo = mResponse.AppendElement(fallible);
|
||||||
&*stmt, 1, 0, *mDatabase->GetFileManager());
|
if (NS_WARN_IF(!cloneInfo)) {
|
||||||
if (NS_WARN_IF(cloneInfoOrErr.isErr())) {
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
return cloneInfoOrErr.unwrapErr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cloneInfoOrErr.inspect().mHasPreprocessInfo) {
|
rv = GetStructuredCloneReadInfoFromStatement(
|
||||||
|
&*stmt, 1, 0, *mDatabase->GetFileManager(), cloneInfo);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cloneInfo->mHasPreprocessInfo) {
|
||||||
IDB_WARNING("Preprocessing for indexes not yet implemented!");
|
IDB_WARNING("Preprocessing for indexes not yet implemented!");
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(!mResponse.EmplaceBack(fallible, cloneInfoOrErr.unwrap()))) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
|
|
@ -76,7 +76,7 @@ void FileInfo::UpdateReferences(ThreadSafeAutoRefCnt& aRefCount, int32_t aDelta,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mFileManager->RemoveFileInfo(Id(), lock);
|
mFileManager->mFileInfos.Remove(Id());
|
||||||
|
|
||||||
needsCleanup = !mFileManager->Invalidated();
|
needsCleanup = !mFileManager->Invalidated();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#define mozilla_dom_indexeddb_filemanager_h__
|
#define mozilla_dom_indexeddb_filemanager_h__
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Mutex.h"
|
|
||||||
#include "mozilla/dom/quota/PersistenceType.h"
|
#include "mozilla/dom/quota/PersistenceType.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
|
@ -27,6 +26,8 @@ class FileInfo;
|
||||||
|
|
||||||
// Implemented in ActorsParent.cpp.
|
// Implemented in ActorsParent.cpp.
|
||||||
class FileManager final {
|
class FileManager final {
|
||||||
|
friend class FileInfo;
|
||||||
|
|
||||||
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
typedef mozilla::dom::quota::PersistenceType PersistenceType;
|
||||||
|
|
||||||
const PersistenceType mPersistenceType;
|
const PersistenceType mPersistenceType;
|
||||||
|
@ -92,8 +93,6 @@ class FileManager final {
|
||||||
|
|
||||||
MOZ_MUST_USE RefPtr<FileInfo> CreateFileInfo();
|
MOZ_MUST_USE RefPtr<FileInfo> CreateFileInfo();
|
||||||
|
|
||||||
void RemoveFileInfo(int64_t aId, const MutexAutoLock& aFilesMutexLock);
|
|
||||||
|
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileManager)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileManager)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -746,7 +746,7 @@ void IDBDatabase::AbortTransactions(bool aShouldWarn) {
|
||||||
// additional strong references here.
|
// additional strong references here.
|
||||||
WeakTransactionArray transactionsThatNeedWarning;
|
WeakTransactionArray transactionsThatNeedWarning;
|
||||||
|
|
||||||
for (const auto& transaction : transactionsToAbort) {
|
for (RefPtr<IDBTransaction>& transaction : transactionsToAbort) {
|
||||||
MOZ_ASSERT(transaction);
|
MOZ_ASSERT(transaction);
|
||||||
MOZ_ASSERT(!transaction->IsFinished());
|
MOZ_ASSERT(!transaction->IsFinished());
|
||||||
|
|
||||||
|
@ -778,21 +778,22 @@ void IDBDatabase::AbortTransactions(bool aShouldWarn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PBackgroundIDBDatabaseFileChild* IDBDatabase::GetOrCreateFileActorForBlob(
|
PBackgroundIDBDatabaseFileChild* IDBDatabase::GetOrCreateFileActorForBlob(
|
||||||
Blob& aBlob) {
|
Blob* aBlob) {
|
||||||
AssertIsOnOwningThread();
|
AssertIsOnOwningThread();
|
||||||
|
MOZ_ASSERT(aBlob);
|
||||||
MOZ_ASSERT(mBackgroundActor);
|
MOZ_ASSERT(mBackgroundActor);
|
||||||
|
|
||||||
// We use the File's nsIWeakReference as the key to the table because
|
// We use the File's nsIWeakReference as the key to the table because
|
||||||
// a) it is unique per blob, b) it is reference-counted so that we can
|
// a) it is unique per blob, b) it is reference-counted so that we can
|
||||||
// guarantee that it stays alive, and c) it doesn't hold the actual File
|
// guarantee that it stays alive, and c) it doesn't hold the actual File
|
||||||
// alive.
|
// alive.
|
||||||
nsWeakPtr weakRef = do_GetWeakReference(&aBlob);
|
nsWeakPtr weakRef = do_GetWeakReference(aBlob);
|
||||||
MOZ_ASSERT(weakRef);
|
MOZ_ASSERT(weakRef);
|
||||||
|
|
||||||
PBackgroundIDBDatabaseFileChild* actor = nullptr;
|
PBackgroundIDBDatabaseFileChild* actor = nullptr;
|
||||||
|
|
||||||
if (!mFileActors.Get(weakRef, &actor)) {
|
if (!mFileActors.Get(weakRef, &actor)) {
|
||||||
BlobImpl* blobImpl = aBlob.Impl();
|
BlobImpl* blobImpl = aBlob->Impl();
|
||||||
MOZ_ASSERT(blobImpl);
|
MOZ_ASSERT(blobImpl);
|
||||||
|
|
||||||
PBackgroundChild* backgroundManager =
|
PBackgroundChild* backgroundManager =
|
||||||
|
|
|
@ -160,7 +160,7 @@ class IDBDatabase final : public DOMEventTargetHelper {
|
||||||
void AbortTransactions(bool aShouldWarn);
|
void AbortTransactions(bool aShouldWarn);
|
||||||
|
|
||||||
indexedDB::PBackgroundIDBDatabaseFileChild* GetOrCreateFileActorForBlob(
|
indexedDB::PBackgroundIDBDatabaseFileChild* GetOrCreateFileActorForBlob(
|
||||||
Blob& aBlob);
|
Blob* aBlob);
|
||||||
|
|
||||||
void NoteFinishedFileActor(
|
void NoteFinishedFileActor(
|
||||||
indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor);
|
indexedDB::PBackgroundIDBDatabaseFileChild* aFileActor);
|
||||||
|
|
|
@ -115,7 +115,7 @@ void IDBMutableFile::AbortFileHandles() {
|
||||||
class MOZ_STACK_CLASS Helper final {
|
class MOZ_STACK_CLASS Helper final {
|
||||||
public:
|
public:
|
||||||
static void AbortFileHandles(
|
static void AbortFileHandles(
|
||||||
const nsTHashtable<nsPtrHashKey<IDBFileHandle>>& aTable) {
|
nsTHashtable<nsPtrHashKey<IDBFileHandle>>& aTable) {
|
||||||
if (!aTable.Count()) {
|
if (!aTable.Count()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,8 @@ void IDBMutableFile::AbortFileHandles() {
|
||||||
nsTArray<RefPtr<IDBFileHandle>> fileHandlesToAbort;
|
nsTArray<RefPtr<IDBFileHandle>> fileHandlesToAbort;
|
||||||
fileHandlesToAbort.SetCapacity(aTable.Count());
|
fileHandlesToAbort.SetCapacity(aTable.Count());
|
||||||
|
|
||||||
for (auto iter = aTable.ConstIter(); !iter.Done(); iter.Next()) {
|
for (auto iter = aTable.Iter(); !iter.Done(); iter.Next()) {
|
||||||
IDBFileHandle* const fileHandle = iter.Get()->GetKey();
|
IDBFileHandle* fileHandle = iter.Get()->GetKey();
|
||||||
MOZ_ASSERT(fileHandle);
|
MOZ_ASSERT(fileHandle);
|
||||||
|
|
||||||
fileHandle->AssertIsOnOwningThread();
|
fileHandle->AssertIsOnOwningThread();
|
||||||
|
@ -139,7 +139,7 @@ void IDBMutableFile::AbortFileHandles() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& fileHandle : fileHandlesToAbort) {
|
for (RefPtr<IDBFileHandle>& fileHandle : fileHandlesToAbort) {
|
||||||
MOZ_ASSERT(fileHandle);
|
MOZ_ASSERT(fileHandle);
|
||||||
|
|
||||||
fileHandle->Abort();
|
fileHandle->Abort();
|
||||||
|
|
|
@ -441,6 +441,13 @@ nsresult GetAddInfoCallback(JSContext* aCx, void* aClosure) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResolveMysteryMutableFile(IDBMutableFile* aMutableFile,
|
||||||
|
const nsString& aName, const nsString& aType) {
|
||||||
|
MOZ_ASSERT(aMutableFile);
|
||||||
|
aMutableFile->SetLazyData(aName, aType);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool StructuredCloneReadString(JSStructuredCloneReader* aReader,
|
bool StructuredCloneReadString(JSStructuredCloneReader* aReader,
|
||||||
nsCString& aString) {
|
nsCString& aString) {
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
|
@ -560,25 +567,6 @@ bool ReadWasmModule(JSStructuredCloneReader* aReader, WasmModuleData* aRetval) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool WrapAsJSObject(JSContext* const aCx, T& aBaseObject,
|
|
||||||
JS::MutableHandle<JSObject*> aResult) {
|
|
||||||
JS::Rooted<JS::Value> wrappedValue(aCx);
|
|
||||||
if (!ToJSValue(aCx, aBaseObject, &wrappedValue)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
aResult.set(&wrappedValue.toObject());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
JSObject* WrapAsJSObject(JSContext* const aCx, T& aBaseObject) {
|
|
||||||
JS::Rooted<JSObject*> result(aCx);
|
|
||||||
const bool res = WrapAsJSObject(aCx, aBaseObject, &result);
|
|
||||||
return res ? static_cast<JSObject*>(result) : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ValueDeserializationHelper {
|
class ValueDeserializationHelper {
|
||||||
public:
|
public:
|
||||||
static bool CreateAndWrapMutableFile(JSContext* aCx,
|
static bool CreateAndWrapMutableFile(JSContext* aCx,
|
||||||
|
@ -588,10 +576,10 @@ class ValueDeserializationHelper {
|
||||||
MOZ_ASSERT(aCx);
|
MOZ_ASSERT(aCx);
|
||||||
|
|
||||||
// If we have eBlob, we are in an IDB SQLite schema upgrade where we don't
|
// If we have eBlob, we are in an IDB SQLite schema upgrade where we don't
|
||||||
// care about a real 'MutableFile', but we just care of having a proper
|
// care about a real 'MutableFile', but we just care of having a propert
|
||||||
// |mType| flag.
|
// |mType| flag.
|
||||||
if (aFile.Type() == StructuredCloneFile::eBlob) {
|
if (aFile.mType == StructuredCloneFile::eBlob) {
|
||||||
aFile.MutateType(StructuredCloneFile::eMutableFile);
|
aFile.mType = StructuredCloneFile::eMutableFile;
|
||||||
|
|
||||||
// Just make a dummy object.
|
// Just make a dummy object.
|
||||||
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
|
JS::Rooted<JSObject*> obj(aCx, JS_NewPlainObject(aCx));
|
||||||
|
@ -604,15 +592,24 @@ class ValueDeserializationHelper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eMutableFile);
|
MOZ_ASSERT(aFile.mType == StructuredCloneFile::eMutableFile);
|
||||||
|
|
||||||
if (!aFile.HasMutableFile() || !NS_IsMainThread()) {
|
if (!aFile.mMutableFile || !NS_IsMainThread()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aFile.MutableMutableFile().SetLazyData(aData.name, aData.type);
|
if (NS_WARN_IF(!ResolveMysteryMutableFile(aFile.mMutableFile, aData.name,
|
||||||
|
aData.type))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return WrapAsJSObject(aCx, aFile.MutableMutableFile(), aResult);
|
JS::Rooted<JS::Value> wrappedMutableFile(aCx);
|
||||||
|
if (!ToJSValue(aCx, aFile.mMutableFile, &wrappedMutableFile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
aResult.set(&wrappedMutableFile.toObject());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CreateAndWrapBlobOrFile(JSContext* aCx, IDBDatabase* aDatabase,
|
static bool CreateAndWrapBlobOrFile(JSContext* aCx, IDBDatabase* aDatabase,
|
||||||
|
@ -623,51 +620,50 @@ class ValueDeserializationHelper {
|
||||||
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
|
MOZ_ASSERT(aData.tag == SCTAG_DOM_FILE ||
|
||||||
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
|
aData.tag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
|
||||||
aData.tag == SCTAG_DOM_BLOB);
|
aData.tag == SCTAG_DOM_BLOB);
|
||||||
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eBlob);
|
MOZ_ASSERT(aFile.mType == StructuredCloneFile::eBlob);
|
||||||
|
|
||||||
const auto blob = [&aFile, aDatabase, aCx]() -> RefPtr<Blob> {
|
RefPtr<Blob> blob = aFile.mBlob;
|
||||||
if (aFile.HasBlob()) {
|
|
||||||
return aFile.BlobPtr();
|
// It can happen that this IDB is chrome code, so there is no parent, but
|
||||||
|
// still we want to set a correct parent for the new File object.
|
||||||
|
nsCOMPtr<nsIGlobalObject> global;
|
||||||
|
if (NS_IsMainThread()) {
|
||||||
|
if (aDatabase && aDatabase->GetParentObject()) {
|
||||||
|
global = aDatabase->GetParentObject();
|
||||||
|
} else {
|
||||||
|
global = xpc::CurrentNativeGlobal(aCx);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||||
|
MOZ_ASSERT(workerPrivate);
|
||||||
|
|
||||||
// It can happen that this IDB is chrome code, so there is no parent, but
|
WorkerGlobalScope* globalScope = workerPrivate->GlobalScope();
|
||||||
// still we want to set a correct parent for the new File object.
|
MOZ_ASSERT(globalScope);
|
||||||
const auto global = [aDatabase, aCx]() -> nsCOMPtr<nsIGlobalObject> {
|
|
||||||
if (NS_IsMainThread()) {
|
|
||||||
if (aDatabase && aDatabase->GetParentObject()) {
|
|
||||||
return aDatabase->GetParentObject();
|
|
||||||
}
|
|
||||||
return xpc::CurrentNativeGlobal(aCx);
|
|
||||||
}
|
|
||||||
const WorkerPrivate* const workerPrivate =
|
|
||||||
GetCurrentThreadWorkerPrivate();
|
|
||||||
MOZ_ASSERT(workerPrivate);
|
|
||||||
|
|
||||||
WorkerGlobalScope* const globalScope = workerPrivate->GlobalScope();
|
global = do_QueryObject(globalScope);
|
||||||
MOZ_ASSERT(globalScope);
|
}
|
||||||
|
|
||||||
return do_QueryObject(globalScope);
|
MOZ_ASSERT(global);
|
||||||
}();
|
|
||||||
|
|
||||||
MOZ_ASSERT(global);
|
/* If we are creating an index, we do not have an mBlob but do have an
|
||||||
|
* mInfo. Unlike other index or upgrade cases, we do need a real-looking
|
||||||
/* If we are creating an index, we do not have an mBlob but do have an
|
* Blob/File instance because the index's key path can reference their
|
||||||
* FileInfo. Unlike other index or upgrade cases, we do need a
|
* properties. Rather than create a fake-looking object, create a real
|
||||||
* real-looking Blob/File instance because the index's key path can
|
* Blob. */
|
||||||
* reference their properties. Rather than create a fake-looking object,
|
if (!blob) {
|
||||||
* create a real Blob. */
|
MOZ_ASSERT(aFile.mFileInfo);
|
||||||
const nsCOMPtr<nsIFile> file =
|
const nsCOMPtr<nsIFile> file =
|
||||||
FileInfo::GetFileForFileInfo(aFile.FileInfo());
|
FileInfo::GetFileForFileInfo(*aFile.mFileInfo);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return nullptr;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto impl = MakeRefPtr<FileBlobImpl>(file);
|
const RefPtr<FileBlobImpl> impl = new FileBlobImpl(file);
|
||||||
impl->SetFileId(aFile.FileInfo().Id());
|
impl->SetFileId(aFile.mFileInfo->Id());
|
||||||
return File::Create(global, impl);
|
blob = File::Create(global, impl);
|
||||||
}();
|
if (NS_WARN_IF(!blob)) {
|
||||||
if (NS_WARN_IF(!blob)) {
|
return false;
|
||||||
return false;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aData.tag == SCTAG_DOM_BLOB) {
|
if (aData.tag == SCTAG_DOM_BLOB) {
|
||||||
|
@ -688,7 +684,14 @@ class ValueDeserializationHelper {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return WrapAsJSObject(aCx, exposedBlob, aResult);
|
MOZ_ASSERT(exposedBlob);
|
||||||
|
JS::Rooted<JS::Value> wrappedBlob(aCx);
|
||||||
|
if (!ToJSValue(aCx, exposedBlob, &wrappedBlob)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
aResult.set(&wrappedBlob.toObject());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
blob->Impl()->SetLazyData(aData.name, aData.type, aData.size,
|
blob->Impl()->SetLazyData(aData.name, aData.type, aData.size,
|
||||||
|
@ -698,7 +701,13 @@ class ValueDeserializationHelper {
|
||||||
const RefPtr<File> file = blob->ToFile();
|
const RefPtr<File> file = blob->ToFile();
|
||||||
MOZ_ASSERT(file);
|
MOZ_ASSERT(file);
|
||||||
|
|
||||||
return WrapAsJSObject(aCx, file, aResult);
|
JS::Rooted<JS::Value> wrappedFile(aCx);
|
||||||
|
if (!ToJSValue(aCx, file, &wrappedFile)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
aResult.set(&wrappedFile.toObject());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CreateAndWrapWasmModule(JSContext* aCx,
|
static bool CreateAndWrapWasmModule(JSContext* aCx,
|
||||||
|
@ -706,8 +715,8 @@ class ValueDeserializationHelper {
|
||||||
const WasmModuleData& aData,
|
const WasmModuleData& aData,
|
||||||
JS::MutableHandle<JSObject*> aResult) {
|
JS::MutableHandle<JSObject*> aResult) {
|
||||||
MOZ_ASSERT(aCx);
|
MOZ_ASSERT(aCx);
|
||||||
MOZ_ASSERT(aFile.Type() == StructuredCloneFile::eWasmBytecode);
|
MOZ_ASSERT(aFile.mType == StructuredCloneFile::eWasmBytecode);
|
||||||
MOZ_ASSERT(!aFile.HasBlob());
|
MOZ_ASSERT(!aFile.mBlob);
|
||||||
|
|
||||||
// Just create a plain object here, support for de-serialization of
|
// Just create a plain object here, support for de-serialization of
|
||||||
// WebAssembly.Modules has been removed in bug 1561876. Full removal is
|
// WebAssembly.Modules has been removed in bug 1561876. Full removal is
|
||||||
|
@ -818,6 +827,8 @@ JSObject* CopyingStructuredCloneReadCallback(
|
||||||
auto* const cloneInfo =
|
auto* const cloneInfo =
|
||||||
static_cast<IDBObjectStore::StructuredCloneInfo*>(aClosure);
|
static_cast<IDBObjectStore::StructuredCloneInfo*>(aClosure);
|
||||||
|
|
||||||
|
JS::Rooted<JSObject*> result(aCx);
|
||||||
|
|
||||||
if (aData >= cloneInfo->mFiles.Length()) {
|
if (aData >= cloneInfo->mFiles.Length()) {
|
||||||
MOZ_ASSERT(false, "Bad index value!");
|
MOZ_ASSERT(false, "Bad index value!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -825,40 +836,53 @@ JSObject* CopyingStructuredCloneReadCallback(
|
||||||
|
|
||||||
StructuredCloneFile& file = cloneInfo->mFiles[aData];
|
StructuredCloneFile& file = cloneInfo->mFiles[aData];
|
||||||
|
|
||||||
switch (aTag) {
|
if (aTag == SCTAG_DOM_BLOB) {
|
||||||
case SCTAG_DOM_BLOB:
|
MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob);
|
||||||
MOZ_ASSERT(file.Type() == StructuredCloneFile::eBlob);
|
MOZ_ASSERT(!file.mBlob->IsFile());
|
||||||
MOZ_ASSERT(!file.Blob().IsFile());
|
|
||||||
|
|
||||||
return WrapAsJSObject(aCx, file.MutableBlob());
|
JS::Rooted<JS::Value> wrappedBlob(aCx);
|
||||||
|
if (NS_WARN_IF(!ToJSValue(aCx, file.mBlob, &wrappedBlob))) {
|
||||||
case SCTAG_DOM_FILE: {
|
return nullptr;
|
||||||
MOZ_ASSERT(file.Type() == StructuredCloneFile::eBlob);
|
|
||||||
|
|
||||||
JS::Rooted<JSObject*> result(aCx);
|
|
||||||
|
|
||||||
{
|
|
||||||
// Create a scope so ~RefPtr fires before returning an unwrapped
|
|
||||||
// JS::Value.
|
|
||||||
const RefPtr<Blob> blob = file.BlobPtr();
|
|
||||||
MOZ_ASSERT(blob->IsFile());
|
|
||||||
|
|
||||||
const RefPtr<File> file = blob->ToFile();
|
|
||||||
MOZ_ASSERT(file);
|
|
||||||
|
|
||||||
if (!WrapAsJSObject(aCx, file, &result)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case SCTAG_DOM_MUTABLEFILE:
|
result.set(&wrappedBlob.toObject());
|
||||||
MOZ_ASSERT(file.Type() == StructuredCloneFile::eMutableFile);
|
|
||||||
|
|
||||||
return WrapAsJSObject(aCx, file.MutableMutableFile());
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aTag == SCTAG_DOM_FILE) {
|
||||||
|
MOZ_ASSERT(file.mType == StructuredCloneFile::eBlob);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Create a scope so ~RefPtr fires before returning an unwrapped
|
||||||
|
// JS::Value.
|
||||||
|
const RefPtr<Blob> blob = file.mBlob;
|
||||||
|
MOZ_ASSERT(blob->IsFile());
|
||||||
|
|
||||||
|
const RefPtr<File> file = blob->ToFile();
|
||||||
|
MOZ_ASSERT(file);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> wrappedFile(aCx);
|
||||||
|
if (NS_WARN_IF(!ToJSValue(aCx, file, &wrappedFile))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.set(&wrappedFile.toObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(file.mType == StructuredCloneFile::eMutableFile);
|
||||||
|
|
||||||
|
JS::Rooted<JS::Value> wrappedMutableFile(aCx);
|
||||||
|
if (NS_WARN_IF(!ToJSValue(aCx, file.mMutableFile, &wrappedMutableFile))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.set(&wrappedMutableFile.toObject());
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StructuredCloneHolder::ReadFullySerializableObjects(aCx, aReader,
|
return StructuredCloneHolder::ReadFullySerializableObjects(aCx, aReader,
|
||||||
|
@ -1317,13 +1341,14 @@ class DeserializeUpgradeValueHelper final : public Runnable {
|
||||||
for (uint32_t count = mCloneReadInfo.mFiles.Length(), index = 0;
|
for (uint32_t count = mCloneReadInfo.mFiles.Length(), index = 0;
|
||||||
index < count; index++) {
|
index < count; index++) {
|
||||||
const StructuredCloneFile& file = mCloneReadInfo.mFiles[index];
|
const StructuredCloneFile& file = mCloneReadInfo.mFiles[index];
|
||||||
|
MOZ_ASSERT(file.mFileInfo);
|
||||||
|
|
||||||
const int64_t id = file.FileInfo().Id();
|
const int64_t id = file.mFileInfo->Id();
|
||||||
|
|
||||||
if (index) {
|
if (index) {
|
||||||
aFileIds.Append(' ');
|
aFileIds.Append(' ');
|
||||||
}
|
}
|
||||||
aFileIds.AppendInt(file.Type() == StructuredCloneFile::eBlob ? id : -id);
|
aFileIds.AppendInt(file.mType == StructuredCloneFile::eBlob ? id : -id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,13 +1586,13 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
|
||||||
FileAddInfo* const fileAddInfo = fileAddInfos.AppendElement(fallible);
|
FileAddInfo* const fileAddInfo = fileAddInfos.AppendElement(fallible);
|
||||||
MOZ_ASSERT(fileAddInfo);
|
MOZ_ASSERT(fileAddInfo);
|
||||||
|
|
||||||
switch (file.Type()) {
|
switch (file.mType) {
|
||||||
case StructuredCloneFile::eBlob: {
|
case StructuredCloneFile::eBlob: {
|
||||||
MOZ_ASSERT(file.HasBlob());
|
MOZ_ASSERT(file.mBlob);
|
||||||
MOZ_ASSERT(!file.HasMutableFile());
|
MOZ_ASSERT(!file.mMutableFile);
|
||||||
|
|
||||||
PBackgroundIDBDatabaseFileChild* const fileActor =
|
PBackgroundIDBDatabaseFileChild* const fileActor =
|
||||||
database->GetOrCreateFileActorForBlob(file.MutableBlob());
|
database->GetOrCreateFileActorForBlob(file.mBlob);
|
||||||
if (NS_WARN_IF(!fileActor)) {
|
if (NS_WARN_IF(!fileActor)) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
aRv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
aRv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
@ -1581,11 +1606,11 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
case StructuredCloneFile::eMutableFile: {
|
case StructuredCloneFile::eMutableFile: {
|
||||||
MOZ_ASSERT(file.HasMutableFile());
|
MOZ_ASSERT(file.mMutableFile);
|
||||||
MOZ_ASSERT(!file.HasBlob());
|
MOZ_ASSERT(!file.mBlob);
|
||||||
|
|
||||||
PBackgroundMutableFileChild* const mutableFileActor =
|
PBackgroundMutableFileChild* const mutableFileActor =
|
||||||
file.MutableFile().GetBackgroundActor();
|
file.mMutableFile->GetBackgroundActor();
|
||||||
if (NS_WARN_IF(!mutableFileActor)) {
|
if (NS_WARN_IF(!mutableFileActor)) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
aRv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
aRv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
@ -1600,11 +1625,11 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
|
||||||
|
|
||||||
case StructuredCloneFile::eWasmBytecode:
|
case StructuredCloneFile::eWasmBytecode:
|
||||||
case StructuredCloneFile::eWasmCompiled: {
|
case StructuredCloneFile::eWasmCompiled: {
|
||||||
MOZ_ASSERT(file.HasBlob());
|
MOZ_ASSERT(file.mBlob);
|
||||||
MOZ_ASSERT(!file.HasMutableFile());
|
MOZ_ASSERT(!file.mMutableFile);
|
||||||
|
|
||||||
PBackgroundIDBDatabaseFileChild* const fileActor =
|
PBackgroundIDBDatabaseFileChild* const fileActor =
|
||||||
database->GetOrCreateFileActorForBlob(file.MutableBlob());
|
database->GetOrCreateFileActorForBlob(file.mBlob);
|
||||||
if (NS_WARN_IF(!fileActor)) {
|
if (NS_WARN_IF(!fileActor)) {
|
||||||
IDB_REPORT_INTERNAL_ERR();
|
IDB_REPORT_INTERNAL_ERR();
|
||||||
aRv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
aRv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||||
|
@ -1612,7 +1637,7 @@ RefPtr<IDBRequest> IDBObjectStore::AddOrPut(JSContext* aCx,
|
||||||
}
|
}
|
||||||
|
|
||||||
fileAddInfo->file() = fileActor;
|
fileAddInfo->file() = fileActor;
|
||||||
fileAddInfo->type() = file.Type();
|
fileAddInfo->type() = file.mType;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,8 @@
|
||||||
#define mozilla_dom_indexeddatabase_h__
|
#define mozilla_dom_indexeddatabase_h__
|
||||||
|
|
||||||
#include "js/StructuredClone.h"
|
#include "js/StructuredClone.h"
|
||||||
#include "mozilla/Variant.h"
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "InitializedOnce.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -35,24 +33,13 @@ struct StructuredCloneFile {
|
||||||
eEndGuard
|
eEndGuard
|
||||||
};
|
};
|
||||||
|
|
||||||
StructuredCloneFile(const StructuredCloneFile&) = delete;
|
RefPtr<Blob> mBlob;
|
||||||
StructuredCloneFile& operator=(const StructuredCloneFile&) = delete;
|
RefPtr<IDBMutableFile> mMutableFile;
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
RefPtr<FileInfo> mFileInfo;
|
||||||
// In IndexedDatabaseInlines.h
|
FileType mType;
|
||||||
StructuredCloneFile(StructuredCloneFile&&);
|
|
||||||
#else
|
|
||||||
StructuredCloneFile(StructuredCloneFile&&) = default;
|
|
||||||
#endif
|
|
||||||
StructuredCloneFile& operator=(StructuredCloneFile&&) = delete;
|
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
// In IndexedDatabaseInlines.h
|
||||||
inline explicit StructuredCloneFile(FileType aType);
|
inline explicit StructuredCloneFile(FileType aType, RefPtr<Blob> aBlob = {});
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
|
||||||
inline StructuredCloneFile(FileType aType, RefPtr<Blob> aBlob);
|
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
|
||||||
inline StructuredCloneFile(FileType aType, RefPtr<FileInfo> aFileInfo);
|
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
// In IndexedDatabaseInlines.h
|
||||||
inline explicit StructuredCloneFile(RefPtr<IDBMutableFile> aMutableFile);
|
inline explicit StructuredCloneFile(RefPtr<IDBMutableFile> aMutableFile);
|
||||||
|
@ -62,52 +49,6 @@ struct StructuredCloneFile {
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
// In IndexedDatabaseInlines.h
|
||||||
inline bool operator==(const StructuredCloneFile& aOther) const;
|
inline bool operator==(const StructuredCloneFile& aOther) const;
|
||||||
|
|
||||||
// XXX This is only needed for a schema upgrade (UpgradeSchemaFrom19_0To20_0).
|
|
||||||
// If support for older schemas is dropped, we can probably remove this method
|
|
||||||
// and make mType const.
|
|
||||||
void MutateType(FileType aNewType) { mType = aNewType; }
|
|
||||||
|
|
||||||
FileType Type() const { return mType; }
|
|
||||||
|
|
||||||
const indexedDB::FileInfo& FileInfo() const {
|
|
||||||
return *mContents->as<RefPtr<indexedDB::FileInfo>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
|
||||||
RefPtr<indexedDB::FileInfo> FileInfoPtr() const;
|
|
||||||
|
|
||||||
const dom::Blob& Blob() const { return *mContents->as<RefPtr<dom::Blob>>(); }
|
|
||||||
|
|
||||||
// XXX This is currently used for a number of reasons. Bug 1620560 will remove
|
|
||||||
// the need for one of them, but the uses of do_GetWeakReference in
|
|
||||||
// IDBDatabase::GetOrCreateFileActorForBlob and WrapAsJSObject in
|
|
||||||
// CopyingStructuredCloneReadCallback are probably harder to change.
|
|
||||||
dom::Blob& MutableBlob() const { return *mContents->as<RefPtr<dom::Blob>>(); }
|
|
||||||
|
|
||||||
// In IndexedDatabaseInlines.h
|
|
||||||
inline RefPtr<dom::Blob> BlobPtr() const;
|
|
||||||
|
|
||||||
bool HasBlob() const { return mContents->is<RefPtr<dom::Blob>>(); }
|
|
||||||
|
|
||||||
const IDBMutableFile& MutableFile() const {
|
|
||||||
return *mContents->as<RefPtr<IDBMutableFile>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
IDBMutableFile& MutableMutableFile() const {
|
|
||||||
return *mContents->as<RefPtr<IDBMutableFile>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasMutableFile() const {
|
|
||||||
return mContents->is<RefPtr<IDBMutableFile>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
InitializedOnce<
|
|
||||||
const Variant<Nothing, RefPtr<dom::Blob>, RefPtr<IDBMutableFile>,
|
|
||||||
RefPtr<indexedDB::FileInfo>>>
|
|
||||||
mContents;
|
|
||||||
FileType mType;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StructuredCloneReadInfo {
|
struct StructuredCloneReadInfo {
|
||||||
|
|
|
@ -21,55 +21,27 @@ namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
namespace indexedDB {
|
namespace indexedDB {
|
||||||
|
|
||||||
inline StructuredCloneFile::StructuredCloneFile(FileType aType)
|
|
||||||
: mContents{Nothing()}, mType{aType} {
|
|
||||||
MOZ_COUNT_CTOR(StructuredCloneFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline StructuredCloneFile::StructuredCloneFile(FileType aType,
|
inline StructuredCloneFile::StructuredCloneFile(FileType aType,
|
||||||
RefPtr<dom::Blob> aBlob)
|
RefPtr<Blob> aBlob)
|
||||||
: mContents{std::move(aBlob)}, mType{aType} {
|
: mBlob{std::move(aBlob)}, mType{aType} {
|
||||||
MOZ_ASSERT(eBlob == aType || eStructuredClone == aType);
|
|
||||||
MOZ_ASSERT(mContents->as<RefPtr<dom::Blob>>());
|
|
||||||
MOZ_COUNT_CTOR(StructuredCloneFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline StructuredCloneFile::StructuredCloneFile(
|
|
||||||
FileType aType, RefPtr<indexedDB::FileInfo> aFileInfo)
|
|
||||||
: mContents{std::move(aFileInfo)}, mType{aType} {
|
|
||||||
MOZ_ASSERT(mContents->as<RefPtr<indexedDB::FileInfo>>());
|
|
||||||
MOZ_COUNT_CTOR(StructuredCloneFile);
|
MOZ_COUNT_CTOR(StructuredCloneFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StructuredCloneFile::StructuredCloneFile(
|
inline StructuredCloneFile::StructuredCloneFile(
|
||||||
RefPtr<IDBMutableFile> aMutableFile)
|
RefPtr<IDBMutableFile> aMutableFile)
|
||||||
: mContents{std::move(aMutableFile)}, mType{eMutableFile} {
|
: mMutableFile{std::move(aMutableFile)}, mType{eMutableFile} {
|
||||||
MOZ_ASSERT(mContents->as<RefPtr<IDBMutableFile>>());
|
|
||||||
MOZ_COUNT_CTOR(StructuredCloneFile);
|
MOZ_COUNT_CTOR(StructuredCloneFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
|
||||||
inline StructuredCloneFile::StructuredCloneFile(StructuredCloneFile&& aOther)
|
|
||||||
: mContents{std::move(aOther.mContents)}, mType{aOther.mType} {
|
|
||||||
MOZ_COUNT_CTOR(StructuredCloneFile);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline StructuredCloneFile::~StructuredCloneFile() {
|
inline StructuredCloneFile::~StructuredCloneFile() {
|
||||||
MOZ_COUNT_DTOR(StructuredCloneFile);
|
MOZ_COUNT_DTOR(StructuredCloneFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline RefPtr<indexedDB::FileInfo> StructuredCloneFile::FileInfoPtr() const {
|
|
||||||
return mContents->as<RefPtr<indexedDB::FileInfo>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline RefPtr<dom::Blob> StructuredCloneFile::BlobPtr() const {
|
|
||||||
return mContents->as<RefPtr<dom::Blob>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool StructuredCloneFile::operator==(
|
inline bool StructuredCloneFile::operator==(
|
||||||
const StructuredCloneFile& aOther) const {
|
const StructuredCloneFile& aOther) const {
|
||||||
return this->mType == aOther.mType && *this->mContents == *aOther.mContents;
|
return this->mBlob == aOther.mBlob &&
|
||||||
|
this->mMutableFile == aOther.mMutableFile &&
|
||||||
|
this->mFileInfo == aOther.mFileInfo && this->mType == aOther.mType;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline StructuredCloneReadInfo::StructuredCloneReadInfo(
|
inline StructuredCloneReadInfo::StructuredCloneReadInfo(
|
||||||
|
|
Загрузка…
Ссылка в новой задаче