1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li
5*1a96fba6SXin Li #include <brillo/streams/memory_stream.h>
6*1a96fba6SXin Li
7*1a96fba6SXin Li #include <limits>
8*1a96fba6SXin Li
9*1a96fba6SXin Li #include <base/bind.h>
10*1a96fba6SXin Li #include <brillo/message_loops/message_loop.h>
11*1a96fba6SXin Li #include <brillo/streams/stream_errors.h>
12*1a96fba6SXin Li #include <brillo/streams/stream_utils.h>
13*1a96fba6SXin Li
14*1a96fba6SXin Li namespace brillo {
15*1a96fba6SXin Li
MemoryStream(std::unique_ptr<data_container::DataContainerInterface> container,size_t stream_position)16*1a96fba6SXin Li MemoryStream::MemoryStream(
17*1a96fba6SXin Li std::unique_ptr<data_container::DataContainerInterface> container,
18*1a96fba6SXin Li size_t stream_position)
19*1a96fba6SXin Li : container_{std::move(container)}, stream_position_{stream_position} {}
20*1a96fba6SXin Li
OpenRef(const void * buffer,size_t size,ErrorPtr * error)21*1a96fba6SXin Li StreamPtr MemoryStream::OpenRef(const void* buffer,
22*1a96fba6SXin Li size_t size,
23*1a96fba6SXin Li ErrorPtr* error) {
24*1a96fba6SXin Li std::unique_ptr<data_container::ReadOnlyBuffer> container{
25*1a96fba6SXin Li new data_container::ReadOnlyBuffer{buffer, size}};
26*1a96fba6SXin Li return CreateEx(std::move(container), 0, error);
27*1a96fba6SXin Li }
28*1a96fba6SXin Li
OpenCopyOf(const void * buffer,size_t size,ErrorPtr * error)29*1a96fba6SXin Li StreamPtr MemoryStream::OpenCopyOf(const void* buffer,
30*1a96fba6SXin Li size_t size,
31*1a96fba6SXin Li ErrorPtr* error) {
32*1a96fba6SXin Li std::unique_ptr<data_container::ReadOnlyVectorCopy<uint8_t>> container{
33*1a96fba6SXin Li new data_container::ReadOnlyVectorCopy<uint8_t>{
34*1a96fba6SXin Li reinterpret_cast<const uint8_t*>(buffer), size}};
35*1a96fba6SXin Li return CreateEx(std::move(container), 0, error);
36*1a96fba6SXin Li }
37*1a96fba6SXin Li
OpenRef(const std::string & buffer,ErrorPtr * error)38*1a96fba6SXin Li StreamPtr MemoryStream::OpenRef(const std::string& buffer, ErrorPtr* error) {
39*1a96fba6SXin Li std::unique_ptr<data_container::ReadOnlyStringRef> container{
40*1a96fba6SXin Li new data_container::ReadOnlyStringRef{buffer}};
41*1a96fba6SXin Li return CreateEx(std::move(container), 0, error);
42*1a96fba6SXin Li }
43*1a96fba6SXin Li
OpenCopyOf(std::string buffer,ErrorPtr * error)44*1a96fba6SXin Li StreamPtr MemoryStream::OpenCopyOf(std::string buffer, ErrorPtr* error) {
45*1a96fba6SXin Li std::unique_ptr<data_container::ReadOnlyStringCopy> container{
46*1a96fba6SXin Li new data_container::ReadOnlyStringCopy{std::move(buffer)}};
47*1a96fba6SXin Li return CreateEx(std::move(container), 0, error);
48*1a96fba6SXin Li }
49*1a96fba6SXin Li
OpenRef(const char * buffer,ErrorPtr * error)50*1a96fba6SXin Li StreamPtr MemoryStream::OpenRef(const char* buffer, ErrorPtr* error) {
51*1a96fba6SXin Li return OpenRef(buffer, std::strlen(buffer), error);
52*1a96fba6SXin Li }
53*1a96fba6SXin Li
OpenCopyOf(const char * buffer,ErrorPtr * error)54*1a96fba6SXin Li StreamPtr MemoryStream::OpenCopyOf(const char* buffer, ErrorPtr* error) {
55*1a96fba6SXin Li return OpenCopyOf(buffer, std::strlen(buffer), error);
56*1a96fba6SXin Li }
57*1a96fba6SXin Li
Create(size_t reserve_size,ErrorPtr * error)58*1a96fba6SXin Li StreamPtr MemoryStream::Create(size_t reserve_size, ErrorPtr* error) {
59*1a96fba6SXin Li std::unique_ptr<data_container::ByteBuffer> container{
60*1a96fba6SXin Li new data_container::ByteBuffer{reserve_size}};
61*1a96fba6SXin Li return CreateEx(std::move(container), 0, error);
62*1a96fba6SXin Li }
63*1a96fba6SXin Li
CreateRef(std::string * buffer,ErrorPtr * error)64*1a96fba6SXin Li StreamPtr MemoryStream::CreateRef(std::string* buffer, ErrorPtr* error) {
65*1a96fba6SXin Li std::unique_ptr<data_container::StringPtr> container{
66*1a96fba6SXin Li new data_container::StringPtr{buffer}};
67*1a96fba6SXin Li return CreateEx(std::move(container), 0, error);
68*1a96fba6SXin Li }
69*1a96fba6SXin Li
CreateRefForAppend(std::string * buffer,ErrorPtr * error)70*1a96fba6SXin Li StreamPtr MemoryStream::CreateRefForAppend(std::string* buffer,
71*1a96fba6SXin Li ErrorPtr* error) {
72*1a96fba6SXin Li std::unique_ptr<data_container::StringPtr> container{
73*1a96fba6SXin Li new data_container::StringPtr{buffer}};
74*1a96fba6SXin Li return CreateEx(std::move(container), buffer->size(), error);
75*1a96fba6SXin Li }
76*1a96fba6SXin Li
CreateEx(std::unique_ptr<data_container::DataContainerInterface> container,size_t stream_position,ErrorPtr * error)77*1a96fba6SXin Li StreamPtr MemoryStream::CreateEx(
78*1a96fba6SXin Li std::unique_ptr<data_container::DataContainerInterface> container,
79*1a96fba6SXin Li size_t stream_position,
80*1a96fba6SXin Li ErrorPtr* error) {
81*1a96fba6SXin Li ignore_result(error); // Unused.
82*1a96fba6SXin Li return StreamPtr{new MemoryStream(std::move(container), stream_position)};
83*1a96fba6SXin Li }
84*1a96fba6SXin Li
IsOpen() const85*1a96fba6SXin Li bool MemoryStream::IsOpen() const { return container_ != nullptr; }
CanRead() const86*1a96fba6SXin Li bool MemoryStream::CanRead() const { return IsOpen(); }
87*1a96fba6SXin Li
CanWrite() const88*1a96fba6SXin Li bool MemoryStream::CanWrite() const {
89*1a96fba6SXin Li return IsOpen() && !container_->IsReadOnly();
90*1a96fba6SXin Li }
91*1a96fba6SXin Li
CanSeek() const92*1a96fba6SXin Li bool MemoryStream::CanSeek() const { return IsOpen(); }
CanGetSize() const93*1a96fba6SXin Li bool MemoryStream::CanGetSize() const { return IsOpen(); }
94*1a96fba6SXin Li
GetSize() const95*1a96fba6SXin Li uint64_t MemoryStream::GetSize() const {
96*1a96fba6SXin Li return IsOpen() ? container_->GetSize() : 0;
97*1a96fba6SXin Li }
98*1a96fba6SXin Li
SetSizeBlocking(uint64_t size,ErrorPtr * error)99*1a96fba6SXin Li bool MemoryStream::SetSizeBlocking(uint64_t size, ErrorPtr* error) {
100*1a96fba6SXin Li if (!CheckContainer(error))
101*1a96fba6SXin Li return false;
102*1a96fba6SXin Li return container_->Resize(size, error);
103*1a96fba6SXin Li }
104*1a96fba6SXin Li
GetRemainingSize() const105*1a96fba6SXin Li uint64_t MemoryStream::GetRemainingSize() const {
106*1a96fba6SXin Li uint64_t pos = GetPosition();
107*1a96fba6SXin Li uint64_t size = GetSize();
108*1a96fba6SXin Li return (pos < size) ? size - pos : 0;
109*1a96fba6SXin Li }
110*1a96fba6SXin Li
GetPosition() const111*1a96fba6SXin Li uint64_t MemoryStream::GetPosition() const {
112*1a96fba6SXin Li return IsOpen() ? stream_position_ : 0;
113*1a96fba6SXin Li }
114*1a96fba6SXin Li
Seek(int64_t offset,Whence whence,uint64_t * new_position,ErrorPtr * error)115*1a96fba6SXin Li bool MemoryStream::Seek(int64_t offset,
116*1a96fba6SXin Li Whence whence,
117*1a96fba6SXin Li uint64_t* new_position,
118*1a96fba6SXin Li ErrorPtr* error) {
119*1a96fba6SXin Li uint64_t pos = 0;
120*1a96fba6SXin Li if (!CheckContainer(error) ||
121*1a96fba6SXin Li !stream_utils::CalculateStreamPosition(FROM_HERE, offset, whence,
122*1a96fba6SXin Li stream_position_, GetSize(), &pos,
123*1a96fba6SXin Li error)) {
124*1a96fba6SXin Li return false;
125*1a96fba6SXin Li }
126*1a96fba6SXin Li if (pos > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) {
127*1a96fba6SXin Li // This can only be the case on 32 bit systems.
128*1a96fba6SXin Li brillo::Error::AddTo(error, FROM_HERE, errors::stream::kDomain,
129*1a96fba6SXin Li errors::stream::kInvalidParameter,
130*1a96fba6SXin Li "Stream pointer position is outside allowed limits");
131*1a96fba6SXin Li return false;
132*1a96fba6SXin Li }
133*1a96fba6SXin Li
134*1a96fba6SXin Li stream_position_ = static_cast<size_t>(pos);
135*1a96fba6SXin Li if (new_position)
136*1a96fba6SXin Li *new_position = stream_position_;
137*1a96fba6SXin Li return true;
138*1a96fba6SXin Li }
139*1a96fba6SXin Li
ReadNonBlocking(void * buffer,size_t size_to_read,size_t * size_read,bool * end_of_stream,ErrorPtr * error)140*1a96fba6SXin Li bool MemoryStream::ReadNonBlocking(void* buffer,
141*1a96fba6SXin Li size_t size_to_read,
142*1a96fba6SXin Li size_t* size_read,
143*1a96fba6SXin Li bool* end_of_stream,
144*1a96fba6SXin Li ErrorPtr* error) {
145*1a96fba6SXin Li if (!CheckContainer(error))
146*1a96fba6SXin Li return false;
147*1a96fba6SXin Li size_t read = 0;
148*1a96fba6SXin Li if (!container_->Read(buffer, size_to_read, stream_position_, &read, error))
149*1a96fba6SXin Li return false;
150*1a96fba6SXin Li stream_position_ += read;
151*1a96fba6SXin Li *size_read = read;
152*1a96fba6SXin Li if (end_of_stream)
153*1a96fba6SXin Li *end_of_stream = (read == 0) && (size_to_read != 0);
154*1a96fba6SXin Li return true;
155*1a96fba6SXin Li }
156*1a96fba6SXin Li
WriteNonBlocking(const void * buffer,size_t size_to_write,size_t * size_written,ErrorPtr * error)157*1a96fba6SXin Li bool MemoryStream::WriteNonBlocking(const void* buffer,
158*1a96fba6SXin Li size_t size_to_write,
159*1a96fba6SXin Li size_t* size_written,
160*1a96fba6SXin Li ErrorPtr* error) {
161*1a96fba6SXin Li if (!CheckContainer(error))
162*1a96fba6SXin Li return false;
163*1a96fba6SXin Li if (!container_->Write(buffer, size_to_write, stream_position_, size_written,
164*1a96fba6SXin Li error)) {
165*1a96fba6SXin Li return false;
166*1a96fba6SXin Li }
167*1a96fba6SXin Li stream_position_ += *size_written;
168*1a96fba6SXin Li return true;
169*1a96fba6SXin Li }
170*1a96fba6SXin Li
FlushBlocking(ErrorPtr * error)171*1a96fba6SXin Li bool MemoryStream::FlushBlocking(ErrorPtr* error) {
172*1a96fba6SXin Li return CheckContainer(error);
173*1a96fba6SXin Li }
174*1a96fba6SXin Li
CloseBlocking(ErrorPtr * error)175*1a96fba6SXin Li bool MemoryStream::CloseBlocking(ErrorPtr* error) {
176*1a96fba6SXin Li ignore_result(error); // Unused.
177*1a96fba6SXin Li container_.reset();
178*1a96fba6SXin Li return true;
179*1a96fba6SXin Li }
180*1a96fba6SXin Li
CheckContainer(ErrorPtr * error) const181*1a96fba6SXin Li bool MemoryStream::CheckContainer(ErrorPtr* error) const {
182*1a96fba6SXin Li return container_ || stream_utils::ErrorStreamClosed(FROM_HERE, error);
183*1a96fba6SXin Li }
184*1a96fba6SXin Li
WaitForData(AccessMode mode,const base::Callback<void (AccessMode)> & callback,ErrorPtr *)185*1a96fba6SXin Li bool MemoryStream::WaitForData(AccessMode mode,
186*1a96fba6SXin Li const base::Callback<void(AccessMode)>& callback,
187*1a96fba6SXin Li ErrorPtr* /* error */) {
188*1a96fba6SXin Li MessageLoop::current()->PostTask(FROM_HERE, base::BindOnce(callback, mode));
189*1a96fba6SXin Li return true;
190*1a96fba6SXin Li }
191*1a96fba6SXin Li
WaitForDataBlocking(AccessMode in_mode,base::TimeDelta,AccessMode * out_mode,ErrorPtr *)192*1a96fba6SXin Li bool MemoryStream::WaitForDataBlocking(AccessMode in_mode,
193*1a96fba6SXin Li base::TimeDelta /* timeout */,
194*1a96fba6SXin Li AccessMode* out_mode,
195*1a96fba6SXin Li ErrorPtr* /* error */) {
196*1a96fba6SXin Li if (out_mode)
197*1a96fba6SXin Li *out_mode = in_mode;
198*1a96fba6SXin Li return true;
199*1a96fba6SXin Li }
200*1a96fba6SXin Li
201*1a96fba6SXin Li } // namespace brillo
202