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::IsInternalMessage(const Message
& m
) {
42 return m
.routing_id() == MSG_ROUTING_NONE
&&
43 m
.type() >= Channel::CLOSE_FD_MESSAGE_TYPE
&&
44 m
.type() <= Channel::HELLO_MESSAGE_TYPE
;
47 bool ChannelReader::IsHelloMessage(const Message
& m
) {
48 return m
.routing_id() == MSG_ROUTING_NONE
&&
49 m
.type() == Channel::HELLO_MESSAGE_TYPE
;
52 bool ChannelReader::DispatchInputData(const char* input_data
,
57 // Possibly combine with the overflow buffer to make a larger buffer.
58 if (input_overflow_buf_
.empty()) {
60 end
= input_data
+ input_data_len
;
62 if (input_overflow_buf_
.size() + input_data_len
>
63 Channel::kMaximumMessageSize
) {
64 input_overflow_buf_
.clear();
65 LOG(ERROR
) << "IPC message is too big";
68 input_overflow_buf_
.append(input_data
, input_data_len
);
69 p
= input_overflow_buf_
.data();
70 end
= p
+ input_overflow_buf_
.size();
73 // Dispatch all complete messages in the data buffer.
75 const char* message_tail
= Message::FindNext(p
, end
);
77 int len
= static_cast<int>(message_tail
- p
);
79 if (!WillDispatchInputMessage(&m
))
82 #ifdef IPC_MESSAGE_LOG_ENABLED
83 Logging
* logger
= Logging::GetInstance();
85 logger
->GetMessageText(m
.type(), &name
, &m
, NULL
);
86 TRACE_EVENT1("ipc,toplevel", "ChannelReader::DispatchInputData",
89 TRACE_EVENT2("ipc,toplevel", "ChannelReader::DispatchInputData",
90 "class", IPC_MESSAGE_ID_CLASS(m
.type()),
91 "line", IPC_MESSAGE_ID_LINE(m
.type()));
94 if (IsInternalMessage(m
))
95 HandleInternalMessage(m
);
97 listener_
->OnMessageReceived(m
);
98 if (m
.dispatch_error())
99 listener_
->OnBadMessageReceived(m
);
102 // Last message is partial.
107 // Save any partial data in the overflow buffer.
108 input_overflow_buf_
.assign(p
, end
- p
);
110 if (input_overflow_buf_
.empty() && !DidEmptyInputBuffers())
116 } // namespace internal