1// Copyright 2015 The Chromium OS 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 LIBBRILLO_BRILLO_STREAMS_INPUT_STREAM_SET_H_
6#define LIBBRILLO_BRILLO_STREAMS_INPUT_STREAM_SET_H_
7
8#include <vector>
9
10#include <base/macros.h>
11#include <brillo/brillo_export.h>
12#include <brillo/streams/stream.h>
13
14namespace brillo {
15
16// Multiplexer stream allows to bundle a bunch of secondary streams in one
17// logical stream and simulate a read operation across data concatenated from
18// all those source streams.
19//
20// When created on a set of source streams like stream1, stream2, stream3, etc.,
21// reading from the multiplexer stream will read all the data from stream1 until
22// end-of-stream is reached, then keep reading from stream2, stream3 and so on.
23//
24// InputStreamSet has an option of owning the underlying source streams
25// or just referencing them. Owned streams are passed to InputStreamSet
26// with exclusive ownership transfer (using StreamPtr) and those streams will
27// be closed/destroyed when InputStreamSet is closed/destroyed.
28// Referenced source streams' life time is maintained elsewhere and they must
29// be valid for the duration of InputStreamSet's life. Closing the
30// muliplexer stream does not close the referenced streams.
31class BRILLO_EXPORT InputStreamSet : public Stream {
32 public:
33  // == Construction ==========================================================
34
35  // Generic method that constructs a multiplexer stream on a list of source
36  // streams. |source_streams| is the list of all source stream references
37  // in the order they need to be read from. |owned_source_streams| is a list
38  // of source stream instances that the multiplexer stream will own.
39  // Note that the streams from |owned_source_streams| should still be
40  // referenced in |source_streams| if you need their data to be read from.
41  // |owned_source_streams| could be empty (in which case none of the source
42  // streams are not owned), or contain fewer items than in |source_streams|.
43  static StreamPtr Create(std::vector<Stream*> source_streams,
44                          std::vector<StreamPtr> owned_source_streams,
45                          ErrorPtr* error);
46
47  // Simple helper method to create a multiplexer stream with a list of
48  // referenced streams. None of the streams will be owned.
49  // Effectively calls Create(source_streams, {}, error);
50  static StreamPtr Create(std::vector<Stream*> source_streams, ErrorPtr* error);
51
52  // Simple helper method to create a multiplexer stream with a list of
53  // referenced streams. None of the streams will be owned.
54  // Effectively calls Create(source_streams, owned_source_streams, error)
55  // with |source_streams| containing pointers to the streams from
56  // |owned_source_streams| list.
57  static StreamPtr Create(std::vector<StreamPtr> owned_source_streams,
58                          ErrorPtr* error);
59
60  // == Stream capabilities ===================================================
61  bool IsOpen() const override;
62  bool CanRead() const override { return true; }
63  bool CanWrite() const override { return false; }
64  bool CanSeek() const override { return false; }
65  bool CanGetSize() const override;
66
67  // == Stream size operations ================================================
68  uint64_t GetSize() const override;
69  bool SetSizeBlocking(uint64_t size, ErrorPtr* error) override;
70  uint64_t GetRemainingSize() const override;
71
72  // == Seek operations =======================================================
73  uint64_t GetPosition() const override { return 0; }
74  bool Seek(int64_t offset,
75            Whence whence,
76            uint64_t* new_position,
77            ErrorPtr* error) override;
78
79  // == Read operations =======================================================
80  bool ReadNonBlocking(void* buffer,
81                       size_t size_to_read,
82                       size_t* size_read,
83                       bool* end_of_stream,
84                       ErrorPtr* error) override;
85
86  // == Write operations ======================================================
87  bool WriteNonBlocking(const void* buffer,
88                        size_t size_to_write,
89                        size_t* size_written,
90                        ErrorPtr* error) override;
91
92  // == Finalizing/closing streams  ===========================================
93  bool FlushBlocking(ErrorPtr* /* error */) override { return true; }
94  bool CloseBlocking(ErrorPtr* error) override;
95
96  // == Data availability monitoring ==========================================
97  bool WaitForData(AccessMode mode,
98                   const base::Callback<void(AccessMode)>& callback,
99                   ErrorPtr* error) override;
100
101  bool WaitForDataBlocking(AccessMode in_mode,
102                           base::TimeDelta timeout,
103                           AccessMode* out_mode,
104                           ErrorPtr* error) override;
105
106  void CancelPendingAsyncOperations() override;
107
108 private:
109  friend class InputStreamSetTest;
110
111  // Internal constructor used by the Create() factory methods.
112  InputStreamSet(std::vector<Stream*> source_streams,
113                 std::vector<StreamPtr> owned_source_streams,
114                 uint64_t initial_stream_size);
115
116  // List of streams to read data from.
117  std::vector<Stream*> source_streams_;
118
119  // List of source streams this stream owns. Owned source streams will be
120  // closed when InputStreamSet::CloseBlocking() is called and will be
121  // destroyed when this stream is destroyed.
122  std::vector<StreamPtr> owned_source_streams_;
123
124  uint64_t initial_stream_size_{0};
125  bool closed_{false};
126
127  DISALLOW_COPY_AND_ASSIGN(InputStreamSet);
128};
129
130}  // namespace brillo
131
132#endif  // LIBBRILLO_BRILLO_STREAMS_INPUT_STREAM_SET_H_
133