blob: 94d31adf13d8a601359eedab25d4b5140e6c688c [file] [log] [blame]
Niels Möllere7547d52018-11-01 08:33:081/*
2 * Copyright 2018 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Jonas Olssona4d87372019-07-05 17:08:3311#include "rtc_base/memory_stream.h"
12
Yves Gerey3e707812018-11-28 15:47:4913#include <errno.h>
14#include <string.h>
Jonas Olssona4d87372019-07-05 17:08:3315
Niels Möllere7547d52018-11-01 08:33:0816#include <algorithm>
17
Yves Gerey3e707812018-11-28 15:47:4918#include "rtc_base/checks.h"
Niels Möllere7547d52018-11-01 08:33:0819
20namespace rtc {
21
22StreamState MemoryStream::GetState() const {
23 return SS_OPEN;
24}
25
26StreamResult MemoryStream::Read(void* buffer,
27 size_t bytes,
28 size_t* bytes_read,
29 int* error) {
30 if (seek_position_ >= data_length_) {
31 return SR_EOS;
32 }
33 size_t available = data_length_ - seek_position_;
34 if (bytes > available) {
35 // Read partial buffer
36 bytes = available;
37 }
38 memcpy(buffer, &buffer_[seek_position_], bytes);
39 seek_position_ += bytes;
40 if (bytes_read) {
41 *bytes_read = bytes;
42 }
43 return SR_SUCCESS;
44}
45
46StreamResult MemoryStream::Write(const void* buffer,
47 size_t bytes,
48 size_t* bytes_written,
49 int* error) {
50 size_t available = buffer_length_ - seek_position_;
51 if (0 == available) {
52 // Increase buffer size to the larger of:
53 // a) new position rounded up to next 256 bytes
54 // b) double the previous length
55 size_t new_buffer_length =
56 std::max(((seek_position_ + bytes) | 0xFF) + 1, buffer_length_ * 2);
57 StreamResult result = DoReserve(new_buffer_length, error);
58 if (SR_SUCCESS != result) {
59 return result;
60 }
61 RTC_DCHECK(buffer_length_ >= new_buffer_length);
62 available = buffer_length_ - seek_position_;
63 }
64
65 if (bytes > available) {
66 bytes = available;
67 }
68 memcpy(&buffer_[seek_position_], buffer, bytes);
69 seek_position_ += bytes;
70 if (data_length_ < seek_position_) {
71 data_length_ = seek_position_;
72 }
73 if (bytes_written) {
74 *bytes_written = bytes;
75 }
76 return SR_SUCCESS;
77}
78
79void MemoryStream::Close() {
80 // nothing to do
81}
82
83bool MemoryStream::SetPosition(size_t position) {
84 if (position > data_length_)
85 return false;
86 seek_position_ = position;
87 return true;
88}
89
90bool MemoryStream::GetPosition(size_t* position) const {
91 if (position)
92 *position = seek_position_;
93 return true;
94}
95
Niels Möller1a86b782019-01-14 11:48:5396void MemoryStream::Rewind() {
97 seek_position_ = 0;
98}
99
Niels Möllere7547d52018-11-01 08:33:08100bool MemoryStream::GetSize(size_t* size) const {
101 if (size)
102 *size = data_length_;
103 return true;
104}
105
106bool MemoryStream::ReserveSize(size_t size) {
107 return (SR_SUCCESS == DoReserve(size, nullptr));
108}
109
110///////////////////////////////////////////////////////////////////////////////
111
112MemoryStream::MemoryStream() {}
113
Niels Möllere7547d52018-11-01 08:33:08114MemoryStream::~MemoryStream() {
115 delete[] buffer_;
116}
117
118void MemoryStream::SetData(const void* data, size_t length) {
119 data_length_ = buffer_length_ = length;
120 delete[] buffer_;
121 buffer_ = new char[buffer_length_];
122 memcpy(buffer_, data, data_length_);
123 seek_position_ = 0;
124}
125
126StreamResult MemoryStream::DoReserve(size_t size, int* error) {
127 if (buffer_length_ >= size)
128 return SR_SUCCESS;
129
130 if (char* new_buffer = new char[size]) {
131 memcpy(new_buffer, buffer_, data_length_);
132 delete[] buffer_;
133 buffer_ = new_buffer;
134 buffer_length_ = size;
135 return SR_SUCCESS;
136 }
137
138 if (error) {
139 *error = ENOMEM;
140 }
141 return SR_ERROR;
142}
143
144} // namespace rtc