| 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 |