OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_BASE_STREAM_H_ | 11 #ifndef WEBRTC_BASE_STREAM_H_ |
12 #define WEBRTC_BASE_STREAM_H_ | 12 #define WEBRTC_BASE_STREAM_H_ |
13 | 13 |
14 #include <stdio.h> | |
15 | 14 |
16 #include <memory> | 15 // This header is deprecated and is just left here temporarily during |
17 | 16 // refactoring. See https://bugs.webrtc.org/7634 for more details. |
18 #include "webrtc/base/buffer.h" | 17 #include "webrtc/rtc_base/stream.h" |
19 #include "webrtc/base/constructormagic.h" | |
20 #include "webrtc/base/criticalsection.h" | |
21 #include "webrtc/base/logging.h" | |
22 #include "webrtc/base/messagehandler.h" | |
23 #include "webrtc/base/messagequeue.h" | |
24 #include "webrtc/base/sigslot.h" | |
25 | |
26 namespace rtc { | |
27 | |
28 /////////////////////////////////////////////////////////////////////////////// | |
29 // StreamInterface is a generic asynchronous stream interface, supporting read, | |
30 // write, and close operations, and asynchronous signalling of state changes. | |
31 // The interface is designed with file, memory, and socket implementations in | |
32 // mind. Some implementations offer extended operations, such as seeking. | |
33 /////////////////////////////////////////////////////////////////////////////// | |
34 | |
35 // The following enumerations are declared outside of the StreamInterface | |
36 // class for brevity in use. | |
37 | |
38 // The SS_OPENING state indicates that the stream will signal open or closed | |
39 // in the future. | |
40 enum StreamState { SS_CLOSED, SS_OPENING, SS_OPEN }; | |
41 | |
42 // Stream read/write methods return this value to indicate various success | |
43 // and failure conditions described below. | |
44 enum StreamResult { SR_ERROR, SR_SUCCESS, SR_BLOCK, SR_EOS }; | |
45 | |
46 // StreamEvents are used to asynchronously signal state transitionss. The flags | |
47 // may be combined. | |
48 // SE_OPEN: The stream has transitioned to the SS_OPEN state | |
49 // SE_CLOSE: The stream has transitioned to the SS_CLOSED state | |
50 // SE_READ: Data is available, so Read is likely to not return SR_BLOCK | |
51 // SE_WRITE: Data can be written, so Write is likely to not return SR_BLOCK | |
52 enum StreamEvent { SE_OPEN = 1, SE_READ = 2, SE_WRITE = 4, SE_CLOSE = 8 }; | |
53 | |
54 class Thread; | |
55 | |
56 struct StreamEventData : public MessageData { | |
57 int events, error; | |
58 StreamEventData(int ev, int er) : events(ev), error(er) { } | |
59 }; | |
60 | |
61 class StreamInterface : public MessageHandler { | |
62 public: | |
63 enum { | |
64 MSG_POST_EVENT = 0xF1F1, MSG_MAX = MSG_POST_EVENT | |
65 }; | |
66 | |
67 ~StreamInterface() override; | |
68 | |
69 virtual StreamState GetState() const = 0; | |
70 | |
71 // Read attempts to fill buffer of size buffer_len. Write attempts to send | |
72 // data_len bytes stored in data. The variables read and write are set only | |
73 // on SR_SUCCESS (see below). Likewise, error is only set on SR_ERROR. | |
74 // Read and Write return a value indicating: | |
75 // SR_ERROR: an error occurred, which is returned in a non-null error | |
76 // argument. Interpretation of the error requires knowledge of the | |
77 // stream's concrete type, which limits its usefulness. | |
78 // SR_SUCCESS: some number of bytes were successfully written, which is | |
79 // returned in a non-null read/write argument. | |
80 // SR_BLOCK: the stream is in non-blocking mode, and the operation would | |
81 // block, or the stream is in SS_OPENING state. | |
82 // SR_EOS: the end-of-stream has been reached, or the stream is in the | |
83 // SS_CLOSED state. | |
84 virtual StreamResult Read(void* buffer, size_t buffer_len, | |
85 size_t* read, int* error) = 0; | |
86 virtual StreamResult Write(const void* data, size_t data_len, | |
87 size_t* written, int* error) = 0; | |
88 // Attempt to transition to the SS_CLOSED state. SE_CLOSE will not be | |
89 // signalled as a result of this call. | |
90 virtual void Close() = 0; | |
91 | |
92 // Streams may signal one or more StreamEvents to indicate state changes. | |
93 // The first argument identifies the stream on which the state change occured. | |
94 // The second argument is a bit-wise combination of StreamEvents. | |
95 // If SE_CLOSE is signalled, then the third argument is the associated error | |
96 // code. Otherwise, the value is undefined. | |
97 // Note: Not all streams will support asynchronous event signalling. However, | |
98 // SS_OPENING and SR_BLOCK returned from stream member functions imply that | |
99 // certain events will be raised in the future. | |
100 sigslot::signal3<StreamInterface*, int, int> SignalEvent; | |
101 | |
102 // Like calling SignalEvent, but posts a message to the specified thread, | |
103 // which will call SignalEvent. This helps unroll the stack and prevent | |
104 // re-entrancy. | |
105 void PostEvent(Thread* t, int events, int err); | |
106 // Like the aforementioned method, but posts to the current thread. | |
107 void PostEvent(int events, int err); | |
108 | |
109 // | |
110 // OPTIONAL OPERATIONS | |
111 // | |
112 // Not all implementations will support the following operations. In general, | |
113 // a stream will only support an operation if it reasonably efficient to do | |
114 // so. For example, while a socket could buffer incoming data to support | |
115 // seeking, it will not do so. Instead, a buffering stream adapter should | |
116 // be used. | |
117 // | |
118 // Even though several of these operations are related, you should | |
119 // always use whichever operation is most relevant. For example, you may | |
120 // be tempted to use GetSize() and GetPosition() to deduce the result of | |
121 // GetAvailable(). However, a stream which is read-once may support the | |
122 // latter operation but not the former. | |
123 // | |
124 | |
125 // The following four methods are used to avoid copying data multiple times. | |
126 | |
127 // GetReadData returns a pointer to a buffer which is owned by the stream. | |
128 // The buffer contains data_len bytes. null is returned if no data is | |
129 // available, or if the method fails. If the caller processes the data, it | |
130 // must call ConsumeReadData with the number of processed bytes. GetReadData | |
131 // does not require a matching call to ConsumeReadData if the data is not | |
132 // processed. Read and ConsumeReadData invalidate the buffer returned by | |
133 // GetReadData. | |
134 virtual const void* GetReadData(size_t* data_len); | |
135 virtual void ConsumeReadData(size_t used) {} | |
136 | |
137 // GetWriteBuffer returns a pointer to a buffer which is owned by the stream. | |
138 // The buffer has a capacity of buf_len bytes. null is returned if there is | |
139 // no buffer available, or if the method fails. The call may write data to | |
140 // the buffer, and then call ConsumeWriteBuffer with the number of bytes | |
141 // written. GetWriteBuffer does not require a matching call to | |
142 // ConsumeWriteData if no data is written. Write, ForceWrite, and | |
143 // ConsumeWriteData invalidate the buffer returned by GetWriteBuffer. | |
144 // TODO: Allow the caller to specify a minimum buffer size. If the specified | |
145 // amount of buffer is not yet available, return null and Signal SE_WRITE | |
146 // when it is available. If the requested amount is too large, return an | |
147 // error. | |
148 virtual void* GetWriteBuffer(size_t* buf_len); | |
149 virtual void ConsumeWriteBuffer(size_t used) {} | |
150 | |
151 // Write data_len bytes found in data, circumventing any throttling which | |
152 // would could cause SR_BLOCK to be returned. Returns true if all the data | |
153 // was written. Otherwise, the method is unsupported, or an unrecoverable | |
154 // error occurred, and the error value is set. This method should be used | |
155 // sparingly to write critical data which should not be throttled. A stream | |
156 // which cannot circumvent its blocking constraints should not implement this | |
157 // method. | |
158 // NOTE: This interface is being considered experimentally at the moment. It | |
159 // would be used by JUDP and BandwidthStream as a way to circumvent certain | |
160 // soft limits in writing. | |
161 //virtual bool ForceWrite(const void* data, size_t data_len, int* error) { | |
162 // if (error) *error = -1; | |
163 // return false; | |
164 //} | |
165 | |
166 // Seek to a byte offset from the beginning of the stream. Returns false if | |
167 // the stream does not support seeking, or cannot seek to the specified | |
168 // position. | |
169 virtual bool SetPosition(size_t position); | |
170 | |
171 // Get the byte offset of the current position from the start of the stream. | |
172 // Returns false if the position is not known. | |
173 virtual bool GetPosition(size_t* position) const; | |
174 | |
175 // Get the byte length of the entire stream. Returns false if the length | |
176 // is not known. | |
177 virtual bool GetSize(size_t* size) const; | |
178 | |
179 // Return the number of Read()-able bytes remaining before end-of-stream. | |
180 // Returns false if not known. | |
181 virtual bool GetAvailable(size_t* size) const; | |
182 | |
183 // Return the number of Write()-able bytes remaining before end-of-stream. | |
184 // Returns false if not known. | |
185 virtual bool GetWriteRemaining(size_t* size) const; | |
186 | |
187 // Return true if flush is successful. | |
188 virtual bool Flush(); | |
189 | |
190 // Communicates the amount of data which will be written to the stream. The | |
191 // stream may choose to preallocate memory to accomodate this data. The | |
192 // stream may return false to indicate that there is not enough room (ie, | |
193 // Write will return SR_EOS/SR_ERROR at some point). Note that calling this | |
194 // function should not affect the existing state of data in the stream. | |
195 virtual bool ReserveSize(size_t size); | |
196 | |
197 // | |
198 // CONVENIENCE METHODS | |
199 // | |
200 // These methods are implemented in terms of other methods, for convenience. | |
201 // | |
202 | |
203 // Seek to the start of the stream. | |
204 inline bool Rewind() { return SetPosition(0); } | |
205 | |
206 // WriteAll is a helper function which repeatedly calls Write until all the | |
207 // data is written, or something other than SR_SUCCESS is returned. Note that | |
208 // unlike Write, the argument 'written' is always set, and may be non-zero | |
209 // on results other than SR_SUCCESS. The remaining arguments have the | |
210 // same semantics as Write. | |
211 StreamResult WriteAll(const void* data, size_t data_len, | |
212 size_t* written, int* error); | |
213 | |
214 // Similar to ReadAll. Calls Read until buffer_len bytes have been read, or | |
215 // until a non-SR_SUCCESS result is returned. 'read' is always set. | |
216 StreamResult ReadAll(void* buffer, size_t buffer_len, | |
217 size_t* read, int* error); | |
218 | |
219 // ReadLine is a helper function which repeatedly calls Read until it hits | |
220 // the end-of-line character, or something other than SR_SUCCESS. | |
221 // TODO: this is too inefficient to keep here. Break this out into a buffered | |
222 // readline object or adapter | |
223 StreamResult ReadLine(std::string* line); | |
224 | |
225 protected: | |
226 StreamInterface(); | |
227 | |
228 // MessageHandler Interface | |
229 void OnMessage(Message* msg) override; | |
230 | |
231 private: | |
232 RTC_DISALLOW_COPY_AND_ASSIGN(StreamInterface); | |
233 }; | |
234 | |
235 /////////////////////////////////////////////////////////////////////////////// | |
236 // StreamAdapterInterface is a convenient base-class for adapting a stream. | |
237 // By default, all operations are pass-through. Override the methods that you | |
238 // require adaptation. Streams should really be upgraded to reference-counted. | |
239 // In the meantime, use the owned flag to indicate whether the adapter should | |
240 // own the adapted stream. | |
241 /////////////////////////////////////////////////////////////////////////////// | |
242 | |
243 class StreamAdapterInterface : public StreamInterface, | |
244 public sigslot::has_slots<> { | |
245 public: | |
246 explicit StreamAdapterInterface(StreamInterface* stream, bool owned = true); | |
247 | |
248 // Core Stream Interface | |
249 StreamState GetState() const override; | |
250 StreamResult Read(void* buffer, | |
251 size_t buffer_len, | |
252 size_t* read, | |
253 int* error) override; | |
254 StreamResult Write(const void* data, | |
255 size_t data_len, | |
256 size_t* written, | |
257 int* error) override; | |
258 void Close() override; | |
259 | |
260 // Optional Stream Interface | |
261 /* Note: Many stream adapters were implemented prior to this Read/Write | |
262 interface. Therefore, a simple pass through of data in those cases may | |
263 be broken. At a later time, we should do a once-over pass of all | |
264 adapters, and make them compliant with these interfaces, after which this | |
265 code can be uncommented. | |
266 virtual const void* GetReadData(size_t* data_len) { | |
267 return stream_->GetReadData(data_len); | |
268 } | |
269 virtual void ConsumeReadData(size_t used) { | |
270 stream_->ConsumeReadData(used); | |
271 } | |
272 | |
273 virtual void* GetWriteBuffer(size_t* buf_len) { | |
274 return stream_->GetWriteBuffer(buf_len); | |
275 } | |
276 virtual void ConsumeWriteBuffer(size_t used) { | |
277 stream_->ConsumeWriteBuffer(used); | |
278 } | |
279 */ | |
280 | |
281 /* Note: This interface is currently undergoing evaluation. | |
282 virtual bool ForceWrite(const void* data, size_t data_len, int* error) { | |
283 return stream_->ForceWrite(data, data_len, error); | |
284 } | |
285 */ | |
286 | |
287 bool SetPosition(size_t position) override; | |
288 bool GetPosition(size_t* position) const override; | |
289 bool GetSize(size_t* size) const override; | |
290 bool GetAvailable(size_t* size) const override; | |
291 bool GetWriteRemaining(size_t* size) const override; | |
292 bool ReserveSize(size_t size) override; | |
293 bool Flush() override; | |
294 | |
295 void Attach(StreamInterface* stream, bool owned = true); | |
296 StreamInterface* Detach(); | |
297 | |
298 protected: | |
299 ~StreamAdapterInterface() override; | |
300 | |
301 // Note that the adapter presents itself as the origin of the stream events, | |
302 // since users of the adapter may not recognize the adapted object. | |
303 virtual void OnEvent(StreamInterface* stream, int events, int err); | |
304 StreamInterface* stream() { return stream_; } | |
305 | |
306 private: | |
307 StreamInterface* stream_; | |
308 bool owned_; | |
309 RTC_DISALLOW_COPY_AND_ASSIGN(StreamAdapterInterface); | |
310 }; | |
311 | |
312 /////////////////////////////////////////////////////////////////////////////// | |
313 // StreamTap is a non-modifying, pass-through adapter, which copies all data | |
314 // in either direction to the tap. Note that errors or blocking on writing to | |
315 // the tap will prevent further tap writes from occurring. | |
316 /////////////////////////////////////////////////////////////////////////////// | |
317 | |
318 class StreamTap : public StreamAdapterInterface { | |
319 public: | |
320 explicit StreamTap(StreamInterface* stream, StreamInterface* tap); | |
321 ~StreamTap() override; | |
322 | |
323 void AttachTap(StreamInterface* tap); | |
324 StreamInterface* DetachTap(); | |
325 StreamResult GetTapResult(int* error); | |
326 | |
327 // StreamAdapterInterface Interface | |
328 StreamResult Read(void* buffer, | |
329 size_t buffer_len, | |
330 size_t* read, | |
331 int* error) override; | |
332 StreamResult Write(const void* data, | |
333 size_t data_len, | |
334 size_t* written, | |
335 int* error) override; | |
336 | |
337 private: | |
338 std::unique_ptr<StreamInterface> tap_; | |
339 StreamResult tap_result_; | |
340 int tap_error_; | |
341 RTC_DISALLOW_COPY_AND_ASSIGN(StreamTap); | |
342 }; | |
343 | |
344 /////////////////////////////////////////////////////////////////////////////// | |
345 // NullStream gives errors on read, and silently discards all written data. | |
346 /////////////////////////////////////////////////////////////////////////////// | |
347 | |
348 class NullStream : public StreamInterface { | |
349 public: | |
350 NullStream(); | |
351 ~NullStream() override; | |
352 | |
353 // StreamInterface Interface | |
354 StreamState GetState() const override; | |
355 StreamResult Read(void* buffer, | |
356 size_t buffer_len, | |
357 size_t* read, | |
358 int* error) override; | |
359 StreamResult Write(const void* data, | |
360 size_t data_len, | |
361 size_t* written, | |
362 int* error) override; | |
363 void Close() override; | |
364 }; | |
365 | |
366 /////////////////////////////////////////////////////////////////////////////// | |
367 // FileStream is a simple implementation of a StreamInterface, which does not | |
368 // support asynchronous notification. | |
369 /////////////////////////////////////////////////////////////////////////////// | |
370 | |
371 class FileStream : public StreamInterface { | |
372 public: | |
373 FileStream(); | |
374 ~FileStream() override; | |
375 | |
376 // The semantics of filename and mode are the same as stdio's fopen | |
377 virtual bool Open(const std::string& filename, const char* mode, int* error); | |
378 virtual bool OpenShare(const std::string& filename, const char* mode, | |
379 int shflag, int* error); | |
380 | |
381 // By default, reads and writes are buffered for efficiency. Disabling | |
382 // buffering causes writes to block until the bytes on disk are updated. | |
383 virtual bool DisableBuffering(); | |
384 | |
385 StreamState GetState() const override; | |
386 StreamResult Read(void* buffer, | |
387 size_t buffer_len, | |
388 size_t* read, | |
389 int* error) override; | |
390 StreamResult Write(const void* data, | |
391 size_t data_len, | |
392 size_t* written, | |
393 int* error) override; | |
394 void Close() override; | |
395 bool SetPosition(size_t position) override; | |
396 bool GetPosition(size_t* position) const override; | |
397 bool GetSize(size_t* size) const override; | |
398 bool GetAvailable(size_t* size) const override; | |
399 bool ReserveSize(size_t size) override; | |
400 | |
401 bool Flush() override; | |
402 | |
403 #if defined(WEBRTC_POSIX) && !defined(__native_client__) | |
404 // Tries to aquire an exclusive lock on the file. | |
405 // Use OpenShare(...) on win32 to get similar functionality. | |
406 bool TryLock(); | |
407 bool Unlock(); | |
408 #endif | |
409 | |
410 // Note: Deprecated in favor of Filesystem::GetFileSize(). | |
411 static bool GetSize(const std::string& filename, size_t* size); | |
412 | |
413 protected: | |
414 virtual void DoClose(); | |
415 | |
416 FILE* file_; | |
417 | |
418 private: | |
419 RTC_DISALLOW_COPY_AND_ASSIGN(FileStream); | |
420 }; | |
421 | |
422 /////////////////////////////////////////////////////////////////////////////// | |
423 // MemoryStream is a simple implementation of a StreamInterface over in-memory | |
424 // data. Data is read and written at the current seek position. Reads return | |
425 // end-of-stream when they reach the end of data. Writes actually extend the | |
426 // end of data mark. | |
427 /////////////////////////////////////////////////////////////////////////////// | |
428 | |
429 class MemoryStreamBase : public StreamInterface { | |
430 public: | |
431 StreamState GetState() const override; | |
432 StreamResult Read(void* buffer, | |
433 size_t bytes, | |
434 size_t* bytes_read, | |
435 int* error) override; | |
436 StreamResult Write(const void* buffer, | |
437 size_t bytes, | |
438 size_t* bytes_written, | |
439 int* error) override; | |
440 void Close() override; | |
441 bool SetPosition(size_t position) override; | |
442 bool GetPosition(size_t* position) const override; | |
443 bool GetSize(size_t* size) const override; | |
444 bool GetAvailable(size_t* size) const override; | |
445 bool ReserveSize(size_t size) override; | |
446 | |
447 char* GetBuffer() { return buffer_; } | |
448 const char* GetBuffer() const { return buffer_; } | |
449 | |
450 protected: | |
451 MemoryStreamBase(); | |
452 | |
453 virtual StreamResult DoReserve(size_t size, int* error); | |
454 | |
455 // Invariant: 0 <= seek_position <= data_length_ <= buffer_length_ | |
456 char* buffer_; | |
457 size_t buffer_length_; | |
458 size_t data_length_; | |
459 size_t seek_position_; | |
460 | |
461 private: | |
462 RTC_DISALLOW_COPY_AND_ASSIGN(MemoryStreamBase); | |
463 }; | |
464 | |
465 // MemoryStream dynamically resizes to accomodate written data. | |
466 | |
467 class MemoryStream : public MemoryStreamBase { | |
468 public: | |
469 MemoryStream(); | |
470 explicit MemoryStream(const char* data); // Calls SetData(data, strlen(data)) | |
471 MemoryStream(const void* data, size_t length); // Calls SetData(data, length) | |
472 ~MemoryStream() override; | |
473 | |
474 void SetData(const void* data, size_t length); | |
475 | |
476 protected: | |
477 StreamResult DoReserve(size_t size, int* error) override; | |
478 // Memory Streams are aligned for efficiency. | |
479 static const int kAlignment = 16; | |
480 char* buffer_alloc_; | |
481 }; | |
482 | |
483 // ExternalMemoryStream adapts an external memory buffer, so writes which would | |
484 // extend past the end of the buffer will return end-of-stream. | |
485 | |
486 class ExternalMemoryStream : public MemoryStreamBase { | |
487 public: | |
488 ExternalMemoryStream(); | |
489 ExternalMemoryStream(void* data, size_t length); | |
490 ~ExternalMemoryStream() override; | |
491 | |
492 void SetData(void* data, size_t length); | |
493 }; | |
494 | |
495 // FifoBuffer allows for efficient, thread-safe buffering of data between | |
496 // writer and reader. As the data can wrap around the end of the buffer, | |
497 // MemoryStreamBase can't help us here. | |
498 | |
499 class FifoBuffer : public StreamInterface { | |
500 public: | |
501 // Creates a FIFO buffer with the specified capacity. | |
502 explicit FifoBuffer(size_t length); | |
503 // Creates a FIFO buffer with the specified capacity and owner | |
504 FifoBuffer(size_t length, Thread* owner); | |
505 ~FifoBuffer() override; | |
506 // Gets the amount of data currently readable from the buffer. | |
507 bool GetBuffered(size_t* data_len) const; | |
508 // Resizes the buffer to the specified capacity. Fails if data_length_ > size | |
509 bool SetCapacity(size_t length); | |
510 | |
511 // Read into |buffer| with an offset from the current read position, offset | |
512 // is specified in number of bytes. | |
513 // This method doesn't adjust read position nor the number of available | |
514 // bytes, user has to call ConsumeReadData() to do this. | |
515 StreamResult ReadOffset(void* buffer, size_t bytes, size_t offset, | |
516 size_t* bytes_read); | |
517 | |
518 // Write |buffer| with an offset from the current write position, offset is | |
519 // specified in number of bytes. | |
520 // This method doesn't adjust the number of buffered bytes, user has to call | |
521 // ConsumeWriteBuffer() to do this. | |
522 StreamResult WriteOffset(const void* buffer, size_t bytes, size_t offset, | |
523 size_t* bytes_written); | |
524 | |
525 // StreamInterface methods | |
526 StreamState GetState() const override; | |
527 StreamResult Read(void* buffer, | |
528 size_t bytes, | |
529 size_t* bytes_read, | |
530 int* error) override; | |
531 StreamResult Write(const void* buffer, | |
532 size_t bytes, | |
533 size_t* bytes_written, | |
534 int* error) override; | |
535 void Close() override; | |
536 const void* GetReadData(size_t* data_len) override; | |
537 void ConsumeReadData(size_t used) override; | |
538 void* GetWriteBuffer(size_t* buf_len) override; | |
539 void ConsumeWriteBuffer(size_t used) override; | |
540 bool GetWriteRemaining(size_t* size) const override; | |
541 | |
542 private: | |
543 // Helper method that implements ReadOffset. Caller must acquire a lock | |
544 // when calling this method. | |
545 StreamResult ReadOffsetLocked(void* buffer, size_t bytes, size_t offset, | |
546 size_t* bytes_read) | |
547 EXCLUSIVE_LOCKS_REQUIRED(crit_); | |
548 | |
549 // Helper method that implements WriteOffset. Caller must acquire a lock | |
550 // when calling this method. | |
551 StreamResult WriteOffsetLocked(const void* buffer, size_t bytes, | |
552 size_t offset, size_t* bytes_written) | |
553 EXCLUSIVE_LOCKS_REQUIRED(crit_); | |
554 | |
555 // keeps the opened/closed state of the stream | |
556 StreamState state_ GUARDED_BY(crit_); | |
557 // the allocated buffer | |
558 std::unique_ptr<char[]> buffer_ GUARDED_BY(crit_); | |
559 // size of the allocated buffer | |
560 size_t buffer_length_ GUARDED_BY(crit_); | |
561 // amount of readable data in the buffer | |
562 size_t data_length_ GUARDED_BY(crit_); | |
563 // offset to the readable data | |
564 size_t read_position_ GUARDED_BY(crit_); | |
565 // stream callbacks are dispatched on this thread | |
566 Thread* owner_; | |
567 // object lock | |
568 CriticalSection crit_; | |
569 RTC_DISALLOW_COPY_AND_ASSIGN(FifoBuffer); | |
570 }; | |
571 | |
572 /////////////////////////////////////////////////////////////////////////////// | |
573 | |
574 class LoggingAdapter : public StreamAdapterInterface { | |
575 public: | |
576 LoggingAdapter(StreamInterface* stream, LoggingSeverity level, | |
577 const std::string& label, bool hex_mode = false); | |
578 | |
579 void set_label(const std::string& label); | |
580 | |
581 StreamResult Read(void* buffer, | |
582 size_t buffer_len, | |
583 size_t* read, | |
584 int* error) override; | |
585 StreamResult Write(const void* data, | |
586 size_t data_len, | |
587 size_t* written, | |
588 int* error) override; | |
589 void Close() override; | |
590 | |
591 protected: | |
592 void OnEvent(StreamInterface* stream, int events, int err) override; | |
593 | |
594 private: | |
595 LoggingSeverity level_; | |
596 std::string label_; | |
597 bool hex_mode_; | |
598 LogMultilineState lms_; | |
599 | |
600 RTC_DISALLOW_COPY_AND_ASSIGN(LoggingAdapter); | |
601 }; | |
602 | |
603 /////////////////////////////////////////////////////////////////////////////// | |
604 // StringStream - Reads/Writes to an external std::string | |
605 /////////////////////////////////////////////////////////////////////////////// | |
606 | |
607 class StringStream : public StreamInterface { | |
608 public: | |
609 explicit StringStream(std::string* str); | |
610 explicit StringStream(const std::string& str); | |
611 | |
612 StreamState GetState() const override; | |
613 StreamResult Read(void* buffer, | |
614 size_t buffer_len, | |
615 size_t* read, | |
616 int* error) override; | |
617 StreamResult Write(const void* data, | |
618 size_t data_len, | |
619 size_t* written, | |
620 int* error) override; | |
621 void Close() override; | |
622 bool SetPosition(size_t position) override; | |
623 bool GetPosition(size_t* position) const override; | |
624 bool GetSize(size_t* size) const override; | |
625 bool GetAvailable(size_t* size) const override; | |
626 bool ReserveSize(size_t size) override; | |
627 | |
628 private: | |
629 std::string& str_; | |
630 size_t read_pos_; | |
631 bool read_only_; | |
632 }; | |
633 | |
634 /////////////////////////////////////////////////////////////////////////////// | |
635 // StreamReference - A reference counting stream adapter | |
636 /////////////////////////////////////////////////////////////////////////////// | |
637 | |
638 // Keep in mind that the streams and adapters defined in this file are | |
639 // not thread-safe, so this has limited uses. | |
640 | |
641 // A StreamRefCount holds the reference count and a pointer to the | |
642 // wrapped stream. It deletes the wrapped stream when there are no | |
643 // more references. We can then have multiple StreamReference | |
644 // instances pointing to one StreamRefCount, all wrapping the same | |
645 // stream. | |
646 | |
647 class StreamReference : public StreamAdapterInterface { | |
648 class StreamRefCount; | |
649 public: | |
650 // Constructor for the first reference to a stream | |
651 // Note: get more references through NewReference(). Use this | |
652 // constructor only once on a given stream. | |
653 explicit StreamReference(StreamInterface* stream); | |
654 StreamInterface* GetStream() { return stream(); } | |
655 StreamInterface* NewReference(); | |
656 ~StreamReference() override; | |
657 | |
658 private: | |
659 class StreamRefCount { | |
660 public: | |
661 explicit StreamRefCount(StreamInterface* stream) | |
662 : stream_(stream), ref_count_(1) { | |
663 } | |
664 void AddReference() { | |
665 CritScope lock(&cs_); | |
666 ++ref_count_; | |
667 } | |
668 void Release() { | |
669 int ref_count; | |
670 { // Atomic ops would have been a better fit here. | |
671 CritScope lock(&cs_); | |
672 ref_count = --ref_count_; | |
673 } | |
674 if (ref_count == 0) { | |
675 delete stream_; | |
676 delete this; | |
677 } | |
678 } | |
679 private: | |
680 StreamInterface* stream_; | |
681 int ref_count_; | |
682 CriticalSection cs_; | |
683 RTC_DISALLOW_COPY_AND_ASSIGN(StreamRefCount); | |
684 }; | |
685 | |
686 // Constructor for adding references | |
687 explicit StreamReference(StreamRefCount* stream_ref_count, | |
688 StreamInterface* stream); | |
689 | |
690 StreamRefCount* stream_ref_count_; | |
691 RTC_DISALLOW_COPY_AND_ASSIGN(StreamReference); | |
692 }; | |
693 | |
694 /////////////////////////////////////////////////////////////////////////////// | |
695 | |
696 // Flow attempts to move bytes from source to sink via buffer of size | |
697 // buffer_len. The function returns SR_SUCCESS when source reaches | |
698 // end-of-stream (returns SR_EOS), and all the data has been written successful | |
699 // to sink. Alternately, if source returns SR_BLOCK or SR_ERROR, or if sink | |
700 // returns SR_BLOCK, SR_ERROR, or SR_EOS, then the function immediately returns | |
701 // with the unexpected StreamResult value. | |
702 // data_len is the length of the valid data in buffer. in case of error | |
703 // this is the data that read from source but can't move to destination. | |
704 // as a pass in parameter, it indicates data in buffer that should move to sink | |
705 StreamResult Flow(StreamInterface* source, | |
706 char* buffer, | |
707 size_t buffer_len, | |
708 StreamInterface* sink, | |
709 size_t* data_len = nullptr); | |
710 | |
711 /////////////////////////////////////////////////////////////////////////////// | |
712 | |
713 } // namespace rtc | |
714 | 18 |
715 #endif // WEBRTC_BASE_STREAM_H_ | 19 #endif // WEBRTC_BASE_STREAM_H_ |
OLD | NEW |