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