• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium 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 // General-purpose abstractions for a write stream.
6 
7 #ifndef QUICHE_COMMON_QUICHE_STREAM_H_
8 #define QUICHE_COMMON_QUICHE_STREAM_H_
9 
10 #include "absl/status/status.h"
11 #include "absl/strings/string_view.h"
12 #include "absl/types/span.h"
13 #include "quiche/common/platform/api/quiche_export.h"
14 
15 namespace quiche {
16 
17 // A shared base class for read and write stream to support abrupt termination.
18 class QUICHE_EXPORT TerminableStream {
19  public:
20   virtual ~TerminableStream() = default;
21 
22   // Abruptly terminate the stream due to an error. If `error` is not OK, it may
23   // carry the error information that could be potentially communicated to the
24   // peer in case the stream is remote. If the stream is a duplex stream, both
25   // ends of the stream are terminated.
26   virtual void AbruptlyTerminate(absl::Status error) = 0;
27 };
28 
29 // A general-purpose visitor API that gets notifications for WriteStream-related
30 // events.
31 class QUICHE_EXPORT WriteStreamVisitor {
32  public:
~WriteStreamVisitor()33   virtual ~WriteStreamVisitor() {}
34 
35   // Called whenever the stream is not write-blocked and can accept new data.
36   virtual void OnCanWrite() = 0;
37 };
38 
39 // Options for writing data into a WriteStream.
40 class QUICHE_EXPORT StreamWriteOptions {
41  public:
42   StreamWriteOptions() = default;
43 
44   // If send_fin() is sent to true, the write operation also sends a FIN on the
45   // stream.
send_fin()46   bool send_fin() const { return send_fin_; }
set_send_fin(bool send_fin)47   void set_send_fin(bool send_fin) { send_fin_ = send_fin; }
48 
49  private:
50   bool send_fin_ = false;
51 };
52 
53 inline constexpr StreamWriteOptions kDefaultStreamWriteOptions =
54     StreamWriteOptions();
55 
56 // WriteStream is an object that can accept a stream of bytes.
57 //
58 // The writes into a WriteStream are all-or-nothing.  A WriteStream object has
59 // to either accept all data written into it by returning absl::OkStatus, or ask
60 // the caller to try again once via OnCanWrite() by returning
61 // absl::UnavailableError.
62 class QUICHE_EXPORT WriteStream : public TerminableStream {
63  public:
~WriteStream()64   virtual ~WriteStream() {}
65 
66   // Writes |data| into the stream.
67   virtual absl::Status Writev(absl::Span<const absl::string_view> data,
68                               const StreamWriteOptions& options) = 0;
69 
70   // Indicates whether it is possible to write into stream right now.
71   virtual bool CanWrite() const = 0;
72 
73   // Legacy convenience method for writing a single string_view.  New users
74   // should use quiche::WriteIntoStream instead, since this method does not
75   // return useful failure information.
SendFin()76   [[nodiscard]] bool SendFin() {
77     StreamWriteOptions options;
78     options.set_send_fin(true);
79     return Writev(absl::Span<const absl::string_view>(), options).ok();
80   }
81 
82   // Legacy convenience method for writing a single string_view.  New users
83   // should use quiche::WriteIntoStream instead, since this method does not
84   // return useful failure information.
Write(absl::string_view data)85   [[nodiscard]] bool Write(absl::string_view data) {
86     return Writev(absl::MakeSpan(&data, 1), kDefaultStreamWriteOptions).ok();
87   }
88 };
89 
90 // Convenience methods to write a single chunk of data into the stream.
91 inline absl::Status WriteIntoStream(
92     WriteStream& stream, absl::string_view data,
93     const StreamWriteOptions& options = kDefaultStreamWriteOptions) {
94   return stream.Writev(absl::MakeSpan(&data, 1), options);
95 }
96 
97 // Convenience methods to send a FIN on the stream.
SendFinOnStream(WriteStream & stream)98 inline absl::Status SendFinOnStream(WriteStream& stream) {
99   StreamWriteOptions options;
100   options.set_send_fin(true);
101   return stream.Writev(absl::Span<const absl::string_view>(), options);
102 }
103 
104 }  // namespace quiche
105 
106 #endif  // QUICHE_COMMON_QUICHE_STREAM_H_
107