147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX)
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <sys/file.h>
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_POSIX
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <sys/types.h>
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <sys/stat.h>
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <errno.h>
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string>
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/basictypes.h"
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h"
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h"
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/messagequeue.h"
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stream.h"
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stringencode.h"
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stringutils.h"
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h"
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/timeutils.h"
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h"
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define fileno _fileno
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// StreamInterface
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamInterface::~StreamInterface() {
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StreamInterface::WriteAll(const void* data, size_t data_len,
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                       size_t* written, int* error) {
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = SR_SUCCESS;
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t total_written = 0, current_written;
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (total_written < data_len) {
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    result = Write(static_cast<const char*>(data) + total_written,
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   data_len - total_written, &current_written, error);
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (result != SR_SUCCESS)
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    total_written += current_written;
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (written)
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *written = total_written;
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StreamInterface::ReadAll(void* buffer, size_t buffer_len,
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                      size_t* read, int* error) {
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = SR_SUCCESS;
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t total_read = 0, current_read;
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (total_read < buffer_len) {
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    result = Read(static_cast<char*>(buffer) + total_read,
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                  buffer_len - total_read, &current_read, error);
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (result != SR_SUCCESS)
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    total_read += current_read;
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (read)
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *read = total_read;
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StreamInterface::ReadLine(std::string* line) {
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  line->clear();
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = SR_SUCCESS;
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (true) {
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    char ch;
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    result = Read(&ch, sizeof(ch), NULL, NULL);
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (result != SR_SUCCESS) {
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (ch == '\n') {
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    line->push_back(ch);
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!line->empty()) {   // give back the line we've collected so far with
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    result = SR_SUCCESS;  // a success code.  Otherwise return the last code
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid StreamInterface::PostEvent(Thread* t, int events, int err) {
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  t->Post(this, MSG_POST_EVENT, new StreamEventData(events, err));
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid StreamInterface::PostEvent(int events, int err) {
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  PostEvent(Thread::Current(), events, err);
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamInterface::StreamInterface() {
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid StreamInterface::OnMessage(Message* msg) {
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (MSG_POST_EVENT == msg->message_id) {
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    StreamEventData* pe = static_cast<StreamEventData*>(msg->pdata);
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SignalEvent(this, pe->events, pe->error);
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete msg->pdata;
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// StreamAdapterInterface
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamAdapterInterface::StreamAdapterInterface(StreamInterface* stream,
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                               bool owned)
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : stream_(stream), owned_(owned) {
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (NULL != stream_)
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent);
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid StreamAdapterInterface::Attach(StreamInterface* stream, bool owned) {
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (NULL != stream_)
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    stream_->SignalEvent.disconnect(this);
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (owned_)
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete stream_;
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream_ = stream;
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  owned_ = owned;
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (NULL != stream_)
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    stream_->SignalEvent.connect(this, &StreamAdapterInterface::OnEvent);
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamInterface* StreamAdapterInterface::Detach() {
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (NULL != stream_)
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    stream_->SignalEvent.disconnect(this);
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamInterface* stream = stream_;
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream_ = NULL;
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return stream;
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamAdapterInterface::~StreamAdapterInterface() {
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (owned_)
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete stream_;
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// StreamTap
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamTap::StreamTap(StreamInterface* stream, StreamInterface* tap)
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : StreamAdapterInterface(stream), tap_(), tap_result_(SR_SUCCESS),
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        tap_error_(0) {
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AttachTap(tap);
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid StreamTap::AttachTap(StreamInterface* tap) {
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  tap_.reset(tap);
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamInterface* StreamTap::DetachTap() {
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return tap_.release();
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StreamTap::GetTapResult(int* error) {
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (error) {
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *error = tap_error_;
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return tap_result_;
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StreamTap::Read(void* buffer, size_t buffer_len,
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             size_t* read, int* error) {
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t backup_read;
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!read) {
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read = &backup_read;
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult res = StreamAdapterInterface::Read(buffer, buffer_len,
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                  read, error);
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) {
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    tap_result_ = tap_->WriteAll(buffer, *read, NULL, &tap_error_);
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return res;
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StreamTap::Write(const void* data, size_t data_len,
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              size_t* written, int* error) {
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t backup_written;
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!written) {
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    written = &backup_written;
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult res = StreamAdapterInterface::Write(data, data_len,
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                   written, error);
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((res == SR_SUCCESS) && (tap_result_ == SR_SUCCESS)) {
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    tap_result_ = tap_->WriteAll(data, *written, NULL, &tap_error_);
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return res;
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// StreamSegment
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamSegment::StreamSegment(StreamInterface* stream)
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : StreamAdapterInterface(stream), start_(SIZE_UNKNOWN), pos_(0),
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    length_(SIZE_UNKNOWN) {
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // It's ok for this to fail, in which case start_ is left as SIZE_UNKNOWN.
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream->GetPosition(&start_);
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamSegment::StreamSegment(StreamInterface* stream, size_t length)
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : StreamAdapterInterface(stream), start_(SIZE_UNKNOWN), pos_(0),
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    length_(length) {
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // It's ok for this to fail, in which case start_ is left as SIZE_UNKNOWN.
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream->GetPosition(&start_);
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StreamSegment::Read(void* buffer, size_t buffer_len,
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 size_t* read, int* error) {
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SIZE_UNKNOWN != length_) {
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (pos_ >= length_)
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return SR_EOS;
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_len = _min(buffer_len, length_ - pos_);
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t backup_read;
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!read) {
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read = &backup_read;
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = StreamAdapterInterface::Read(buffer, buffer_len,
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                     read, error);
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SR_SUCCESS == result) {
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    pos_ += *read;
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StreamSegment::SetPosition(size_t position) {
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SIZE_UNKNOWN == start_)
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;  // Not seekable
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((SIZE_UNKNOWN != length_) && (position > length_))
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;  // Seek past end of segment
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!StreamAdapterInterface::SetPosition(start_ + position))
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  pos_ = position;
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StreamSegment::GetPosition(size_t* position) const {
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SIZE_UNKNOWN == start_)
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;  // Not seekable
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!StreamAdapterInterface::GetPosition(position))
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (position) {
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(*position >= start_);
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *position -= start_;
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StreamSegment::GetSize(size_t* size) const {
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!StreamAdapterInterface::GetSize(size))
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size) {
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SIZE_UNKNOWN != start_) {
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT(*size >= start_);
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *size -= start_;
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SIZE_UNKNOWN != length_) {
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *size = _min(*size, length_);
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StreamSegment::GetAvailable(size_t* size) const {
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!StreamAdapterInterface::GetAvailable(size))
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size && (SIZE_UNKNOWN != length_))
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *size = _min(*size, length_ - pos_);
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// NullStream
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgNullStream::NullStream() {
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgNullStream::~NullStream() {
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamState NullStream::GetState() const {
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SS_OPEN;
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult NullStream::Read(void* buffer, size_t buffer_len,
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              size_t* read, int* error) {
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (error) *error = -1;
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_ERROR;
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult NullStream::Write(const void* data, size_t data_len,
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               size_t* written, int* error) {
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (written) *written = data_len;
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid NullStream::Close() {
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// FileStream
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgFileStream::FileStream() : file_(NULL) {
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgFileStream::~FileStream() {
32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  FileStream::Close();
32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::Open(const std::string& filename, const char* mode,
32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      int* error) {
32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Close();
32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring wfilename;
32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (Utf8ToWindowsFilename(filename, &wfilename)) {
32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    file_ = _wfopen(wfilename.c_str(), ToUtf16(mode).c_str());
33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (error) {
33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *error = -1;
33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return false;
33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  file_ = fopen(filename.c_str(), mode);
33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!file_ && error) {
34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *error = errno;
34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (file_ != NULL);
34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::OpenShare(const std::string& filename, const char* mode,
34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                           int shflag, int* error) {
34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Close();
34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::wstring wfilename;
35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (Utf8ToWindowsFilename(filename, &wfilename)) {
35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    file_ = _wfsopen(wfilename.c_str(), ToUtf16(mode).c_str(), shflag);
35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!file_ && error) {
35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *error = errno;
35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return false;
35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return file_ != NULL;
35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (error) {
35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *error = -1;
36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return Open(filename, mode, error);
36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::DisableBuffering() {
36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!file_)
37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (setvbuf(file_, NULL, _IONBF, 0) == 0);
37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamState FileStream::GetState() const {
37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (file_ == NULL) ? SS_CLOSED : SS_OPEN;
37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FileStream::Read(void* buffer, size_t buffer_len,
37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              size_t* read, int* error) {
38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!file_)
38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_EOS;
38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t result = fread(buffer, 1, buffer_len, file_);
38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((result == 0) && (buffer_len > 0)) {
38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (feof(file_))
38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return SR_EOS;
38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (error)
38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *error = errno;
38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_ERROR;
38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (read)
39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *read = result;
39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FileStream::Write(const void* data, size_t data_len,
39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               size_t* written, int* error) {
39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!file_)
39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_EOS;
39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t result = fwrite(data, 1, data_len, file_);
40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((result == 0) && (data_len > 0)) {
40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (error)
40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *error = errno;
40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_ERROR;
40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (written)
40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *written = result;
40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid FileStream::Close() {
41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (file_) {
41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DoClose();
41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    file_ = NULL;
41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::SetPosition(size_t position) {
41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!file_)
41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (fseek(file_, static_cast<int>(position), SEEK_SET) == 0);
42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::GetPosition(size_t* position) const {
42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(NULL != position);
42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!file_)
42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  long result = ftell(file_);
42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result < 0)
42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (position)
43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *position = result;
43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::GetSize(size_t* size) const {
43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(NULL != size);
43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!file_)
43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  struct stat file_stats;
44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (fstat(fileno(file_), &file_stats) != 0)
44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size)
44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *size = file_stats.st_size;
44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::GetAvailable(size_t* size) const {
44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(NULL != size);
44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!GetSize(size))
45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  long result = ftell(file_);
45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result < 0)
45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size)
45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *size -= result;
45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::ReserveSize(size_t size) {
46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: extend the file to the proper length
46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::GetSize(const std::string& filename, size_t* size) {
46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  struct stat file_stats;
46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (stat(filename.c_str(), &file_stats) != 0)
46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *size = file_stats.st_size;
46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
47247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::Flush() {
47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (file_) {
47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return (0 == fflush(file_));
47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // try to flush empty file?
47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(false);
47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return false;
47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) && !defined(__native_client__)
48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::TryLock() {
48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (file_ == NULL) {
48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Stream not open.
48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(false);
48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return flock(fileno(file_), LOCK_EX|LOCK_NB) == 0;
49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FileStream::Unlock() {
49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (file_ == NULL) {
49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Stream not open.
49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(false);
49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return flock(fileno(file_), LOCK_UN) == 0;
50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid FileStream::DoClose() {
50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  fclose(file_);
50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgCircularFileStream::CircularFileStream(size_t max_size)
51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  : max_write_size_(max_size),
51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    position_(0),
51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    marked_position_(max_size / 2),
51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    last_write_position_(0),
51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_segment_(READ_LATEST),
51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_segment_available_(0) {
51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool CircularFileStream::Open(
51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const std::string& filename, const char* mode, int* error) {
52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!FileStream::Open(filename.c_str(), mode, error))
52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
52247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
52347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (strchr(mode, "r") != NULL) {  // Opened in read mode.
52447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Check if the buffer has been overwritten and determine how to read the
52547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // log in time sequence.
52647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t file_size;
52747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    GetSize(&file_size);
52847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (file_size == position_) {
52947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // The buffer has not been overwritten yet. Read 0 .. file_size
53047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      read_segment_ = READ_LATEST;
53147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      read_segment_available_ = file_size;
53247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
53347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // The buffer has been over written. There are three segments: The first
53447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // one is 0 .. marked_position_, which is the marked earliest log. The
53547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // second one is position_ .. file_size, which is the middle log. The
53647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // last one is marked_position_ .. position_, which is the latest log.
53747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      read_segment_ = READ_MARKED;
53847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      read_segment_available_ = marked_position_;
53947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      last_write_position_ = position_;
54047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
54147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
54247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Read from the beginning.
54347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    position_ = 0;
54447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SetPosition(position_);
54547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
54647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
54747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
54847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
54947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
55047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult CircularFileStream::Read(void* buffer, size_t buffer_len,
55147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                      size_t* read, int* error) {
55247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (read_segment_available_ == 0) {
55347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t file_size;
55447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    switch (read_segment_) {
55547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      case READ_MARKED:  // Finished READ_MARKED and start READ_MIDDLE.
55647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        read_segment_ = READ_MIDDLE;
55747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        position_ = last_write_position_;
55847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        SetPosition(position_);
55947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        GetSize(&file_size);
56047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        read_segment_available_ = file_size - position_;
56147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        break;
56247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
56347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      case READ_MIDDLE:  // Finished READ_MIDDLE and start READ_LATEST.
56447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        read_segment_ = READ_LATEST;
56547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        position_ = marked_position_;
56647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        SetPosition(position_);
56747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        read_segment_available_ = last_write_position_ - position_;
56847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        break;
56947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      default:  // Finished READ_LATEST and return EOS.
57147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return rtc::SR_EOS;
57247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
57347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
57447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t local_read;
57647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!read) read = &local_read;
57747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t to_read = rtc::_min(buffer_len, read_segment_available_);
57947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::StreamResult result
58047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    = rtc::FileStream::Read(buffer, to_read, read, error);
58147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result == rtc::SR_SUCCESS) {
58247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_segment_available_ -= *read;
58347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    position_ += *read;
58447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
58547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
58647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
58747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult CircularFileStream::Write(const void* data, size_t data_len,
58947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                       size_t* written, int* error) {
59047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (position_ >= max_write_size_) {
59147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(position_ == max_write_size_);
59247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    position_ = marked_position_;
59347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SetPosition(position_);
59447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
59547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
59647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t local_written;
59747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!written) written = &local_written;
59847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
59947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t to_eof = max_write_size_ - position_;
60047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t to_write = rtc::_min(data_len, to_eof);
60147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::StreamResult result
60247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    = rtc::FileStream::Write(data, to_write, written, error);
60347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result == rtc::SR_SUCCESS) {
60447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    position_ += *written;
60547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
60647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
60747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
60847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncWriteStream::~AsyncWriteStream() {
61047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  write_thread_->Clear(this, 0, NULL);
61147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ClearBufferAndWrite();
61247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_stream_);
61447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream_.reset();
61547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
61647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// This is needed by some stream writers, such as RtpDumpWriter.
61847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool AsyncWriteStream::GetPosition(size_t* position) const {
61947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_stream_);
62047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return stream_->GetPosition(position);
62147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
62247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
62347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// This is needed by some stream writers, such as the plugin log writers.
62447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult AsyncWriteStream::Read(void* buffer, size_t buffer_len,
62547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                    size_t* read, int* error) {
62647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_stream_);
62747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return stream_->Read(buffer, buffer_len, read, error);
62847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
62947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
63047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncWriteStream::Close() {
63147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (state_ == SS_CLOSED) {
63247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;
63347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
63447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
63547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  write_thread_->Clear(this, 0, NULL);
63647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ClearBufferAndWrite();
63747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
63847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_stream_);
63947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream_->Close();
64047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  state_ = SS_CLOSED;
64147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
64247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult AsyncWriteStream::Write(const void* data, size_t data_len,
64447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     size_t* written, int* error) {
64547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (state_ == SS_CLOSED) {
64647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_ERROR;
64747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
64847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t previous_buffer_length = 0;
65047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  {
65147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CritScope cs(&crit_buffer_);
65247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    previous_buffer_length = buffer_.length();
65347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_.AppendData(data, data_len);
65447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
65547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
65647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (previous_buffer_length == 0) {
65747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // If there's stuff already in the buffer, then we already called
65847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Post and the write_thread_ hasn't pulled it out yet, so we
65947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // don't need to re-Post.
66047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    write_thread_->Post(this, 0, NULL);
66147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
66247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Return immediately, assuming that it works.
66347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (written) {
66447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *written = data_len;
66547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
66647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
66747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
66847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
66947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncWriteStream::OnMessage(rtc::Message* pmsg) {
67047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ClearBufferAndWrite();
67147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
67247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
67347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool AsyncWriteStream::Flush() {
67447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (state_ == SS_CLOSED) {
67547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
67647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
67747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
67847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ClearBufferAndWrite();
67947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_stream_);
68147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return stream_->Flush();
68247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
68347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid AsyncWriteStream::ClearBufferAndWrite() {
68547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Buffer to_write;
68647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  {
68747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CritScope cs_buffer(&crit_buffer_);
68847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_.TransferTo(&to_write);
68947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
69047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (to_write.length() > 0) {
69247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CritScope cs(&crit_stream_);
69347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    stream_->WriteAll(to_write.data(), to_write.length(), NULL, NULL);
69447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
69547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
69647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_POSIX) && !defined(__native_client__)
69847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Have to identically rewrite the FileStream destructor or else it would call
70047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// the base class's Close() instead of the sub-class's.
70147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgPOpenStream::~POpenStream() {
70247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  POpenStream::Close();
70347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
70447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
70547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool POpenStream::Open(const std::string& subcommand,
70647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       const char* mode,
70747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       int* error) {
70847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Close();
70947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  file_ = popen(subcommand.c_str(), mode);
71047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (file_ == NULL) {
71147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (error)
71247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *error = errno;
71347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
71447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
71547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
71647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
71747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
71847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool POpenStream::OpenShare(const std::string& subcommand, const char* mode,
71947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            int shflag, int* error) {
72047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return Open(subcommand, mode, error);
72147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
72247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
72347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid POpenStream::DoClose() {
72447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  wait_status_ = pclose(file_);
72547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
72647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
72747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
72847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
72947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
73047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// MemoryStream
73147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
73247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
73347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgMemoryStreamBase::MemoryStreamBase()
73447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  : buffer_(NULL), buffer_length_(0), data_length_(0),
73547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    seek_position_(0) {
73647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
73747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
73847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamState MemoryStreamBase::GetState() const {
73947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SS_OPEN;
74047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
74147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
74247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult MemoryStreamBase::Read(void* buffer, size_t bytes,
74347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                    size_t* bytes_read, int* error) {
74447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (seek_position_ >= data_length_) {
74547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_EOS;
74647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
74747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t available = data_length_ - seek_position_;
74847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (bytes > available) {
74947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Read partial buffer
75047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    bytes = available;
75147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
75247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(buffer, &buffer_[seek_position_], bytes);
75347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  seek_position_ += bytes;
75447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (bytes_read) {
75547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *bytes_read = bytes;
75647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
75747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
75847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
75947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
76047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult MemoryStreamBase::Write(const void* buffer, size_t bytes,
76147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     size_t* bytes_written, int* error) {
76247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t available = buffer_length_ - seek_position_;
76347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (0 == available) {
76447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Increase buffer size to the larger of:
76547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // a) new position rounded up to next 256 bytes
76647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // b) double the previous length
76747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t new_buffer_length = _max(((seek_position_ + bytes) | 0xFF) + 1,
76847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                    buffer_length_ * 2);
76947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    StreamResult result = DoReserve(new_buffer_length, error);
77047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SR_SUCCESS != result) {
77147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return result;
77247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
77347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(buffer_length_ >= new_buffer_length);
77447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    available = buffer_length_ - seek_position_;
77547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
77647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
77747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (bytes > available) {
77847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    bytes = available;
77947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
78047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(&buffer_[seek_position_], buffer, bytes);
78147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  seek_position_ += bytes;
78247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_length_ < seek_position_) {
78347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    data_length_ = seek_position_;
78447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
78547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (bytes_written) {
78647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *bytes_written = bytes;
78747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
78847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
78947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
79047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid MemoryStreamBase::Close() {
79247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // nothing to do
79347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
79447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool MemoryStreamBase::SetPosition(size_t position) {
79647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (position > data_length_)
79747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
79847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  seek_position_ = position;
79947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
80047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
80147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool MemoryStreamBase::GetPosition(size_t* position) const {
80347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (position)
80447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *position = seek_position_;
80547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
80647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
80747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool MemoryStreamBase::GetSize(size_t* size) const {
80947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size)
81047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *size = data_length_;
81147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
81247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
81347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool MemoryStreamBase::GetAvailable(size_t* size) const {
81547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size)
81647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *size = data_length_ - seek_position_;
81747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
81847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
81947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool MemoryStreamBase::ReserveSize(size_t size) {
82147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (SR_SUCCESS == DoReserve(size, NULL));
82247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
82347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult MemoryStreamBase::DoReserve(size_t size, int* error) {
82547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (buffer_length_ >= size) ? SR_SUCCESS : SR_EOS;
82647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
82747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
82947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgMemoryStream::MemoryStream()
83147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  : buffer_alloc_(NULL) {
83247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
83347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgMemoryStream::MemoryStream(const char* data)
83547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  : buffer_alloc_(NULL) {
83647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SetData(data, strlen(data));
83747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
83847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgMemoryStream::MemoryStream(const void* data, size_t length)
84047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  : buffer_alloc_(NULL) {
84147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SetData(data, length);
84247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
84347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
84447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgMemoryStream::~MemoryStream() {
84547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete [] buffer_alloc_;
84647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
84747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
84847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid MemoryStream::SetData(const void* data, size_t length) {
84947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  data_length_ = buffer_length_ = length;
85047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete [] buffer_alloc_;
85147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  buffer_alloc_ = new char[buffer_length_ + kAlignment];
85247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  buffer_ = reinterpret_cast<char*>(ALIGNP(buffer_alloc_, kAlignment));
85347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(buffer_, data, data_length_);
85447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  seek_position_ = 0;
85547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
85647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
85747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult MemoryStream::DoReserve(size_t size, int* error) {
85847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (buffer_length_ >= size)
85947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_SUCCESS;
86047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
86147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (char* new_buffer_alloc = new char[size + kAlignment]) {
86247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    char* new_buffer = reinterpret_cast<char*>(
86347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ALIGNP(new_buffer_alloc, kAlignment));
86447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(new_buffer, buffer_, data_length_);
86547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete [] buffer_alloc_;
86647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_alloc_ = new_buffer_alloc;
86747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_ = new_buffer;
86847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_length_ = size;
86947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_SUCCESS;
87047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
87147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
87247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (error) {
87347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *error = ENOMEM;
87447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
87547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_ERROR;
87647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
87747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
87847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
87947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgExternalMemoryStream::ExternalMemoryStream() {
88147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
88247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgExternalMemoryStream::ExternalMemoryStream(void* data, size_t length) {
88447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SetData(data, length);
88547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
88647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgExternalMemoryStream::~ExternalMemoryStream() {
88847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
88947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
89047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid ExternalMemoryStream::SetData(void* data, size_t length) {
89147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  data_length_ = buffer_length_ = length;
89247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  buffer_ = static_cast<char*>(data);
89347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  seek_position_ = 0;
89447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
89547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
89647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
89747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// FifoBuffer
89847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
89947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgFifoBuffer::FifoBuffer(size_t size)
90147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : state_(SS_OPEN), buffer_(new char[size]), buffer_length_(size),
90247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      data_length_(0), read_position_(0), owner_(Thread::Current()) {
90347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // all events are done on the owner_ thread
90447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
90547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgFifoBuffer::FifoBuffer(size_t size, Thread* owner)
90747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : state_(SS_OPEN), buffer_(new char[size]), buffer_length_(size),
90847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      data_length_(0), read_position_(0), owner_(owner) {
90947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // all events are done on the owner_ thread
91047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
91147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
91247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgFifoBuffer::~FifoBuffer() {
91347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
91447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
91547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FifoBuffer::GetBuffered(size_t* size) const {
91647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
91747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *size = data_length_;
91847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
91947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
92047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
92147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FifoBuffer::SetCapacity(size_t size) {
92247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
92347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_length_ > size) {
92447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
92547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
92647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
92747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size != buffer_length_) {
92847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    char* buffer = new char[size];
92947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const size_t copy = data_length_;
93047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const size_t tail_copy = _min(copy, buffer_length_ - read_position_);
93147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(buffer, &buffer_[read_position_], tail_copy);
93247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(buffer + tail_copy, &buffer_[0], copy - tail_copy);
93347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_.reset(buffer);
93447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_position_ = 0;
93547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer_length_ = size;
93647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
93747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
93847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
93947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
94047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FifoBuffer::ReadOffset(void* buffer, size_t bytes,
94147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                    size_t offset, size_t* bytes_read) {
94247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
94347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ReadOffsetLocked(buffer, bytes, offset, bytes_read);
94447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
94547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
94647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FifoBuffer::WriteOffset(const void* buffer, size_t bytes,
94747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                     size_t offset, size_t* bytes_written) {
94847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
94947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return WriteOffsetLocked(buffer, bytes, offset, bytes_written);
95047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
95147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamState FifoBuffer::GetState() const {
95347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return state_;
95447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
95547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FifoBuffer::Read(void* buffer, size_t bytes,
95747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              size_t* bytes_read, int* error) {
95847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
95947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const bool was_writable = data_length_ < buffer_length_;
96047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t copy = 0;
96147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = ReadOffsetLocked(buffer, bytes, 0, &copy);
96247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
96347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result == SR_SUCCESS) {
96447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // If read was successful then adjust the read position and number of
96547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // bytes buffered.
96647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_position_ = (read_position_ + copy) % buffer_length_;
96747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    data_length_ -= copy;
96847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (bytes_read) {
96947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *bytes_read = copy;
97047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
97147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
97247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // if we were full before, and now we're not, post an event
97347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!was_writable && copy > 0) {
97447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      PostEvent(owner_, SE_WRITE, 0);
97547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
97647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
97747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
97847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
97947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
98047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FifoBuffer::Write(const void* buffer, size_t bytes,
98147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               size_t* bytes_written, int* error) {
98247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
98347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
98447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const bool was_readable = (data_length_ > 0);
98547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t copy = 0;
98647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = WriteOffsetLocked(buffer, bytes, 0, &copy);
98747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
98847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result == SR_SUCCESS) {
98947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // If write was successful then adjust the number of readable bytes.
99047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    data_length_ += copy;
99147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (bytes_written) {
99247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *bytes_written = copy;
99347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
99447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
99547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // if we didn't have any data to read before, and now we do, post an event
99647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!was_readable && copy > 0) {
99747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      PostEvent(owner_, SE_READ, 0);
99847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
99947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
100047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
100147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
100247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
100347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid FifoBuffer::Close() {
100447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
100547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  state_ = SS_CLOSED;
100647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
100747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
100847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst void* FifoBuffer::GetReadData(size_t* size) {
100947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
101047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *size = (read_position_ + data_length_ <= buffer_length_) ?
101147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      data_length_ : buffer_length_ - read_position_;
101247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return &buffer_[read_position_];
101347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
101447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
101547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid FifoBuffer::ConsumeReadData(size_t size) {
101647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
101747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(size <= data_length_);
101847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const bool was_writable = data_length_ < buffer_length_;
101947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  read_position_ = (read_position_ + size) % buffer_length_;
102047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  data_length_ -= size;
102147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!was_writable && size > 0) {
102247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    PostEvent(owner_, SE_WRITE, 0);
102347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
102447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
102547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
102647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid* FifoBuffer::GetWriteBuffer(size_t* size) {
102747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
102847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (state_ == SS_CLOSED) {
102947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return NULL;
103047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
103147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // if empty, reset the write position to the beginning, so we can get
103347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // the biggest possible block
103447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_length_ == 0) {
103547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_position_ = 0;
103647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
103747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t write_position = (read_position_ + data_length_)
103947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      % buffer_length_;
104047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *size = (write_position > read_position_ || data_length_ == 0) ?
104147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      buffer_length_ - write_position : read_position_ - write_position;
104247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return &buffer_[write_position];
104347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
104447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
104547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid FifoBuffer::ConsumeWriteBuffer(size_t size) {
104647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
104747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(size <= buffer_length_ - data_length_);
104847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const bool was_readable = (data_length_ > 0);
104947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  data_length_ += size;
105047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!was_readable && size > 0) {
105147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    PostEvent(owner_, SE_READ, 0);
105247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
105347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
105447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
105547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool FifoBuffer::GetWriteRemaining(size_t* size) const {
105647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
105747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  *size = buffer_length_ - data_length_;
105847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
105947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
106047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
106147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FifoBuffer::ReadOffsetLocked(void* buffer,
106247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          size_t bytes,
106347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          size_t offset,
106447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          size_t* bytes_read) {
106547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (offset >= data_length_) {
106647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return (state_ != SS_CLOSED) ? SR_BLOCK : SR_EOS;
106747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
106847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
106947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t available = data_length_ - offset;
107047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t read_position = (read_position_ + offset) % buffer_length_;
107147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t copy = _min(bytes, available);
107247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t tail_copy = _min(copy, buffer_length_ - read_position);
107347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char* const p = static_cast<char*>(buffer);
107447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(p, &buffer_[read_position], tail_copy);
107547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(p + tail_copy, &buffer_[0], copy - tail_copy);
107647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
107747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (bytes_read) {
107847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *bytes_read = copy;
107947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
108047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
108147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
108247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
108347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult FifoBuffer::WriteOffsetLocked(const void* buffer,
108447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           size_t bytes,
108547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           size_t offset,
108647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           size_t* bytes_written) {
108747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (state_ == SS_CLOSED) {
108847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_EOS;
108947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
109047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
109147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_length_ + offset >= buffer_length_) {
109247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_BLOCK;
109347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
109447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
109547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t available = buffer_length_ - data_length_ - offset;
109647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t write_position = (read_position_ + data_length_ + offset)
109747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      % buffer_length_;
109847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t copy = _min(bytes, available);
109947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t tail_copy = _min(copy, buffer_length_ - write_position);
110047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* const p = static_cast<const char*>(buffer);
110147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(&buffer_[write_position], p, tail_copy);
110247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(&buffer_[0], p + tail_copy, copy - tail_copy);
110347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
110447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (bytes_written) {
110547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *bytes_written = copy;
110647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
110747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
110847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
110947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
111047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
111147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
111247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
111347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// LoggingAdapter
111447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
111547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
111647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgLoggingAdapter::LoggingAdapter(StreamInterface* stream, LoggingSeverity level,
111747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                               const std::string& label, bool hex_mode)
111847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : StreamAdapterInterface(stream), level_(level), hex_mode_(hex_mode) {
111947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  set_label(label);
112047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
112147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
112247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid LoggingAdapter::set_label(const std::string& label) {
112347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  label_.assign("[");
112447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  label_.append(label);
112547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  label_.append("]");
112647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
112747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
112847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult LoggingAdapter::Read(void* buffer, size_t buffer_len,
112947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  size_t* read, int* error) {
113047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t local_read; if (!read) read = &local_read;
113147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = StreamAdapterInterface::Read(buffer, buffer_len, read,
113247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                     error);
113347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result == SR_SUCCESS) {
113447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LogMultiline(level_, label_.c_str(), true, buffer, *read, hex_mode_, &lms_);
113547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
113647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
113747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
113847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
113947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult LoggingAdapter::Write(const void* data, size_t data_len,
114047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                   size_t* written, int* error) {
114147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t local_written;
114247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!written) written = &local_written;
114347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result = StreamAdapterInterface::Write(data, data_len, written,
114447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                      error);
114547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result == SR_SUCCESS) {
114647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LogMultiline(level_, label_.c_str(), false, data, *written, hex_mode_,
114747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 &lms_);
114847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
114947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
115047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
115147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
115247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid LoggingAdapter::Close() {
115347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
115447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
115547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG_V(level_) << label_ << " Closed locally";
115647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamAdapterInterface::Close();
115747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
115847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
115947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid LoggingAdapter::OnEvent(StreamInterface* stream, int events, int err) {
116047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (events & SE_OPEN) {
116147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG_V(level_) << label_ << " Open";
116247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (events & SE_CLOSE) {
116347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LogMultiline(level_, label_.c_str(), false, NULL, 0, hex_mode_, &lms_);
116447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LogMultiline(level_, label_.c_str(), true, NULL, 0, hex_mode_, &lms_);
116547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG_V(level_) << label_ << " Closed with error: " << err;
116647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
116747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamAdapterInterface::OnEvent(stream, events, err);
116847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
116947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
117047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
117147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// StringStream - Reads/Writes to an external std::string
117247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
117347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
117447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStringStream::StringStream(std::string& str)
117547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : str_(str), read_pos_(0), read_only_(false) {
117647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
117747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
117847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStringStream::StringStream(const std::string& str)
117947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : str_(const_cast<std::string&>(str)), read_pos_(0), read_only_(true) {
118047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
118147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
118247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamState StringStream::GetState() const {
118347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SS_OPEN;
118447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
118547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
118647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StringStream::Read(void* buffer, size_t buffer_len,
118747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                      size_t* read, int* error) {
118847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t available = _min(buffer_len, str_.size() - read_pos_);
118947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!available)
119047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_EOS;
119147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(buffer, str_.data() + read_pos_, available);
119247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  read_pos_ += available;
119347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (read)
119447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *read = available;
119547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
119647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
119747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
119847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult StringStream::Write(const void* data, size_t data_len,
119947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                      size_t* written, int* error) {
120047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (read_only_) {
120147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (error) {
120247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *error = -1;
120347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
120447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return SR_ERROR;
120547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
120647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  str_.append(static_cast<const char*>(data),
120747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              static_cast<const char*>(data) + data_len);
120847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (written)
120947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *written = data_len;
121047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
121147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
121247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
121347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid StringStream::Close() {
121447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
121547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
121647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StringStream::SetPosition(size_t position) {
121747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (position > str_.size())
121847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
121947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  read_pos_ = position;
122047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
122147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
122247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
122347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StringStream::GetPosition(size_t* position) const {
122447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (position)
122547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *position = read_pos_;
122647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
122747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
122847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
122947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StringStream::GetSize(size_t* size) const {
123047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size)
123147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *size = str_.size();
123247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
123347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
123447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
123547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StringStream::GetAvailable(size_t* size) const {
123647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (size)
123747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *size = str_.size() - read_pos_;
123847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
123947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
124047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
124147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool StringStream::ReserveSize(size_t size) {
124247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (read_only_)
124347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
124447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  str_.reserve(size);
124547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
124647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
124747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
124847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
124947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// StreamReference
125047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
125147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
125247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamReference::StreamReference(StreamInterface* stream)
125347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : StreamAdapterInterface(stream, false) {
125447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // owner set to false so the destructor does not free the stream.
125547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream_ref_count_ = new StreamRefCount(stream);
125647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
125747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
125847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamInterface* StreamReference::NewReference() {
125947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream_ref_count_->AddReference();
126047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return new StreamReference(stream_ref_count_, stream());
126147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
126247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
126347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamReference::~StreamReference() {
126447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stream_ref_count_->Release();
126547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
126647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
126747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamReference::StreamReference(StreamRefCount* stream_ref_count,
126847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 StreamInterface* stream)
126947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : StreamAdapterInterface(stream, false),
127047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      stream_ref_count_(stream_ref_count) {
127147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
127247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
127347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
127447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
127547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgStreamResult Flow(StreamInterface* source,
127647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                  char* buffer, size_t buffer_len,
127747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                  StreamInterface* sink,
127847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                  size_t* data_len /* = NULL */) {
127947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(buffer_len > 0);
128047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
128147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  StreamResult result;
128247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t count, read_pos, write_pos;
128347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_len) {
128447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_pos = *data_len;
128547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
128647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_pos = 0;
128747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
128847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
128947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool end_of_stream = false;
129047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  do {
129147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Read until buffer is full, end of stream, or error
129247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while (!end_of_stream && (read_pos < buffer_len)) {
129347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = source->Read(buffer + read_pos, buffer_len - read_pos,
129447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            &count, NULL);
129547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (result == SR_EOS) {
129647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        end_of_stream = true;
129747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else if (result != SR_SUCCESS) {
129847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (data_len) {
129947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          *data_len = read_pos;
130047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
130147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return result;
130247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
130347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        read_pos += count;
130447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
130547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
130647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
130747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Write until buffer is empty, or error (including end of stream)
130847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    write_pos = 0;
130947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while (write_pos < read_pos) {
131047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = sink->Write(buffer + write_pos, read_pos - write_pos,
131147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                           &count, NULL);
131247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (result != SR_SUCCESS) {
131347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (data_len) {
131447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          *data_len = read_pos - write_pos;
131547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          if (write_pos > 0) {
131647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            memmove(buffer, buffer + write_pos, *data_len);
131747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          }
131847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
131947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return result;
132047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
132147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      write_pos += count;
132247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
132347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
132447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    read_pos = 0;
132547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } while (!end_of_stream);
132647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
132747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (data_len) {
132847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *data_len = 0;
132947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
133047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return SR_SUCCESS;
133147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
133247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
133347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org///////////////////////////////////////////////////////////////////////////////
133447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
133547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
1336