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