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