1 /*
2 * Copyright (c) 2021-2023 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 #include <algorithm>
19
20 namespace OHOS {
21 namespace Msdp {
StreamBuffer(const StreamBuffer & buf)22 StreamBuffer::StreamBuffer(const StreamBuffer &buf)
23 {
24 Clone(buf);
25 }
26
operator =(const StreamBuffer & buffer)27 StreamBuffer &StreamBuffer::operator=(const StreamBuffer &buffer)
28 {
29 Clone(buffer);
30 return *this;
31 }
32
Reset()33 void StreamBuffer::Reset()
34 {
35 wPos_ = 0;
36 rPos_ = 0;
37 wCount_ = 0;
38 rCount_ = 0;
39 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK;
40 }
41
Clean()42 void StreamBuffer::Clean()
43 {
44 Reset();
45 errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_));
46 if (ret != EOK) {
47 FI_HILOGE("Call memset_s failed");
48 return;
49 }
50 }
51
SeekReadPos(int32_t n)52 bool StreamBuffer::SeekReadPos(int32_t n)
53 {
54 int32_t pos = rPos_ + n;
55 if (pos < 0 || pos > wPos_) {
56 FI_HILOGE("The position in the calculation is not as expected, pos:%{public}d, [0, %{public}d]",
57 pos, wPos_);
58 return false;
59 }
60 rPos_ = pos;
61 return true;
62 }
63
Write(const std::string & buf)64 bool StreamBuffer::Write(const std::string &buf)
65 {
66 return Write(buf.c_str(), buf.length() + 1);
67 }
68
Read(std::string & buf)69 bool StreamBuffer::Read(std::string &buf)
70 {
71 if (rPos_ == wPos_) {
72 FI_HILOGE("Not enough memory to read, errCode:%{public}d", STREAM_BUF_READ_FAIL);
73 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
74 return false;
75 }
76 buf = ReadBuf();
77 rPos_ = rPos_ + static_cast<int32_t>(buf.length()) + 1;
78 return (buf.length() > 0);
79 }
80
Write(const StreamBuffer & buf)81 bool StreamBuffer::Write(const StreamBuffer &buf)
82 {
83 return Write(buf.Data(), buf.Size());
84 }
85
Read(StreamBuffer & buf)86 bool StreamBuffer::Read(StreamBuffer &buf)
87 {
88 return buf.Write(Data(), Size());
89 }
90
Read(char * buf,size_t size)91 bool StreamBuffer::Read(char *buf, size_t size)
92 {
93 if (ChkRWError()) {
94 FI_HILOGE("Read and write status is error");
95 return false;
96 }
97 if (buf == nullptr) {
98 FI_HILOGE("Invalid input parameter buf:nullptr, errCode:%{public}d", PARAM_INPUT_INVALID);
99 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
100 return false;
101 }
102 if (size == 0) {
103 FI_HILOGE("Invalid input parameter size:%{public}zu, errCode:%{public}d", size, PARAM_INPUT_INVALID);
104 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
105 return false;
106 }
107 if (rPos_ + static_cast<int32_t>(size) > wPos_) {
108 FI_HILOGE("Memory out of bounds on read, errCode:%{public}d", MEM_OUT_OF_BOUNDS);
109 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
110 return false;
111 }
112 errno_t ret = memcpy_sp(buf, size, ReadBuf(), size);
113 if (ret != EOK) {
114 FI_HILOGE("Failed to call memcpy_sp, errCode:%{public}d", MEMCPY_SEC_FUN_FAIL);
115 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
116 return false;
117 }
118
119 rCount_ += 1;
120 rPos_ += static_cast<int32_t>(size);
121 return true;
122 }
123
Write(const char * buf,size_t size)124 bool StreamBuffer::Write(const char *buf, size_t size)
125 {
126 if (ChkRWError()) {
127 FI_HILOGE("Read and write status is error");
128 return false;
129 }
130 if (buf == nullptr) {
131 FI_HILOGE("Invalid input parameter, buf:nullptr, errCode:%{public}d", PARAM_INPUT_INVALID);
132 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
133 return false;
134 }
135 if (size == 0) {
136 FI_HILOGE("Invalid input parameter, size:%{public}zu, errCode:%{public}d", size, PARAM_INPUT_INVALID);
137 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
138 return false;
139 }
140 if (wPos_ + static_cast<int32_t>(size) > MAX_STREAM_BUF_SIZE) {
141 FI_HILOGE("The write length exceeds buffer, wIdx:%{public}d, size:%{public}zu, maxBufSize:%{public}d, "
142 "errCode:%{public}d", wPos_, size, MAX_STREAM_BUF_SIZE, MEM_OUT_OF_BOUNDS);
143 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
144 return false;
145 }
146 errno_t ret = memcpy_sp(&szBuff_[wPos_], GetAvailableBufSize(), buf, size);
147 if (ret != EOK) {
148 FI_HILOGE("Failed to call memcpy_sp, errCode:%{public}d", MEMCPY_SEC_FUN_FAIL);
149 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
150 return false;
151 }
152 wPos_ += static_cast<int32_t>(size);
153 wCount_ += 1;
154 return true;
155 }
156
empty() const157 bool StreamBuffer::empty() const
158 {
159 return (rPos_ == wPos_);
160 }
161
Size() const162 size_t StreamBuffer::Size() const
163 {
164 return static_cast<size_t>(wPos_);
165 }
166
ResidualSize() const167 int32_t StreamBuffer::ResidualSize() const
168 {
169 return ((wPos_ <= rPos_) ? 0 : (wPos_ - rPos_));
170 }
171
ChkRWError() const172 bool StreamBuffer::ChkRWError() const
173 {
174 return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK);
175 }
176
GetAvailableBufSize() const177 int32_t StreamBuffer::GetAvailableBufSize() const
178 {
179 return ((wPos_ >= MAX_STREAM_BUF_SIZE) ? 0 : (MAX_STREAM_BUF_SIZE - wPos_));
180 }
181
GetErrorStatusRemark() const182 const std::string &StreamBuffer::GetErrorStatusRemark() const
183 {
184 static const std::vector<std::pair<ErrorStatus, std::string>> remark {
185 { ErrorStatus::ERROR_STATUS_OK, "OK" },
186 { ErrorStatus::ERROR_STATUS_READ, "READ_ERROR" },
187 { ErrorStatus::ERROR_STATUS_WRITE, "WRITE_ERROR" }
188 };
189 static const std::string invalidStatus { "UNKNOWN" };
190
191 auto tIter = std::find_if(remark.cbegin(), remark.cend(),
192 [this](const auto &item) {
193 return (item.first == rwErrorStatus_);
194 });
195 return (tIter != remark.cend() ? tIter->second : invalidStatus);
196 }
197
Data() const198 const char *StreamBuffer::Data() const
199 {
200 return &szBuff_[0];
201 }
202
ReadBuf() const203 const char *StreamBuffer::ReadBuf() const
204 {
205 return &szBuff_[rPos_];
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 Msdp
214 } // namespace OHOS
215