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 "av_trans_buffer.h"
17 
18 #include <securec.h>
19 
20 #include "av_trans_log.h"
21 
22 namespace OHOS {
23 namespace DistributedHardware {
24 static const uint32_t BUFFER_MAX_CAPACITY = 104857600;
25 
AVTransBuffer(MetaType type)26 AVTransBuffer::AVTransBuffer(MetaType type) : meta_()
27 {
28     meta_ = std::make_shared<BufferMeta>(type);
29 }
30 
CreateBufferData(size_t capacity)31 std::shared_ptr<BufferData> AVTransBuffer::CreateBufferData(size_t capacity)
32 {
33     if (capacity > BUFFER_MAX_CAPACITY) {
34         AVTRANS_LOGE("create buffer data input capacity is over size.");
35         return nullptr;
36     }
37     auto bufData = std::make_shared<BufferData>(capacity);
38     data_.push_back(bufData);
39     return bufData;
40 }
41 
WrapBufferData(const uint8_t * data,size_t capacity,size_t size)42 std::shared_ptr<BufferData> AVTransBuffer::WrapBufferData(const uint8_t* data, size_t capacity, size_t size)
43 {
44     if (capacity > BUFFER_MAX_CAPACITY) {
45         AVTRANS_LOGE("wrap buffer data input capacity is over size.");
46         return nullptr;
47     }
48     auto bufData = std::make_shared<BufferData>(capacity,
49         std::shared_ptr<uint8_t>(const_cast<uint8_t *>(data), [](void* ptr) {}));
50     bufData->SetSize(size);
51     data_.push_back(bufData);
52     return bufData;
53 }
54 
GetBufferData(uint32_t index)55 std::shared_ptr<BufferData> AVTransBuffer::GetBufferData(uint32_t index)
56 {
57     if (data_.size() <= index) {
58         return nullptr;
59     }
60     return data_[index];
61 }
62 
GetBufferMeta()63 std::shared_ptr<BufferMeta> AVTransBuffer::GetBufferMeta()
64 {
65     return meta_;
66 }
67 
UpdateBufferMeta(std::shared_ptr<BufferMeta> bufferMeta)68 void AVTransBuffer::UpdateBufferMeta(std::shared_ptr<BufferMeta> bufferMeta)
69 {
70     meta_ = bufferMeta;
71 }
72 
GetDataCount()73 uint32_t AVTransBuffer::GetDataCount()
74 {
75     return data_.size();
76 }
77 
IsEmpty()78 bool AVTransBuffer::IsEmpty()
79 {
80     return data_.empty();
81 }
82 
Reset()83 void AVTransBuffer::Reset()
84 {
85     if (data_[0]) {
86         data_[0]->Reset();
87     }
88     if (meta_ != nullptr) {
89         MetaType type = meta_->GetMetaType();
90         meta_.reset();
91         meta_ = std::make_shared<BufferMeta>(type);
92     }
93 }
94 
BufferData(size_t capacity)95 BufferData::BufferData(size_t capacity)
96     : capacity_(capacity), size_(0), address_(nullptr)
97 {
98     if (capacity <= CAPACITY_MAX_LENGTH) {
99         address_ = std::shared_ptr<uint8_t>(new uint8_t[capacity], std::default_delete<uint8_t[]>());
100     } else {
101         AVTRANS_LOGE("The capacity is not in range : %{public}d.", capacity);
102     }
103 }
104 
BufferData(size_t capacity,std::shared_ptr<uint8_t> bufData)105 BufferData::BufferData(size_t capacity, std::shared_ptr<uint8_t> bufData)
106     : capacity_(capacity), size_(0), address_(std::move(bufData))
107 {
108 }
109 
GetSize()110 size_t BufferData::GetSize()
111 {
112     return size_;
113 }
114 
GetCapacity()115 size_t BufferData::GetCapacity()
116 {
117     return capacity_;
118 }
119 
GetAddress() const120 uint8_t* BufferData::GetAddress() const
121 {
122     return address_.get();
123 }
124 
Write(const uint8_t * in,size_t writeSize,size_t position)125 size_t BufferData::Write(const uint8_t* in, size_t writeSize, size_t position)
126 {
127     size_t start = 0;
128     if (position == INVALID_POSITION) {
129         start = size_;
130     } else {
131         start = std::min(position, capacity_);
132     }
133     size_t length = std::min(writeSize, capacity_ - start);
134     if (memcpy_s(GetAddress() + start, length, in, length) != EOK) {
135         return 0;
136     }
137     size_ = start + length;
138     return length;
139 }
140 
Read(uint8_t * out,size_t readSize,size_t position)141 size_t BufferData::Read(uint8_t* out, size_t readSize, size_t position)
142 {
143     size_t start = 0;
144     size_t maxLength = size_;
145     if (position != INVALID_POSITION) {
146         start = std::min(position, size_);
147         maxLength = size_ - start;
148     }
149     size_t length = std::min(readSize, maxLength);
150     if (memcpy_s(out, length, GetAddress() + start, length) != EOK) {
151         return 0;
152     }
153     return length;
154 }
155 
Reset()156 void BufferData::Reset()
157 {
158     this->size_ = 0;
159 }
160 
SetSize(size_t size)161 void BufferData::SetSize(size_t size)
162 {
163     this->size_ = size;
164 }
165 
BufferMeta(MetaType type)166 BufferMeta::BufferMeta(MetaType type) : type_(type)
167 {
168 }
169 
GetMetaItem(AVTransTag tag,std::string & value)170 bool BufferMeta::GetMetaItem(AVTransTag tag, std::string& value)
171 {
172     if (tagMap_.count(tag) != 0) {
173         value = tagMap_[tag];
174         return true;
175     } else {
176         return false;
177     }
178 }
179 
SetMetaItem(AVTransTag tag,const std::string & value)180 void BufferMeta::SetMetaItem(AVTransTag tag, const std::string& value)
181 {
182     tagMap_[tag] = value;
183 }
184 
GetMetaType() const185 MetaType BufferMeta::GetMetaType() const
186 {
187     return type_;
188 }
189 } // namespace DistributedHardware
190 } // namespace OHOS