summaryrefslogtreecommitdiff
path: root/brillo/streams/input_stream_set.h
blob: fda255f04297279676ecf46bbdf75a1581c9bbc6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIBCHROMEOS_BRILLO_STREAMS_INPUT_STREAM_SET_H_
#define LIBCHROMEOS_BRILLO_STREAMS_INPUT_STREAM_SET_H_

#include <vector>

#include <base/macros.h>
#include <brillo/brillo_export.h>
#include <brillo/streams/stream.h>

namespace brillo {

// Multiplexer stream allows to bundle a bunch of secondary streams in one
// logical stream and simulate a read operation across data concatenated from
// all those source streams.
//
// When created on a set of source streams like stream1, stream2, stream3, etc.,
// reading from the multiplexer stream will read all the data from stream1 until
// end-of-stream is reached, then keep reading from stream2, stream3 and so on.
//
// InputStreamSet has an option of owning the underlying source streams
// or just referencing them. Owned streams are passed to InputStreamSet
// with exclusive ownership transfer (using StreamPtr) and those streams will
// be closed/destroyed when InputStreamSet is closed/destroyed.
// Referenced source streams' life time is maintained elsewhere and they must
// be valid for the duration of InputStreamSet's life. Closing the
// muliplexer stream does not close the referenced streams.
class BRILLO_EXPORT InputStreamSet : public Stream {
 public:
  // == Construction ==========================================================

  // Generic method that constructs a multiplexer stream on a list of source
  // streams. |source_streams| is the list of all source stream references
  // in the order they need to be read from. |owned_source_streams| is a list
  // of source stream instances that the multiplexer stream will own.
  // Note that the streams from |owned_source_streams| should still be
  // referenced in |source_streams| if you need their data to be read from.
  // |owned_source_streams| could be empty (in which case none of the source
  // streams are not owned), or contain fewer items than in |source_streams|.
  static StreamPtr Create(std::vector<Stream*> source_streams,
                          std::vector<StreamPtr> owned_source_streams,
                          ErrorPtr* error);

  // Simple helper method to create a multiplexer stream with a list of
  // referenced streams. None of the streams will be owned.
  // Effectively calls Create(source_streams, {}, error);
  static StreamPtr Create(std::vector<Stream*> source_streams, ErrorPtr* error);

  // Simple helper method to create a multiplexer stream with a list of
  // referenced streams. None of the streams will be owned.
  // Effectively calls Create(source_streams, owned_source_streams, error)
  // with |source_streams| containing pointers to the streams from
  // |owned_source_streams| list.
  static StreamPtr Create(std::vector<StreamPtr> owned_source_streams,
                          ErrorPtr* error);

  // == Stream capabilities ===================================================
  bool IsOpen() const override;
  bool CanRead() const override { return true; }
  bool CanWrite() const override { return false; }
  bool CanSeek() const override { return false; }
  bool CanGetSize() const override;

  // == Stream size operations ================================================
  uint64_t GetSize() const override;
  bool SetSizeBlocking(uint64_t size, ErrorPtr* error) override;
  uint64_t GetRemainingSize() const override;

  // == Seek operations =======================================================
  uint64_t GetPosition() const override { return 0; }
  bool Seek(int64_t offset,
            Whence whence,
            uint64_t* new_position,
            ErrorPtr* error) override;

  // == Read operations =======================================================
  bool ReadNonBlocking(void* buffer,
                       size_t size_to_read,
                       size_t* size_read,
                       bool* end_of_stream,
                       ErrorPtr* error) override;

  // == Write operations ======================================================
  bool WriteNonBlocking(const void* buffer,
                        size_t size_to_write,
                        size_t* size_written,
                        ErrorPtr* error) override;

  // == Finalizing/closing streams  ===========================================
  bool FlushBlocking(ErrorPtr* error) override { return true; }
  bool CloseBlocking(ErrorPtr* error) override;

  // == Data availability monitoring ==========================================
  bool WaitForData(AccessMode mode,
                   const base::Callback<void(AccessMode)>& callback,
                   ErrorPtr* error) override;

  bool WaitForDataBlocking(AccessMode in_mode,
                           base::TimeDelta timeout,
                           AccessMode* out_mode,
                           ErrorPtr* error) override;

  void CancelPendingAsyncOperations() override;

 private:
  friend class InputStreamSetTest;

  // Internal constructor used by the Create() factory methods.
  InputStreamSet(std::vector<Stream*> source_streams,
                 std::vector<StreamPtr> owned_source_streams,
                 uint64_t initial_stream_size);

  // List of streams to read data from.
  std::vector<Stream*> source_streams_;

  // List of source streams this stream owns. Owned source streams will be
  // closed when InputStreamSet::CloseBlocking() is called and will be
  // destroyed when this stream is destroyed.
  std::vector<StreamPtr> owned_source_streams_;

  uint64_t initial_stream_size_{0};
  bool closed_{false};

  DISALLOW_COPY_AND_ASSIGN(InputStreamSet);
};

}  // namespace brillo

#endif  // LIBCHROMEOS_BRILLO_STREAMS_INPUT_STREAM_SET_H_