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.
4
5#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
6#define MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
7
8#include <vector>
9
10#include "mojo/public/cpp/bindings/message.h"
11#include "mojo/public/cpp/bindings/message_filter.h"
12#include "mojo/public/cpp/system/macros.h"
13
14namespace mojo {
15namespace internal {
16
17class FilterChain {
18  MOJO_MOVE_ONLY_TYPE_FOR_CPP_03(FilterChain, RValue)
19
20 public:
21  // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while
22  // this object is alive.
23  explicit FilterChain(MessageReceiver* sink = NULL);
24
25  // Move-only constructor and operator=.
26  FilterChain(RValue other);
27  FilterChain& operator=(RValue other);
28
29  ~FilterChain();
30
31  template <typename FilterType>
32  inline void Append();
33
34  // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while
35  // this object is alive.
36  void SetSink(MessageReceiver* sink);
37
38  // Returns a receiver to accept messages. Messages flow through all filters in
39  // the same order as they were appended to the chain. If all filters allow a
40  // message to pass, it will be forwarded to |sink_|.
41  // The returned value is invalidated when this object goes away.
42  MessageReceiver* GetHead();
43
44 private:
45  // Owned by this object.
46  std::vector<MessageFilter*> filters_;
47
48  MessageReceiver* sink_;
49};
50
51template <typename FilterType>
52inline void FilterChain::Append() {
53  FilterType* filter = new FilterType(sink_);
54  if (!filters_.empty())
55    filters_.back()->set_sink(filter);
56  filters_.push_back(filter);
57}
58
59template <>
60inline void FilterChain::Append<PassThroughFilter>() {
61}
62
63}  // namespace internal
64}  // namespace mojo
65
66#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
67