Bug 1556358 - Allow FormData::ForEach to take a closure instead of a raw function pointer. r=edgar

Depends on D174114

Differential Revision: https://phabricator.services.mozilla.com/D175542
This commit is contained in:
Adam Vandolder 2023-06-16 18:20:48 +00:00
Родитель 216d5131c8
Коммит 0bf288bb5c
2 изменённых файлов: 27 добавлений и 44 удалений

Просмотреть файл

@ -127,18 +127,17 @@ class FormData final : public nsISupports,
virtual nsresult AddNameDirectoryPair(const nsAString& aName,
Directory* aDirectory) override;
using FormDataEntryCallback =
bool (*)(const nsString& aName,
const OwningBlobOrDirectoryOrUSVString& aValue, void* aClosure);
uint32_t Length() const { return mFormData.Length(); }
// Stops iteration and returns false if any invocation of callback returns
// false. Returns true otherwise.
bool ForEach(FormDataEntryCallback aFunc, void* aClosure) {
// Accepts callbacks of the form `bool(const nsString&, const
// OwningBlobOrDirectoryOrUSVString&)`.
template <typename F>
bool ForEach(F&& aCallback) {
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
FormDataTuple& tuple = mFormData[i];
if (!aFunc(tuple.name, tuple.value, aClosure)) {
if (!aCallback(tuple.name, tuple.value)) {
return false;
}
}

Просмотреть файл

@ -896,52 +896,36 @@ bool WriteFormData(JSStructuredCloneWriter* aWriter, FormData* aFormData,
return false;
}
class MOZ_STACK_CLASS Closure final {
JSStructuredCloneWriter* mWriter;
StructuredCloneHolder* mHolder;
auto write = [aWriter, aHolder](
const nsString& aName,
const OwningBlobOrDirectoryOrUSVString& aValue) {
if (!StructuredCloneHolder::WriteString(aWriter, aName)) {
return false;
}
public:
Closure(JSStructuredCloneWriter* aWriter, StructuredCloneHolder* aHolder)
: mWriter(aWriter), mHolder(aHolder) {}
static bool Write(const nsString& aName,
const OwningBlobOrDirectoryOrUSVString& aValue,
void* aClosure) {
Closure* closure = static_cast<Closure*>(aClosure);
if (!StructuredCloneHolder::WriteString(closure->mWriter, aName)) {
if (aValue.IsBlob()) {
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_BLOB,
aHolder->BlobImpls().Length())) {
return false;
}
if (aValue.IsBlob()) {
if (!JS_WriteUint32Pair(closure->mWriter, SCTAG_DOM_BLOB,
closure->mHolder->BlobImpls().Length())) {
return false;
}
RefPtr<BlobImpl> blobImpl = aValue.GetAsBlob()->Impl();
closure->mHolder->BlobImpls().AppendElement(blobImpl);
return true;
}
if (aValue.IsDirectory()) {
Directory* directory = aValue.GetAsDirectory();
return WriteDirectory(closure->mWriter, directory);
}
size_t charSize = sizeof(nsString::char_type);
if (!JS_WriteUint32Pair(closure->mWriter, 0,
aValue.GetAsUSVString().Length()) ||
!JS_WriteBytes(closure->mWriter, aValue.GetAsUSVString().get(),
aValue.GetAsUSVString().Length() * charSize)) {
return false;
}
RefPtr<BlobImpl> blobImpl = aValue.GetAsBlob()->Impl();
aHolder->BlobImpls().AppendElement(blobImpl);
return true;
}
if (aValue.IsDirectory()) {
Directory* directory = aValue.GetAsDirectory();
return WriteDirectory(aWriter, directory);
}
const size_t charSize = sizeof(nsString::char_type);
return JS_WriteUint32Pair(aWriter, 0, aValue.GetAsUSVString().Length()) &&
JS_WriteBytes(aWriter, aValue.GetAsUSVString().get(),
aValue.GetAsUSVString().Length() * charSize);
};
Closure closure(aWriter, aHolder);
return aFormData->ForEach(Closure::Write, &closure);
return aFormData->ForEach(write);
}
JSObject* ReadWasmModule(JSContext* aCx, uint32_t aIndex,