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