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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// Copyright 2014 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 "content/child/web_data_consumer_handle_impl.h"
#include <limits>
#include "base/bind.h"
#include "base/logging.h"
#include "third_party/mojo/src/mojo/public/c/system/types.h"
namespace content {
using Result = blink::WebDataConsumerHandle::Result;
class WebDataConsumerHandleImpl::Context
: public base::RefCountedThreadSafe<Context> {
public:
explicit Context(Handle handle) : handle_(handle.Pass()) {}
const Handle& handle() { return handle_; }
private:
friend class base::RefCountedThreadSafe<Context>;
~Context() {}
Handle handle_;
DISALLOW_COPY_AND_ASSIGN(Context);
};
WebDataConsumerHandleImpl::ReaderImpl::ReaderImpl(
scoped_refptr<Context> context,
Client* client)
: context_(context), client_(client) {
if (client_)
StartWatching();
}
WebDataConsumerHandleImpl::ReaderImpl::~ReaderImpl() {
}
Result WebDataConsumerHandleImpl::ReaderImpl::read(void* data,
size_t size,
Flags flags,
size_t* read_size) {
// We need this variable definition to avoid a link error.
const Flags kNone = FlagNone;
DCHECK_EQ(flags, kNone);
DCHECK_LE(size, std::numeric_limits<uint32_t>::max());
*read_size = 0;
uint32_t size_to_pass = size;
MojoReadDataFlags flags_to_pass = MOJO_READ_DATA_FLAG_NONE;
MojoResult rv = mojo::ReadDataRaw(context_->handle().get(), data,
&size_to_pass, flags_to_pass);
if (rv == MOJO_RESULT_OK)
*read_size = size_to_pass;
return HandleReadResult(rv);
}
Result WebDataConsumerHandleImpl::ReaderImpl::beginRead(const void** buffer,
Flags flags,
size_t* available) {
// We need this variable definition to avoid a link error.
const Flags kNone = FlagNone;
DCHECK_EQ(flags, kNone);
*buffer = nullptr;
*available = 0;
uint32_t size_to_pass = 0;
MojoReadDataFlags flags_to_pass = MOJO_READ_DATA_FLAG_NONE;
MojoResult rv = mojo::BeginReadDataRaw(context_->handle().get(), buffer,
&size_to_pass, flags_to_pass);
if (rv == MOJO_RESULT_OK)
*available = size_to_pass;
return HandleReadResult(rv);
}
Result WebDataConsumerHandleImpl::ReaderImpl::endRead(size_t read_size) {
MojoResult rv = mojo::EndReadDataRaw(context_->handle().get(), read_size);
return rv == MOJO_RESULT_OK ? Ok : UnexpectedError;
}
Result WebDataConsumerHandleImpl::ReaderImpl::HandleReadResult(
MojoResult mojo_result) {
switch (mojo_result) {
case MOJO_RESULT_OK:
return Ok;
case MOJO_RESULT_FAILED_PRECONDITION:
return Done;
case MOJO_RESULT_BUSY:
return Busy;
case MOJO_RESULT_SHOULD_WAIT:
if (client_)
StartWatching();
return ShouldWait;
case MOJO_RESULT_RESOURCE_EXHAUSTED:
return ResourceExhausted;
default:
return UnexpectedError;
}
}
void WebDataConsumerHandleImpl::ReaderImpl::StartWatching() {
handle_watcher_.Start(
context_->handle().get(), MOJO_HANDLE_SIGNAL_READABLE,
MOJO_DEADLINE_INDEFINITE,
base::Bind(&ReaderImpl::OnHandleGotReadable, base::Unretained(this)));
}
void WebDataConsumerHandleImpl::ReaderImpl::OnHandleGotReadable(MojoResult) {
DCHECK(client_);
client_->didGetReadable();
}
WebDataConsumerHandleImpl::WebDataConsumerHandleImpl(Handle handle)
: context_(new Context(handle.Pass())) {
}
WebDataConsumerHandleImpl::~WebDataConsumerHandleImpl() {
}
scoped_ptr<blink::WebDataConsumerHandle::Reader>
WebDataConsumerHandleImpl::ObtainReader(Client* client) {
return make_scoped_ptr(obtainReaderInternal(client));
}
WebDataConsumerHandleImpl::ReaderImpl*
WebDataConsumerHandleImpl::obtainReaderInternal(Client* client) {
return new ReaderImpl(context_, client);
}
} // namespace content
|