98 lines
3.6 KiB
C++
98 lines
3.6 KiB
C++
/*
|
|
* Copyright (C) 2020 Apple Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include "ShareDataReader.h"
|
|
|
|
#include "BlobLoader.h"
|
|
#include "Document.h"
|
|
#include "SharedBuffer.h"
|
|
|
|
namespace WebCore {
|
|
|
|
ShareDataReader::ShareDataReader(CompletionHandler<void(ExceptionOr<ShareDataWithParsedURL&>)>&& completionHandler)
|
|
: m_completionHandler(WTFMove(completionHandler))
|
|
{
|
|
|
|
}
|
|
|
|
ShareDataReader::~ShareDataReader()
|
|
{
|
|
cancel();
|
|
}
|
|
|
|
void ShareDataReader::start(Document* document, ShareDataWithParsedURL&& shareData)
|
|
{
|
|
m_filesReadSoFar = 0;
|
|
m_shareData = WTFMove(shareData);
|
|
int count = 0;
|
|
m_pendingFileLoads.reserveInitialCapacity(m_shareData.shareData.files.size());
|
|
for (auto& blob : m_shareData.shareData.files) {
|
|
m_pendingFileLoads.uncheckedAppend(makeUniqueRef<BlobLoader>([this, count, fileName = blob->name()](BlobLoader&) {
|
|
this->didFinishLoading(count, fileName);
|
|
}));
|
|
m_pendingFileLoads.last()->start(*blob, document, FileReaderLoader::ReadAsArrayBuffer);
|
|
++count;
|
|
}
|
|
}
|
|
|
|
void ShareDataReader::didFinishLoading(int loadIndex, const String& fileName)
|
|
{
|
|
if (m_pendingFileLoads.isEmpty()) {
|
|
// cancel() was called.
|
|
return;
|
|
}
|
|
|
|
if (m_pendingFileLoads[loadIndex]->errorCode()) {
|
|
if (auto completionHandler = std::exchange(m_completionHandler, { }))
|
|
completionHandler(Exception { AbortError, "Abort due to error while reading files."_s });
|
|
cancel();
|
|
return;
|
|
}
|
|
|
|
auto arrayBuffer = m_pendingFileLoads[loadIndex]->arrayBufferResult();
|
|
|
|
RawFile file;
|
|
file.fileName = fileName;
|
|
file.fileData = SharedBuffer::create(static_cast<const unsigned char*>(arrayBuffer->data()), arrayBuffer->byteLength());
|
|
m_shareData.files.append(WTFMove(file));
|
|
m_filesReadSoFar++;
|
|
|
|
if (m_filesReadSoFar == static_cast<int>(m_pendingFileLoads.size())) {
|
|
m_pendingFileLoads.clear();
|
|
if (auto completionHandler = std::exchange(m_completionHandler, { }))
|
|
completionHandler(m_shareData);
|
|
}
|
|
}
|
|
|
|
void ShareDataReader::cancel()
|
|
{
|
|
// Don't call m_pendingFileLoads.clear() here since destroying a BlobLoader will cause its completion handler
|
|
// to get called, which will call didFinishLoading() and try to access m_pendingFileLoads.
|
|
std::exchange(m_pendingFileLoads, { });
|
|
}
|
|
|
|
}
|