forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unzip_job.cc
90 lines (78 loc) · 2.84 KB
/
unzip_job.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/assets/unzip_job.h"
#include <utility>
#include "mojo/public/cpp/environment/environment.h"
#include "third_party/zlib/contrib/minizip/unzip.h"
namespace blink {
UnzipJob::UnzipJob(zip::UniqueUnzipper unzipper,
std::string asset_name,
mojo::ScopedDataPipeProducerHandle producer,
ftl::RefPtr<ftl::TaskRunner> task_runner)
: unzipper_(std::move(unzipper)),
asset_name_(std::move(asset_name)),
producer_(std::move(producer)),
task_runner_(std::move(task_runner)),
waiter_(mojo::Environment::GetDefaultAsyncWaiter()),
wait_id_(0) {
FTL_DCHECK(unzipper_.is_valid());
task_runner_->PostTask([this]() { Start(); });
}
UnzipJob::~UnzipJob() {}
void UnzipJob::Start() {
int result = unzLocateFile(unzipper_.get(), asset_name_.c_str(), 0);
if (result != UNZ_OK) {
FTL_LOG(WARNING) << "Requested asset '" << asset_name_
<< "' does not exist.";
delete this;
return;
}
result = unzOpenCurrentFile(unzipper_.get());
if (result != UNZ_OK) {
FTL_LOG(WARNING) << "unzOpenCurrentFile failed, error=" << result;
delete this;
return;
}
OnHandleReady(MOJO_RESULT_OK);
}
void UnzipJob::OnHandleReady(MojoResult result) {
if (result == MOJO_RESULT_OK) {
void* buffer = nullptr;
uint32_t size = 0;
result = mojo::BeginWriteDataRaw(producer_.get(), &buffer, &size,
MOJO_WRITE_DATA_FLAG_NONE);
if (result == MOJO_RESULT_OK) {
FTL_DCHECK(size < static_cast<uint32_t>(std::numeric_limits<int>::max()));
ssize_t bytes_read = unzReadCurrentFile(unzipper_.get(), buffer, size);
result = mojo::EndWriteDataRaw(producer_.get(),
std::max<ssize_t>(0l, bytes_read));
if (bytes_read < 0) {
FTL_LOG(WARNING) << "Asset unzip failed, error=" << bytes_read;
delete this;
} else if (result != MOJO_RESULT_OK) {
FTL_LOG(WARNING) << "Mojo EndWrite failed, error=" << result;
delete this;
} else if (bytes_read < size) {
// Reached EOF. Stop the process.
delete this;
} else {
task_runner_->PostTask([this]() { OnHandleReady(MOJO_RESULT_OK); });
}
return;
}
}
if (result == MOJO_RESULT_SHOULD_WAIT) {
wait_id_ =
waiter_->AsyncWait(producer_.get().value(), MOJO_HANDLE_SIGNAL_WRITABLE,
MOJO_DEADLINE_INDEFINITE, &WaitComplete, this);
return;
}
delete this;
}
void UnzipJob::WaitComplete(void* context, MojoResult result) {
UnzipJob* job = static_cast<UnzipJob*>(context);
job->wait_id_ = 0;
job->OnHandleReady(result);
}
} // namespace blink