| Index: ipc/ipc_channel_reader.cc
|
| diff --git a/ipc/ipc_channel_reader.cc b/ipc/ipc_channel_reader.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..47d1e8d50ee8902d03963592c36d54aa1acc98b7
|
| --- /dev/null
|
| +++ b/ipc/ipc_channel_reader.cc
|
| @@ -0,0 +1,93 @@
|
| +// Copyright (c) 2012 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 "ipc/ipc_channel_reader.h"
|
| +
|
| +namespace IPC {
|
| +namespace internal {
|
| +
|
| +ChannelReader::ChannelReader(Channel::Listener* listener)
|
| + : listener_(listener) {
|
| +}
|
| +
|
| +ChannelReader::~ChannelReader() {
|
| +}
|
| +
|
| +bool ChannelReader::ProcessIncomingMessages() {
|
| + while (true) {
|
| + int bytes_read = 0;
|
| + ReadState read_state = ReadData(input_buf_, Channel::kReadBufferSize,
|
| + &bytes_read);
|
| + if (read_state == READ_FAILED)
|
| + return false;
|
| + if (read_state == READ_PENDING)
|
| + return true;
|
| +
|
| + DCHECK(bytes_read > 0);
|
| + if (!DispatchInputData(input_buf_, bytes_read))
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +bool ChannelReader::AsyncReadComplete(int bytes_read) {
|
| + return DispatchInputData(input_buf_, bytes_read);
|
| +}
|
| +
|
| +bool ChannelReader::IsHelloMessage(const Message& m) const {
|
| + return m.routing_id() == MSG_ROUTING_NONE &&
|
| + m.type() == Channel::HELLO_MESSAGE_TYPE;
|
| +}
|
| +
|
| +bool ChannelReader::DispatchInputData(const char* input_data,
|
| + int input_data_len) {
|
| + const char* p;
|
| + const char* end;
|
| +
|
| + // Possibly combine with the overflow buffer to make a larger buffer.
|
| + if (input_overflow_buf_.empty()) {
|
| + p = input_data;
|
| + end = input_data + input_data_len;
|
| + } else {
|
| + if (input_overflow_buf_.size() >
|
| + Channel::kMaximumMessageSize - input_data_len) {
|
| + input_overflow_buf_.clear();
|
| + LOG(ERROR) << "IPC message is too big";
|
| + return false;
|
| + }
|
| + input_overflow_buf_.append(input_data, input_data_len);
|
| + p = input_overflow_buf_.data();
|
| + end = p + input_overflow_buf_.size();
|
| + }
|
| +
|
| + // Dispatch all complete messages in the data buffer.
|
| + while (p < end) {
|
| + const char* message_tail = Message::FindNext(p, end);
|
| + if (message_tail) {
|
| + int len = static_cast<int>(message_tail - p);
|
| + Message m(p, len);
|
| + if (!WillDispatchInputMessage(&m))
|
| + return false;
|
| +
|
| + if (IsHelloMessage(m))
|
| + HandleHelloMessage(m);
|
| + else
|
| + listener_->OnMessageReceived(m);
|
| + p = message_tail;
|
| + } else {
|
| + // Last message is partial.
|
| + break;
|
| + }
|
| + }
|
| +
|
| + // Save any partial data in the overflow buffer.
|
| + input_overflow_buf_.assign(p, end - p);
|
| +
|
| + if (input_overflow_buf_.empty() && !DidEmptyInputBuffers())
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +} // namespace internal
|
| +} // namespace IPC
|
|
|