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