Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ipc / message_filter_router.cc
blob35209b091811554b0711b207cc4c70209ba807f7
1 // Copyright 2014 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/message_filter_router.h"
7 #include <stdint.h>
9 #include "ipc/ipc_message_macros.h"
10 #include "ipc/ipc_message_utils.h"
11 #include "ipc/message_filter.h"
13 namespace IPC {
15 namespace {
17 bool TryFiltersImpl(MessageFilterRouter::MessageFilters& filters,
18 const IPC::Message& message) {
19 for (size_t i = 0; i < filters.size(); ++i) {
20 if (filters[i]->OnMessageReceived(message)) {
21 return true;
24 return false;
27 bool RemoveFilterImpl(MessageFilterRouter::MessageFilters& filters,
28 MessageFilter* filter) {
29 MessageFilterRouter::MessageFilters::iterator it =
30 std::remove(filters.begin(), filters.end(), filter);
31 if (it == filters.end())
32 return false;
34 filters.erase(it, filters.end());
35 return true;
38 bool ValidMessageClass(int message_class) {
39 return message_class >= 0 && message_class < LastIPCMsgStart;
42 } // namespace
44 MessageFilterRouter::MessageFilterRouter() {}
45 MessageFilterRouter::~MessageFilterRouter() {}
47 void MessageFilterRouter::AddFilter(MessageFilter* filter) {
48 // Determine if the filter should be applied to all messages, or only
49 // messages of a certain class.
50 std::vector<uint32_t> supported_message_classes;
51 if (filter->GetSupportedMessageClasses(&supported_message_classes)) {
52 DCHECK(!supported_message_classes.empty());
53 for (size_t i = 0; i < supported_message_classes.size(); ++i) {
54 const int message_class = supported_message_classes[i];
55 DCHECK(ValidMessageClass(message_class));
56 // Safely ignore repeated subscriptions to a given message class for the
57 // current filter being added.
58 if (!message_class_filters_[message_class].empty() &&
59 message_class_filters_[message_class].back() == filter) {
60 continue;
62 message_class_filters_[message_class].push_back(filter);
64 } else {
65 global_filters_.push_back(filter);
69 void MessageFilterRouter::RemoveFilter(MessageFilter* filter) {
70 if (RemoveFilterImpl(global_filters_, filter))
71 return;
73 for (size_t i = 0; i < arraysize(message_class_filters_); ++i)
74 RemoveFilterImpl(message_class_filters_[i], filter);
77 bool MessageFilterRouter::TryFilters(const Message& message) {
78 if (TryFiltersImpl(global_filters_, message))
79 return true;
81 const int message_class = IPC_MESSAGE_CLASS(message);
82 if (!ValidMessageClass(message_class))
83 return false;
85 return TryFiltersImpl(message_class_filters_[message_class], message);
88 void MessageFilterRouter::Clear() {
89 global_filters_.clear();
90 for (size_t i = 0; i < arraysize(message_class_filters_); ++i)
91 message_class_filters_[i].clear();
94 } // namespace IPC