1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2014 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <utility>
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <vector>
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h"
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/message.h"
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/public/cpp/bindings/message_filter.h"
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace internal {
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass FilterChain {
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // this object is alive.
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  explicit FilterChain(MessageReceiver* sink = nullptr);
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  FilterChain(FilterChain&& other);
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  FilterChain& operator=(FilterChain&& other);
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~FilterChain();
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  template <typename FilterType, typename... Args>
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  inline void Append(Args&&... args);
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Doesn't take ownership of |sink|. Therefore |sink| has to stay alive while
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // this object is alive.
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void SetSink(MessageReceiver* sink);
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Returns a receiver to accept messages. Messages flow through all filters in
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // the same order as they were appended to the chain. If all filters allow a
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // message to pass, it will be forwarded to |sink_|.
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // The returned value is invalidated when this object goes away.
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessageReceiver* GetHead();
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private:
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Owned by this object.
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // TODO(dcheng): Use unique_ptr.
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::vector<MessageFilter*> filters_;
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MessageReceiver* sink_;
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DISALLOW_COPY_AND_ASSIGN(FilterChain);
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztemplate <typename FilterType, typename... Args>
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline void FilterChain::Append(Args&&... args) {
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  FilterType* filter = new FilterType(std::forward<Args>(args)..., sink_);
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  if (!filters_.empty())
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    filters_.back()->set_sink(filter);
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  filters_.push_back(filter);
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveztemplate <>
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezinline void FilterChain::Append<PassThroughFilter>() {
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace internal
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_FILTER_CHAIN_H_
67