File: FetchStreamReader.h

package info (click to toggle)
firefox 147.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,683,324 kB
  • sloc: cpp: 7,607,156; javascript: 6,532,492; ansic: 3,775,158; python: 1,415,368; xml: 634,556; asm: 438,949; java: 186,241; sh: 62,751; makefile: 18,079; objc: 13,092; perl: 12,808; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (130 lines) | stat: -rw-r--r-- 4,330 bytes parent folder | download | duplicates (14)
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
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_FetchStreamReader_h
#define mozilla_dom_FetchStreamReader_h

#include "js/RootingAPI.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/WeakPtr.h"
#include "mozilla/dom/FetchBinding.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "nsIAsyncOutputStream.h"
#include "nsIGlobalObject.h"

namespace mozilla::dom {

class ReadableStream;
class ReadableStreamDefaultReader;
class StrongWorkerRef;

class FetchStreamReader;

class OutputStreamHolder final : public nsIOutputStreamCallback {
 public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOUTPUTSTREAMCALLBACK

  OutputStreamHolder(FetchStreamReader* aReader, nsIAsyncOutputStream* aOutput);

  nsresult Init(JSContext* aCx);

  void Shutdown();

  // These just proxy the calls to the nsIAsyncOutputStream
  nsresult AsyncWait(uint32_t aFlags, uint32_t aRequestedCount,
                     nsIEventTarget* aEventTarget);
  nsresult Write(char* aBuffer, uint32_t aLength, uint32_t* aWritten) {
    return mOutput->Write(aBuffer, aLength, aWritten);
  }
  nsresult CloseWithStatus(nsresult aStatus) {
    return mOutput->CloseWithStatus(aStatus);
  }
  nsresult StreamStatus() { return mOutput->StreamStatus(); }

  nsIAsyncOutputStream* GetOutputStream() { return mOutput; }

 private:
  ~OutputStreamHolder();

  RefPtr<FetchStreamReader> mAsyncWaitReader;
  // WeakPtr to avoid cycles
  WeakPtr<FetchStreamReader> mReader;
  // To ensure the worker sticks around
  RefPtr<StrongWorkerRef> mAsyncWaitWorkerRef;
  RefPtr<StrongWorkerRef> mWorkerRef;
  nsCOMPtr<nsIAsyncOutputStream> mOutput;
};

class FetchStreamReader final : public nsISupports, public SupportsWeakPtr {
 public:
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_CLASS(FetchStreamReader)

  // This creates a nsIInputStream able to retrieve data from the ReadableStream
  // object. The reading starts when StartConsuming() is called.
  static nsresult Create(JSContext* aCx, nsIGlobalObject* aGlobal,
                         FetchStreamReader** aStreamReader,
                         nsIInputStream** aInputStream);

  bool OnOutputStreamReady();

  MOZ_CAN_RUN_SCRIPT
  void ChunkSteps(JSContext* aCx, JS::Handle<JS::Value> aChunk,
                  ErrorResult& aRv);
  MOZ_CAN_RUN_SCRIPT
  void CloseSteps(JSContext* aCx, ErrorResult& aRv);
  MOZ_CAN_RUN_SCRIPT
  void ErrorSteps(JSContext* aCx, JS::Handle<JS::Value> aError,
                  ErrorResult& aRv);

  // Idempotently close the output stream and null out all state. If aCx is
  // provided, the reader will also be canceled.  aStatus must be a DOM error
  // as understood by DOMException because it will be provided as the
  // cancellation reason.
  //
  // This is a script boundary minimize annotation changes required while
  // we figure out how to handle some more tricky annotation cases (for
  // example, the destructor of this class. Tracking under Bug 1750656)
  MOZ_CAN_RUN_SCRIPT_BOUNDARY
  void CloseAndRelease(JSContext* aCx, nsresult aStatus);

  void StartConsuming(JSContext* aCx, ReadableStream* aStream,
                      ErrorResult& aRv);

 private:
  explicit FetchStreamReader(nsIGlobalObject* aGlobal);
  ~FetchStreamReader();

  nsresult WriteBuffer();

  // Attempt to copy data from mBuffer into mPipeOut. Returns `true` if data was
  // written, and AsyncWait callbacks or FetchReadRequest calls have been set up
  // to write more data in the future, and `false` otherwise.
  MOZ_CAN_RUN_SCRIPT
  bool Process(JSContext* aCx);

  void ReportErrorToConsole(JSContext* aCx, JS::Handle<JS::Value> aValue);

  nsCOMPtr<nsIGlobalObject> mGlobal;
  nsCOMPtr<nsIEventTarget> mOwningEventTarget;

  RefPtr<OutputStreamHolder> mOutput;

  RefPtr<ReadableStreamDefaultReader> mReader;

  nsTArray<uint8_t> mBuffer;
  uint32_t mBufferRemaining = 0;
  uint32_t mBufferOffset = 0;

  bool mHasOutstandingReadRequest = false;
  bool mStreamClosed = false;
};

}  // namespace mozilla::dom

#endif  // mozilla_dom_FetchStreamReader_h