1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/ipc_channel_reader.h"
7 #include "ipc/ipc_listener.h"
8 #include "ipc/ipc_logging.h"
9 #include "ipc/ipc_message_macros.h"
14 ChannelReader::ChannelReader(Listener
* listener
) : listener_(listener
) {
15 memset(input_buf_
, 0, sizeof(input_buf_
));
18 ChannelReader::~ChannelReader() {
21 bool ChannelReader::ProcessIncomingMessages() {
24 ReadState read_state
= ReadData(input_buf_
, Channel::kReadBufferSize
,
26 if (read_state
== READ_FAILED
)
28 if (read_state
== READ_PENDING
)
31 DCHECK(bytes_read
> 0);
32 if (!DispatchInputData(input_buf_
, bytes_read
))
37 bool ChannelReader::AsyncReadComplete(int bytes_read
) {
38 return DispatchInputData(input_buf_
, bytes_read
);
41 bool ChannelReader::IsHelloMessage(const Message
& m
) const {
42 return m
.routing_id() == MSG_ROUTING_NONE
&&
43 m
.type() == Channel::HELLO_MESSAGE_TYPE
;
46 bool ChannelReader::DispatchInputData(const char* input_data
,
51 // Possibly combine with the overflow buffer to make a larger buffer.
52 if (input_overflow_buf_
.empty()) {
54 end
= input_data
+ input_data_len
;
56 if (input_overflow_buf_
.size() + input_data_len
>
57 Channel::kMaximumMessageSize
) {
58 input_overflow_buf_
.clear();
59 LOG(ERROR
) << "IPC message is too big";
62 input_overflow_buf_
.append(input_data
, input_data_len
);
63 p
= input_overflow_buf_
.data();
64 end
= p
+ input_overflow_buf_
.size();
67 // Dispatch all complete messages in the data buffer.
69 const char* message_tail
= Message::FindNext(p
, end
);
71 int len
= static_cast<int>(message_tail
- p
);
73 if (!WillDispatchInputMessage(&m
))
76 #ifdef IPC_MESSAGE_LOG_ENABLED
77 Logging
* logger
= Logging::GetInstance();
79 logger
->GetMessageText(m
.type(), &name
, &m
, NULL
);
80 TRACE_EVENT1("ipc", "ChannelReader::DispatchInputData", "name", name
);
82 TRACE_EVENT2("ipc", "ChannelReader::DispatchInputData",
83 "class", IPC_MESSAGE_ID_CLASS(m
.type()),
84 "line", IPC_MESSAGE_ID_LINE(m
.type()));
87 if (IsHelloMessage(m
))
88 HandleHelloMessage(m
);
90 listener_
->OnMessageReceived(m
);
93 // Last message is partial.
98 // Save any partial data in the overflow buffer.
99 input_overflow_buf_
.assign(p
, end
- p
);
101 if (input_overflow_buf_
.empty() && !DidEmptyInputBuffers())
107 } // namespace internal