1bae4d13cSopenharmony_ci/*
2bae4d13cSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3bae4d13cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bae4d13cSopenharmony_ci * you may not use this file except in compliance with the License.
5bae4d13cSopenharmony_ci * You may obtain a copy of the License at
6bae4d13cSopenharmony_ci *
7bae4d13cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bae4d13cSopenharmony_ci *
9bae4d13cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bae4d13cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bae4d13cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bae4d13cSopenharmony_ci * See the License for the specific language governing permissions and
13bae4d13cSopenharmony_ci * limitations under the License.
14bae4d13cSopenharmony_ci */
15bae4d13cSopenharmony_ci
16bae4d13cSopenharmony_ci#include "stream_buffer.h"
17bae4d13cSopenharmony_ci
18bae4d13cSopenharmony_cinamespace OHOS {
19bae4d13cSopenharmony_cinamespace Sensors {
20bae4d13cSopenharmony_ciStreamBuffer::StreamBuffer(const StreamBuffer &buf)
21bae4d13cSopenharmony_ci{
22bae4d13cSopenharmony_ci    Clone(buf);
23bae4d13cSopenharmony_ci}
24bae4d13cSopenharmony_ci
25bae4d13cSopenharmony_ciStreamBuffer &StreamBuffer::operator=(const StreamBuffer &other)
26bae4d13cSopenharmony_ci{
27bae4d13cSopenharmony_ci    Clone(other);
28bae4d13cSopenharmony_ci    return *this;
29bae4d13cSopenharmony_ci}
30bae4d13cSopenharmony_ci
31bae4d13cSopenharmony_civoid StreamBuffer::Reset()
32bae4d13cSopenharmony_ci{
33bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
34bae4d13cSopenharmony_ci    StreamBufferReset(streamBufferPtr_.get());
35bae4d13cSopenharmony_ci#else
36bae4d13cSopenharmony_ci    rPos_ = 0;
37bae4d13cSopenharmony_ci    wPos_ = 0;
38bae4d13cSopenharmony_ci    rCount_ = 0;
39bae4d13cSopenharmony_ci    wCount_ = 0;
40bae4d13cSopenharmony_ci    rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK;
41bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
42bae4d13cSopenharmony_ci}
43bae4d13cSopenharmony_ci
44bae4d13cSopenharmony_civoid StreamBuffer::Clean()
45bae4d13cSopenharmony_ci{
46bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
47bae4d13cSopenharmony_ci    StreamBufferClean(streamBufferPtr_.get());
48bae4d13cSopenharmony_ci#else
49bae4d13cSopenharmony_ci    Reset();
50bae4d13cSopenharmony_ci    errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_));
51bae4d13cSopenharmony_ci    if (ret != EOK) {
52bae4d13cSopenharmony_ci        SEN_HILOGE("Call memset_s fail");
53bae4d13cSopenharmony_ci        return;
54bae4d13cSopenharmony_ci    }
55bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
56bae4d13cSopenharmony_ci}
57bae4d13cSopenharmony_ci
58bae4d13cSopenharmony_cibool StreamBuffer::Read(std::string &buf)
59bae4d13cSopenharmony_ci{
60bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
61bae4d13cSopenharmony_ci    const int32_t ERROR_STATUS_READ = 1;
62bae4d13cSopenharmony_ci    if (StreamBufferGetRpos(streamBufferPtr_.get()) == StreamBufferGetWpos(streamBufferPtr_.get())) {
63bae4d13cSopenharmony_ci        SEN_HILOGE("Not enough memory to read, errCode:%{public}d", STREAM_BUF_READ_FAIL);
64bae4d13cSopenharmony_ci        StreamBufferSetRwErrStatus(streamBufferPtr_.get(), ERROR_STATUS_READ);
65bae4d13cSopenharmony_ci        return false;
66bae4d13cSopenharmony_ci    }
67bae4d13cSopenharmony_ci    buf = ReadBuf();
68bae4d13cSopenharmony_ci    StreamBufferSetRpos(streamBufferPtr_.get(),
69bae4d13cSopenharmony_ci        StreamBufferGetRpos(streamBufferPtr_.get()) + static_cast<int32_t>(buf.length()) + 1);
70bae4d13cSopenharmony_ci    return (buf.length() > 0);
71bae4d13cSopenharmony_ci#else
72bae4d13cSopenharmony_ci    if (rPos_ == wPos_) {
73bae4d13cSopenharmony_ci        SEN_HILOGE("Not enough memory to read");
74bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
75bae4d13cSopenharmony_ci        return false;
76bae4d13cSopenharmony_ci    }
77bae4d13cSopenharmony_ci    buf = ReadBuf();
78bae4d13cSopenharmony_ci    rPos_ += buf.length() + 1;
79bae4d13cSopenharmony_ci    return (buf.length() > 0);
80bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
81bae4d13cSopenharmony_ci}
82bae4d13cSopenharmony_ci
83bae4d13cSopenharmony_cibool StreamBuffer::Write(const std::string &buf)
84bae4d13cSopenharmony_ci{
85bae4d13cSopenharmony_ci    return Write(buf.c_str(), buf.length()+1);
86bae4d13cSopenharmony_ci}
87bae4d13cSopenharmony_ci
88bae4d13cSopenharmony_cibool StreamBuffer::Read(StreamBuffer &buf)
89bae4d13cSopenharmony_ci{
90bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
91bae4d13cSopenharmony_ci    return StreamBufferRead(streamBufferPtr_.get(), buf.streamBufferPtr_.get());
92bae4d13cSopenharmony_ci#else
93bae4d13cSopenharmony_ci    return buf.Write(Data(), Size());
94bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
95bae4d13cSopenharmony_ci}
96bae4d13cSopenharmony_ci
97bae4d13cSopenharmony_cibool StreamBuffer::Write(const StreamBuffer &buf)
98bae4d13cSopenharmony_ci{
99bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
100bae4d13cSopenharmony_ci    return StreamBufferWrite(streamBufferPtr_.get(), buf.streamBufferPtr_.get());
101bae4d13cSopenharmony_ci#else
102bae4d13cSopenharmony_ci    return Write(buf.Data(), buf.Size());
103bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
104bae4d13cSopenharmony_ci}
105bae4d13cSopenharmony_ci
106bae4d13cSopenharmony_cibool StreamBuffer::Read(char *buf, size_t size)
107bae4d13cSopenharmony_ci{
108bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
109bae4d13cSopenharmony_ci    return StreamBufferReadChar(streamBufferPtr_.get(), buf, size);
110bae4d13cSopenharmony_ci#else
111bae4d13cSopenharmony_ci    if (ChkRWError()) {
112bae4d13cSopenharmony_ci        return false;
113bae4d13cSopenharmony_ci    }
114bae4d13cSopenharmony_ci    if (buf == nullptr) {
115bae4d13cSopenharmony_ci        SEN_HILOGE("Invalid input parameter, buf is nullptr");
116bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
117bae4d13cSopenharmony_ci        return false;
118bae4d13cSopenharmony_ci    }
119bae4d13cSopenharmony_ci    if (size == 0) {
120bae4d13cSopenharmony_ci        SEN_HILOGE("Invalid input parameter, size:%{public}zu", size);
121bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
122bae4d13cSopenharmony_ci        return false;
123bae4d13cSopenharmony_ci    }
124bae4d13cSopenharmony_ci    if (rPos_ + size > wPos_) {
125bae4d13cSopenharmony_ci        SEN_HILOGE("Memory out of bounds on read");
126bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
127bae4d13cSopenharmony_ci        return false;
128bae4d13cSopenharmony_ci    }
129bae4d13cSopenharmony_ci    errno_t ret = memcpy_sp(buf, size, ReadBuf(), size);
130bae4d13cSopenharmony_ci    if (ret != EOK) {
131bae4d13cSopenharmony_ci        SEN_HILOGE("Failed to call memcpy_sp");
132bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
133bae4d13cSopenharmony_ci        return false;
134bae4d13cSopenharmony_ci    }
135bae4d13cSopenharmony_ci    rPos_ += size;
136bae4d13cSopenharmony_ci    ++rCount_;
137bae4d13cSopenharmony_ci    return true;
138bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
139bae4d13cSopenharmony_ci}
140bae4d13cSopenharmony_ci
141bae4d13cSopenharmony_cibool StreamBuffer::Write(const char *buf, size_t size)
142bae4d13cSopenharmony_ci{
143bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
144bae4d13cSopenharmony_ci    return StreamBufferWriteChar(streamBufferPtr_.get(), buf, size);
145bae4d13cSopenharmony_ci#else
146bae4d13cSopenharmony_ci    if (ChkRWError()) {
147bae4d13cSopenharmony_ci        return false;
148bae4d13cSopenharmony_ci    }
149bae4d13cSopenharmony_ci    if (buf == nullptr) {
150bae4d13cSopenharmony_ci        SEN_HILOGE("Invalid input parameter, buf is nullptr");
151bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
152bae4d13cSopenharmony_ci        return false;
153bae4d13cSopenharmony_ci    }
154bae4d13cSopenharmony_ci    if (size == 0) {
155bae4d13cSopenharmony_ci        SEN_HILOGE("Invalid input parameter, size:%{public}zu", size);
156bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
157bae4d13cSopenharmony_ci        return false;
158bae4d13cSopenharmony_ci    }
159bae4d13cSopenharmony_ci    if (wPos_ + size > MAX_STREAM_BUF_SIZE) {
160bae4d13cSopenharmony_ci        SEN_HILOGE("The write length exceeds buffer. wPos:%{public}zu, size:%{public}zu, maxBufSize:%{public}zu",
161bae4d13cSopenharmony_ci                   wPos_, size, MAX_STREAM_BUF_SIZE);
162bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
163bae4d13cSopenharmony_ci        return false;
164bae4d13cSopenharmony_ci    }
165bae4d13cSopenharmony_ci    errno_t ret = memcpy_sp(&szBuff_[wPos_], GetAvailableBufSize(), buf, size);
166bae4d13cSopenharmony_ci    if (ret != EOK) {
167bae4d13cSopenharmony_ci        SEN_HILOGE("Failed to call memcpy_sp");
168bae4d13cSopenharmony_ci        rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
169bae4d13cSopenharmony_ci        return false;
170bae4d13cSopenharmony_ci    }
171bae4d13cSopenharmony_ci    wPos_ += size;
172bae4d13cSopenharmony_ci    ++wCount_;
173bae4d13cSopenharmony_ci    return true;
174bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
175bae4d13cSopenharmony_ci}
176bae4d13cSopenharmony_ci
177bae4d13cSopenharmony_ciconst char *StreamBuffer::ReadBuf() const
178bae4d13cSopenharmony_ci{
179bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
180bae4d13cSopenharmony_ci    return StreamBufferReadBuf(streamBufferPtr_.get());
181bae4d13cSopenharmony_ci#else
182bae4d13cSopenharmony_ci    return &szBuff_[rPos_];
183bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
184bae4d13cSopenharmony_ci}
185bae4d13cSopenharmony_ci
186bae4d13cSopenharmony_cibool StreamBuffer::Clone(const StreamBuffer &buf)
187bae4d13cSopenharmony_ci{
188bae4d13cSopenharmony_ci    Clean();
189bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
190bae4d13cSopenharmony_ci    return Write(StreamBufferData(buf.streamBufferPtr_.get()), StreamBufferSize(buf.streamBufferPtr_.get()));
191bae4d13cSopenharmony_ci#else
192bae4d13cSopenharmony_ci    return Write(buf.Data(), buf.Size());
193bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
194bae4d13cSopenharmony_ci}
195bae4d13cSopenharmony_ci#ifndef OHOS_BUILD_ENABLE_RUST
196bae4d13cSopenharmony_ci
197bae4d13cSopenharmony_cibool StreamBuffer::ChkRWError() const
198bae4d13cSopenharmony_ci{
199bae4d13cSopenharmony_ci    return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK);
200bae4d13cSopenharmony_ci}
201bae4d13cSopenharmony_ci
202bae4d13cSopenharmony_cibool StreamBuffer::SeekReadPos(size_t n)
203bae4d13cSopenharmony_ci{
204bae4d13cSopenharmony_ci    size_t pos = rPos_ + n;
205bae4d13cSopenharmony_ci    if (pos > wPos_) {
206bae4d13cSopenharmony_ci        SEN_HILOGE("The position in the calculation is not as expected. pos:%{public}zu, [0, %{public}zu]", pos, wPos_);
207bae4d13cSopenharmony_ci        return false;
208bae4d13cSopenharmony_ci    }
209bae4d13cSopenharmony_ci    rPos_ = pos;
210bae4d13cSopenharmony_ci    return true;
211bae4d13cSopenharmony_ci}
212bae4d13cSopenharmony_ci
213bae4d13cSopenharmony_cibool StreamBuffer::IsEmpty() const
214bae4d13cSopenharmony_ci{
215bae4d13cSopenharmony_ci    return (rPos_ == wPos_);
216bae4d13cSopenharmony_ci}
217bae4d13cSopenharmony_ci
218bae4d13cSopenharmony_cisize_t StreamBuffer::Size() const
219bae4d13cSopenharmony_ci{
220bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
221bae4d13cSopenharmony_ci    return StreamBufferSize(&rustStreamBuffer_);
222bae4d13cSopenharmony_ci#else
223bae4d13cSopenharmony_ci    return wPos_;
224bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
225bae4d13cSopenharmony_ci}
226bae4d13cSopenharmony_ci
227bae4d13cSopenharmony_cisize_t StreamBuffer::UnreadSize() const
228bae4d13cSopenharmony_ci{
229bae4d13cSopenharmony_ci    return ((wPos_ <= rPos_) ? 0 : (wPos_ - rPos_));
230bae4d13cSopenharmony_ci}
231bae4d13cSopenharmony_ci
232bae4d13cSopenharmony_cisize_t StreamBuffer::GetAvailableBufSize() const
233bae4d13cSopenharmony_ci{
234bae4d13cSopenharmony_ci    return ((wPos_ >= MAX_STREAM_BUF_SIZE) ? 0 : (MAX_STREAM_BUF_SIZE - wPos_));
235bae4d13cSopenharmony_ci}
236bae4d13cSopenharmony_ci
237bae4d13cSopenharmony_ciconst std::string &StreamBuffer::GetErrorStatusRemark() const
238bae4d13cSopenharmony_ci{
239bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
240bae4d13cSopenharmony_ci    return StreamBufferGetErrorStatusRemark(streamBufferPtr_.get());
241bae4d13cSopenharmony_ci#else
242bae4d13cSopenharmony_ci    static const std::vector<std::pair<ErrorStatus, std::string>> remark {
243bae4d13cSopenharmony_ci        {ErrorStatus::ERROR_STATUS_OK, "OK"},
244bae4d13cSopenharmony_ci        {ErrorStatus::ERROR_STATUS_READ, "READ_ERROR"},
245bae4d13cSopenharmony_ci        {ErrorStatus::ERROR_STATUS_WRITE, "WRITE_ERROR"},
246bae4d13cSopenharmony_ci    };
247bae4d13cSopenharmony_ci    static const std::string invalidStatus { "UNKNOWN" };
248bae4d13cSopenharmony_ci    auto tIter = std::find_if(remark.cbegin(), remark.cend(), [this](const auto &item) {
249bae4d13cSopenharmony_ci        return (item.first == rwErrorStatus_);
250bae4d13cSopenharmony_ci    });
251bae4d13cSopenharmony_ci    return (tIter != remark.cend() ? tIter->second : invalidStatus);
252bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
253bae4d13cSopenharmony_ci}
254bae4d13cSopenharmony_ci
255bae4d13cSopenharmony_ciconst char *StreamBuffer::Data() const
256bae4d13cSopenharmony_ci{
257bae4d13cSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_RUST
258bae4d13cSopenharmony_ci    return StreamBufferData(&rustStreamBuffer_);
259bae4d13cSopenharmony_ci#else
260bae4d13cSopenharmony_ci    return &szBuff_[0];
261bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
262bae4d13cSopenharmony_ci}
263bae4d13cSopenharmony_ci
264bae4d13cSopenharmony_ciconst char *StreamBuffer::WriteBuf() const
265bae4d13cSopenharmony_ci{
266bae4d13cSopenharmony_ci    return &szBuff_[wPos_];
267bae4d13cSopenharmony_ci}
268bae4d13cSopenharmony_ci#endif // OHOS_BUILD_ENABLE_RUST
269bae4d13cSopenharmony_ci} // namespace Sensors
270bae4d13cSopenharmony_ci} // namespace OHOS
271