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 #include "define_multimodal.h"
18
19 namespace OHOS {
20 namespace MMI {
StreamBuffer(const StreamBuffer & buf)21 StreamBuffer::StreamBuffer(const StreamBuffer &buf)
22 {
23 Clone(buf);
24 }
25
operator =(const StreamBuffer & other)26 StreamBuffer &StreamBuffer::operator=(const StreamBuffer &other)
27 {
28 Clone(other);
29 return *this;
30 }
31
Reset()32 void StreamBuffer::Reset()
33 {
34 rPos_ = 0;
35 wPos_ = 0;
36 rCount_ = 0;
37 wCount_ = 0;
38 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK;
39 }
40
Clean()41 void StreamBuffer::Clean()
42 {
43 Reset();
44 errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_));
45 if (ret != EOK) {
46 MMI_LOGE("call memset_s fail");
47 return;
48 }
49 }
50
SeekReadPos(int32_t n)51 bool StreamBuffer::SeekReadPos(int32_t n)
52 {
53 int32_t pos = rPos_ + n;
54 if (pos < 0 || pos > wPos_) {
55 MMI_LOGE("The position in the calculation is not as expected. pos:%{public}d [0, %{public}d]",
56 pos, wPos_);
57 return false;
58 }
59 rPos_ = pos;
60 return true;
61 }
62
Read(std::string & buf)63 bool StreamBuffer::Read(std::string &buf)
64 {
65 if (rPos_ == wPos_) {
66 MMI_LOGE("Not enough memory to read, errCode:%{public}d", MEM_NOT_ENOUGH);
67 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
68 return false;
69 }
70 buf = ReadBuf();
71 rPos_ += static_cast<int32_t>(buf.length()) + 1;
72 return (buf.length() > 0);
73 }
74
Write(const std::string & buf)75 bool StreamBuffer::Write(const std::string &buf)
76 {
77 return Write(buf.c_str(), buf.length()+1);
78 }
79
Read(StreamBuffer & buf)80 bool StreamBuffer::Read(StreamBuffer &buf)
81 {
82 return buf.Write(Data(), Size());
83 }
84
Write(const StreamBuffer & buf)85 bool StreamBuffer::Write(const StreamBuffer &buf)
86 {
87 return Write(buf.Data(), buf.Size());
88 }
89
Read(char * buf,size_t size)90 bool StreamBuffer::Read(char *buf, size_t size)
91 {
92 if (ChkRWError()) {
93 return false;
94 }
95 if (buf == nullptr) {
96 MMI_LOGE("Invalid input parameter buf=nullptr errCode:%{public}d", ERROR_NULL_POINTER);
97 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
98 return false;
99 }
100 if (size == 0) {
101 MMI_LOGE("Invalid input parameter size=%{public}zu errCode:%{public}d", size, PARAM_INPUT_INVALID);
102 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
103 return false;
104 }
105 if (rPos_ + static_cast<int32_t>(size) > wPos_) {
106 MMI_LOGE("Memory out of bounds on read... errCode:%{public}d", MEM_OUT_OF_BOUNDS);
107 rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
108 return false;
109 }
110 if (memcpy_sp(buf, size, ReadBuf(), size) != EOK) {
111 MMI_LOGE("memcpy_sp call fail. 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_LOGE("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_LOGE("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_LOGE("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_LOGE("memcpy_sp call fail. 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