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