• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "devicestatus_stream_buffer.h"
17 
18 #include <algorithm>
19 
20 #include "devicestatus_define.h"
21 
22 namespace OHOS {
23 namespace Msdp {
StreamBuffer(const StreamBuffer & buf)24 StreamBuffer::StreamBuffer(const StreamBuffer &buf)
25 {
26     Clone(buf);
27 }
28 
operator =(const StreamBuffer & buffer)29 StreamBuffer &StreamBuffer::operator=(const StreamBuffer &buffer)
30 {
31     Clone(buffer);
32     return *this;
33 }
34 
Reset()35 void StreamBuffer::Reset()
36 {
37     wPos_ = 0;
38     rPos_ = 0;
39     wCount_ = 0;
40     rCount_ = 0;
41     rwErrorStatus_ = ErrorStatus::ERROR_STATUS_OK;
42 }
43 
Clean()44 void StreamBuffer::Clean()
45 {
46     Reset();
47     errno_t ret = memset_sp(&szBuff_, sizeof(szBuff_), 0, sizeof(szBuff_));
48     if (ret != EOK) {
49         FI_HILOGE("Call memset_s failed");
50         return;
51     }
52 }
53 
SeekReadPos(int32_t n)54 bool StreamBuffer::SeekReadPos(int32_t n)
55 {
56     int32_t pos = rPos_ + n;
57     if (pos < 0 || pos > wPos_) {
58         FI_HILOGE("The position in the calculation is not as expected, pos:%{public}d, [0, %{public}d]",
59             pos, wPos_);
60         return false;
61     }
62     rPos_ = pos;
63     return true;
64 }
65 
Write(const std::string & buf)66 bool StreamBuffer::Write(const std::string &buf)
67 {
68     return Write(buf.c_str(), buf.length() + 1);
69 }
70 
Read(std::string & buf)71 bool StreamBuffer::Read(std::string &buf)
72 {
73     if (rPos_ == wPos_) {
74         FI_HILOGE("Not enough memory to read, errCode:%{public}d", STREAM_BUF_READ_FAIL);
75         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
76         return false;
77     }
78     buf = ReadBuf();
79     rPos_ = rPos_ + static_cast<int32_t>(buf.length()) + 1;
80     return (buf.length() > 0);
81 }
82 
Write(const StreamBuffer & buf)83 bool StreamBuffer::Write(const StreamBuffer &buf)
84 {
85     return Write(buf.Data(), buf.Size());
86 }
87 
Read(StreamBuffer & buf)88 bool StreamBuffer::Read(StreamBuffer &buf)
89 {
90     return buf.Write(Data(), Size());
91 }
92 
Read(char * buf,size_t size)93 bool StreamBuffer::Read(char *buf, size_t size)
94 {
95     if (ChkRWError()) {
96         FI_HILOGE("Read and write status is error");
97         return false;
98     }
99     if (buf == nullptr) {
100         FI_HILOGE("Invalid input parameter buf:nullptr, errCode:%{public}d", PARAM_INPUT_INVALID);
101         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
102         return false;
103     }
104     if (size == 0) {
105         FI_HILOGE("Invalid input parameter size:%{public}zu, errCode:%{public}d", size, PARAM_INPUT_INVALID);
106         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
107         return false;
108     }
109     if (rPos_ + static_cast<int32_t>(size) > wPos_) {
110         FI_HILOGE("Memory out of bounds on read, errCode:%{public}d", MEM_OUT_OF_BOUNDS);
111         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
112         return false;
113     }
114     errno_t ret = memcpy_sp(buf, size, ReadBuf(), size);
115     if (ret != EOK) {
116         FI_HILOGE("Failed to call memcpy_sp, errCode:%{public}d", MEMCPY_SEC_FUN_FAIL);
117         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_READ;
118         return false;
119     }
120 
121     rCount_ += 1;
122     rPos_ += static_cast<int32_t>(size);
123     return true;
124 }
125 
Write(const char * buf,size_t size)126 bool StreamBuffer::Write(const char *buf, size_t size)
127 {
128     if (ChkRWError()) {
129         FI_HILOGE("Read and write status is error");
130         return false;
131     }
132     if (buf == nullptr) {
133         FI_HILOGE("Invalid input parameter, buf:nullptr, errCode:%{public}d", PARAM_INPUT_INVALID);
134         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
135         return false;
136     }
137     if (size == 0) {
138         FI_HILOGE("Invalid input parameter, size:%{public}zu, errCode:%{public}d", size, PARAM_INPUT_INVALID);
139         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
140         return false;
141     }
142     if (wPos_ + static_cast<int32_t>(size) > MAX_STREAM_BUF_SIZE) {
143         FI_HILOGE("The write length exceeds buffer, wIdx:%{public}d, size:%{public}zu, maxBufSize:%{public}d, "
144             "errCode:%{public}d", wPos_, size, MAX_STREAM_BUF_SIZE, MEM_OUT_OF_BOUNDS);
145         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
146         return false;
147     }
148     errno_t ret = memcpy_sp(&szBuff_[wPos_], GetAvailableBufSize(), buf, size);
149     if (ret != EOK) {
150         FI_HILOGE("Failed to call memcpy_sp, errCode:%{public}d", MEMCPY_SEC_FUN_FAIL);
151         rwErrorStatus_ = ErrorStatus::ERROR_STATUS_WRITE;
152         return false;
153     }
154     wPos_ += static_cast<int32_t>(size);
155     wCount_ += 1;
156     return true;
157 }
158 
empty() const159 bool StreamBuffer::empty() const
160 {
161     return (rPos_ == wPos_);
162 }
163 
Size() const164 size_t StreamBuffer::Size() const
165 {
166     return static_cast<size_t>(wPos_);
167 }
168 
ResidualSize() const169 int32_t StreamBuffer::ResidualSize() const
170 {
171     return ((wPos_ <= rPos_) ? 0 : (wPos_ - rPos_));
172 }
173 
ChkRWError() const174 bool StreamBuffer::ChkRWError() const
175 {
176     return (rwErrorStatus_ != ErrorStatus::ERROR_STATUS_OK);
177 }
178 
GetAvailableBufSize() const179 int32_t StreamBuffer::GetAvailableBufSize() const
180 {
181     return ((wPos_ >= MAX_STREAM_BUF_SIZE) ? 0 : (MAX_STREAM_BUF_SIZE - wPos_));
182 }
183 
GetErrorStatusRemark() const184 const std::string &StreamBuffer::GetErrorStatusRemark() const
185 {
186     static const std::vector<std::pair<ErrorStatus, std::string>> remark {
187         { ErrorStatus::ERROR_STATUS_OK, "OK" },
188         { ErrorStatus::ERROR_STATUS_READ, "READ_ERROR" },
189         { ErrorStatus::ERROR_STATUS_WRITE, "WRITE_ERROR" }
190     };
191     static const std::string invalidStatus { "UNKNOWN" };
192 
193     auto tIter = std::find_if(remark.cbegin(), remark.cend(),
194         [this](const auto &item) {
195             return (item.first == rwErrorStatus_);
196         });
197     return (tIter != remark.cend() ? tIter->second : invalidStatus);
198 }
199 
Data() const200 const char *StreamBuffer::Data() const
201 {
202     return &szBuff_[0];
203 }
204 
ReadBuf() const205 const char *StreamBuffer::ReadBuf() const
206 {
207     return &szBuff_[rPos_];
208 }
209 
Clone(const StreamBuffer & buf)210 bool StreamBuffer::Clone(const StreamBuffer &buf)
211 {
212     Clean();
213     return Write(buf.Data(), buf.Size());
214 }
215 } // namespace Msdp
216 } // namespace OHOS
217