/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "stream_buffer.h" namespace OHOS { namespace Sensors { StreamBuffer::StreamBuffer(const StreamBuffer &buf) { Clone(buf); } StreamBuffer &StreamBuffer::operator=(const StreamBuffer &other) { Clone(other); return *this; } void StreamBuffer::Reset() { #ifdef OHOS_BUILD_ENABLE_RUST StreamBufferReset(streamBufferPtr_.get()); #else rPos_ = 0; wPos_ = 0; rCount_ = 0; wCount_ = 0; rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK; #endif // OHOS_BUILD_ENABLE_RUST } void StreamBuffer::Clean() { #ifdef OHOS_BUILD_ENABLE_RUST StreamBufferClean(streamBufferPtr_.get()); #else Reset(); errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_)); if (ret != EOK) { SEN_HILOGE("Call memset_s fail"); return; } #endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Read(std::string &buf) { #ifdef OHOS_BUILD_ENABLE_RUST const int32_t ERROR_STATUS_READ = 1; if (StreamBufferGetRpos(streamBufferPtr_.get()) == StreamBufferGetWpos(streamBufferPtr_.get())) { SEN_HILOGE("Not enough memory to read, errCode:%{public}d", STREAM_BUF_READ_FAIL); StreamBufferSetRwErrStatus(streamBufferPtr_.get(), ERROR_STATUS_READ); return false; } buf = ReadBuf(); StreamBufferSetRpos(streamBufferPtr_.get(), StreamBufferGetRpos(streamBufferPtr_.get()) + static_cast(buf.length()) + 1); return (buf.length() > 0); #else if (rPos_ == wPos_) { SEN_HILOGE("Not enough memory to read"); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; return false; } buf = ReadBuf(); rPos_ += buf.length() + 1; return (buf.length() > 0); #endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Write(const std::string &buf) { return Write(buf.c_str(), buf.length()+1); } bool StreamBuffer::Read(StreamBuffer &buf) { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferRead(streamBufferPtr_.get(), buf.streamBufferPtr_.get()); #else return buf.Write(Data(), Size()); #endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Write(const StreamBuffer &buf) { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferWrite(streamBufferPtr_.get(), buf.streamBufferPtr_.get()); #else return Write(buf.Data(), buf.Size()); #endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Read(char *buf, size_t size) { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferReadChar(streamBufferPtr_.get(), buf, size); #else if (ChkRWError()) { return false; } if (buf == nullptr) { SEN_HILOGE("Invalid input parameter, buf is nullptr"); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; return false; } if (size == 0) { SEN_HILOGE("Invalid input parameter, size:%{public}zu", size); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; return false; } if (rPos_ + size > wPos_) { SEN_HILOGE("Memory out of bounds on read"); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; return false; } errno_t ret = memcpy_sp(buf, size, ReadBuf(), size); if (ret != EOK) { SEN_HILOGE("Failed to call memcpy_sp"); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ; return false; } rPos_ += size; ++rCount_; return true; #endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Write(const char *buf, size_t size) { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferWriteChar(streamBufferPtr_.get(), buf, size); #else if (ChkRWError()) { return false; } if (buf == nullptr) { SEN_HILOGE("Invalid input parameter, buf is nullptr"); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; return false; } if (size == 0) { SEN_HILOGE("Invalid input parameter, size:%{public}zu", size); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; return false; } if (wPos_ + size > MAX_STREAM_BUF_SIZE) { SEN_HILOGE("The write length exceeds buffer. wPos:%{public}zu, size:%{public}zu, maxBufSize:%{public}zu", wPos_, size, MAX_STREAM_BUF_SIZE); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; return false; } errno_t ret = memcpy_sp(&szBuff_[wPos_], GetAvailableBufSize(), buf, size); if (ret != EOK) { SEN_HILOGE("Failed to call memcpy_sp"); rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE; return false; } wPos_ += size; ++wCount_; return true; #endif // OHOS_BUILD_ENABLE_RUST } const char *StreamBuffer::ReadBuf() const { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferReadBuf(streamBufferPtr_.get()); #else return &szBuff_[rPos_]; #endif // OHOS_BUILD_ENABLE_RUST } bool StreamBuffer::Clone(const StreamBuffer &buf) { Clean(); #ifdef OHOS_BUILD_ENABLE_RUST return Write(StreamBufferData(buf.streamBufferPtr_.get()), StreamBufferSize(buf.streamBufferPtr_.get())); #else return Write(buf.Data(), buf.Size()); #endif // OHOS_BUILD_ENABLE_RUST } #ifndef OHOS_BUILD_ENABLE_RUST bool StreamBuffer::ChkRWError() const { return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK); } bool StreamBuffer::SeekReadPos(size_t n) { size_t pos = rPos_ + n; if (pos > wPos_) { SEN_HILOGE("The position in the calculation is not as expected. pos:%{public}zu, [0, %{public}zu]", pos, wPos_); return false; } rPos_ = pos; return true; } bool StreamBuffer::IsEmpty() const { return (rPos_ == wPos_); } size_t StreamBuffer::Size() const { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferSize(&rustStreamBuffer_); #else return wPos_; #endif // OHOS_BUILD_ENABLE_RUST } size_t StreamBuffer::UnreadSize() const { return ((wPos_ <= rPos_) ? 0 : (wPos_ - rPos_)); } size_t StreamBuffer::GetAvailableBufSize() const { return ((wPos_ >= MAX_STREAM_BUF_SIZE) ? 0 : (MAX_STREAM_BUF_SIZE - wPos_)); } const std::string &StreamBuffer::GetErrorStatusRemark() const { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferGetErrorStatusRemark(streamBufferPtr_.get()); #else static const std::vector> remark { {ErrorStatus::ERROR_STATUS_OK, "OK"}, {ErrorStatus::ERROR_STATUS_READ, "READ_ERROR"}, {ErrorStatus::ERROR_STATUS_WRITE, "WRITE_ERROR"}, }; static const std::string invalidStatus { "UNKNOWN" }; auto tIter = std::find_if(remark.cbegin(), remark.cend(), [this](const auto &item) { return (item.first == rwErrorStatus_); }); return (tIter != remark.cend() ? tIter->second : invalidStatus); #endif // OHOS_BUILD_ENABLE_RUST } const char *StreamBuffer::Data() const { #ifdef OHOS_BUILD_ENABLE_RUST return StreamBufferData(&rustStreamBuffer_); #else return &szBuff_[0]; #endif // OHOS_BUILD_ENABLE_RUST } const char *StreamBuffer::WriteBuf() const { return &szBuff_[wPos_]; } #endif // OHOS_BUILD_ENABLE_RUST } // namespace Sensors } // namespace OHOS