1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "stream_buffer.h"
17
18 namespace OHOS {
19 namespace MMI {
StreamBuffer(const StreamBuffer & buf)20 StreamBuffer::StreamBuffer(const StreamBuffer &buf)
21 {
22 Clone(buf);
23 }
24
operator =(const StreamBuffer & other)25 StreamBuffer &StreamBuffer::operator=(const StreamBuffer &other)
26 {
27 Clone(other);
28 return *this;
29 }
30
Reset()31 void StreamBuffer::Reset()
32 {
33 rPos_ = 0;
34 wPos_ = 0;
35 rCount_ = 0;
36 wCount_ = 0;
37 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK;
38 }
39
Clean()40 void StreamBuffer::Clean()
41 {
42 Reset();
43 errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_));
44 if (ret != EOK) {
45 MMI_HILOGE("Call memset_s fail");
46 return;
47 }
48 }
49
SeekReadPos(int32_t n)50 bool StreamBuffer::SeekReadPos(int32_t n)
51 {
52 int32_t pos = rPos_ + n;
53 if (pos < 0 || pos > wPos_) {
54 MMI_HILOGE("The position in the calculation is not as expected. pos:%{public}d [0, %{public}d]",
55 pos, wPos_);
56 return false;
57 }
58 rPos_ = pos;
59 return true;
60 }
61
Read(std::string & buf)62 bool StreamBuffer::Read(std::string &buf)
63 {
64 if (rPos_ == wPos_) {
65 MMI_HILOGE("Not enough memory to read, errCode:%{public}d", MEM_NOT_ENOUGH);
66 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
67 return false;
68 }
69 buf = ReadBuf();
70 rPos_ += static_cast<int32_t>(buf.length()) + 1;
71 return (buf.length() > 0);
72 }
73
Write(const std::string & buf)74 bool StreamBuffer::Write(const std::string &buf)
75 {
76 return Write(buf.c_str(), buf.length()+1);
77 }
78
Read(StreamBuffer & buf)79 bool StreamBuffer::Read(StreamBuffer &buf)
80 {
81 return buf.Write(Data(), Size());
82 }
83
Write(const StreamBuffer & buf)84 bool StreamBuffer::Write(const StreamBuffer &buf)
85 {
86 return Write(buf.Data(), buf.Size());
87 }
88
Read(char * buf,size_t size)89 bool StreamBuffer::Read(char *buf, size_t size)
90 {
91 if (ChkRWError()) {
92 return false;
93 }
94 if (buf == nullptr) {
95 MMI_HILOGE("Invalid input parameter buf=nullptr errCode:%{public}d", ERROR_NULL_POINTER);
96 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
97 return false;
98 }
99 if (size == 0) {
100 MMI_HILOGE("Invalid input parameter size=%{public}zu errCode:%{public}d", size, PARAM_INPUT_INVALID);
101 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
102 return false;
103 }
104 if (rPos_ + static_cast<int32_t>(size) > wPos_) {
105 MMI_HILOGE("Memory out of bounds on read... errCode:%{public}d", MEM_OUT_OF_BOUNDS);
106 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
107 return false;
108 }
109 errno_t ret = memcpy_sp(buf, size, ReadBuf(), size);
110 if (ret != EOK) {
111 MMI_HILOGE("Failed to call memcpy_sp. errCode:%{public}d", MEMCPY_SEC_FUN_FAIL);
112 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
113 return false;
114 }
115 rPos_ += static_cast<int32_t>(size);
116 rCount_ += 1;
117 return true;
118 }
119
Write(const char * buf,size_t size)120 bool StreamBuffer::Write(const char *buf, size_t size)
121 {
122 if (ChkRWError()) {
123 return false;
124 }
125 if (buf == nullptr) {
126 MMI_HILOGE("Invalid input parameter buf=nullptr errCode:%{public}d", ERROR_NULL_POINTER);
127 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
128 return false;
129 }
130 if (size == 0) {
131 MMI_HILOGE("Invalid input parameter size=%{public}zu errCode:%{public}d", size, PARAM_INPUT_INVALID);
132 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
133 return false;
134 }
135 if (wPos_ + static_cast<int32_t>(size) > MAX_STREAM_BUF_SIZE) {
136 MMI_HILOGE("The write length exceeds buffer. wIdx:%{public}d size:%{public}zu maxBufSize:%{public}d "
137 "errCode:%{public}d", wPos_, size, MAX_STREAM_BUF_SIZE, MEM_OUT_OF_BOUNDS);
138 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
139 return false;
140 }
141 errno_t ret = memcpy_sp(&szBuff_[wPos_], GetAvailableBufSize(), buf, size);
142 if (ret != EOK) {
143 MMI_HILOGE("Failed to call memcpy_sp. errCode:%{public}d", MEMCPY_SEC_FUN_FAIL);
144 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
145 return false;
146 }
147 wPos_ += static_cast<int32_t>(size);
148 wCount_ += 1;
149 return true;
150 }
151
IsEmpty() const152 bool StreamBuffer::IsEmpty() const
153 {
154 return (rPos_ == wPos_);
155 }
156
Size() const157 size_t StreamBuffer::Size() const
158 {
159 return static_cast<size_t>(wPos_);
160 }
161
UnreadSize() const162 int32_t StreamBuffer::UnreadSize() const
163 {
164 return ((wPos_ <= rPos_) ? 0 : (wPos_ - rPos_));
165 }
166
GetAvailableBufSize() const167 int32_t StreamBuffer::GetAvailableBufSize() const
168 {
169 return ((wPos_ >= MAX_STREAM_BUF_SIZE) ? 0 : (MAX_STREAM_BUF_SIZE - wPos_));
170 }
171
ChkRWError() const172 bool StreamBuffer::ChkRWError() const
173 {
174 return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK);
175 }
176
GetErrorStatusRemark() const177 const std::string &StreamBuffer::GetErrorStatusRemark() const
178 {
179 static const std::vector<std::pair<ErrorStatus, std::string>> remark {
180 { ErrorStatus::ERROR_STATUS_OK, "OK" },
181 { ErrorStatus::ERROR_STATUS_READ, "READ_ERROR" },
182 { ErrorStatus::ERROR_STATUS_WRITE, "WRITE_ERROR" },
183 };
184 for (const auto &it : remark) {
185 if (it.first == rwErrorStatus_) {
186 return it.second;
187 }
188 }
189 static const std::string invalidStatus = "UNKNOWN";
190 return invalidStatus;
191 }
192
Data() const193 const char *StreamBuffer::Data() const
194 {
195 return &szBuff_[0];
196 }
197
ReadBuf() const198 const char *StreamBuffer::ReadBuf() const
199 {
200 return &szBuff_[rPos_];
201 }
202
WriteBuf() const203 const char *StreamBuffer::WriteBuf() const
204 {
205 return &szBuff_[wPos_];
206 }
207
Clone(const StreamBuffer & buf)208 bool StreamBuffer::Clone(const StreamBuffer &buf)
209 {
210 Clean();
211 return Write(buf.Data(), buf.Size());
212 }
213 } // namespace MMI
214 } // namespace OHOS
215