1 /*
2 * Copyright (c) 2022 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 "datashare_template.h"
17
18 namespace OHOS {
19 namespace DataShare {
~PublishedDataItem()20 PublishedDataItem::~PublishedDataItem()
21 {
22 Clear();
23 }
24
PublishedDataItem(const std::string & key,int64_t subscriberId,DataType value)25 PublishedDataItem::PublishedDataItem(const std::string &key, int64_t subscriberId, DataType value)
26 : key_(key), subscriberId_(subscriberId)
27 {
28 Set(value);
29 }
30
PublishedDataItem(PublishedDataItem && item)31 PublishedDataItem::PublishedDataItem(PublishedDataItem &&item)
32 {
33 key_ = std::move(item.key_);
34 subscriberId_ = std::move(item.subscriberId_);
35 value_ = std::move(item.value_);
36 if (item.IsAshmem()) {
37 item.MoveOutAshmem();
38 }
39 }
40
operator =(PublishedDataItem && item)41 PublishedDataItem &PublishedDataItem::operator=(PublishedDataItem &&item)
42 {
43 key_ = std::move(item.key_);
44 subscriberId_ = std::move(item.subscriberId_);
45 value_ = std::move(item.value_);
46 if (item.IsAshmem()) {
47 item.MoveOutAshmem();
48 }
49 return *this;
50 }
51
MoveOutAshmem()52 sptr<Ashmem> PublishedDataItem::MoveOutAshmem()
53 {
54 if (IsAshmem()) {
55 AshmemNode &node = std::get<AshmemNode>(value_);
56 if (!node.isManaged) {
57 return nullptr;
58 }
59 node.isManaged = false;
60 return std::move(node.ashmem);
61 }
62 return nullptr;
63 }
64
IsAshmem() const65 bool PublishedDataItem::IsAshmem() const
66 {
67 return value_.index() == 0;
68 }
69
IsString() const70 bool PublishedDataItem::IsString() const
71 {
72 return value_.index() == 1;
73 }
74
Set(DataType & value)75 void PublishedDataItem::Set(DataType &value)
76 {
77 Clear();
78 if (value.index() == 0) {
79 std::vector<uint8_t> &vecValue = std::get<std::vector<uint8_t>>(value);
80 auto size = vecValue.size();
81 sptr<Ashmem> mem = Ashmem::CreateAshmem((key_ + std::to_string(subscriberId_)).c_str(), size);
82 if (mem == nullptr) {
83 return;
84 }
85 if (!mem->MapReadAndWriteAshmem()) {
86 mem->CloseAshmem();
87 return;
88 }
89 if (!mem->WriteToAshmem(vecValue.data(), size, 0)) {
90 mem->UnmapAshmem();
91 mem->CloseAshmem();
92 return;
93 }
94 AshmemNode node = { mem, true };
95 value_ = std::move(node);
96 } else {
97 value_ = std::move(std::get<std::string>(value));
98 }
99 }
100
GetData() const101 PublishedDataItem::DataType PublishedDataItem::GetData() const
102 {
103 if (IsAshmem()) {
104 const AshmemNode &node = std::get<AshmemNode>(value_);
105 if (node.ashmem != nullptr) {
106 node.ashmem->MapReadOnlyAshmem();
107 uint8_t *data = (uint8_t *)node.ashmem->ReadFromAshmem(node.ashmem->GetAshmemSize(), 0);
108 if (data == nullptr) {
109 return std::vector<uint8_t>();
110 }
111 return std::vector<uint8_t>(data, data + node.ashmem->GetAshmemSize());
112 }
113 return std::vector<uint8_t>();
114 } else {
115 return std::get<std::string>(value_);
116 }
117 }
118
SetAshmem(sptr<Ashmem> ashmem,bool isManaged)119 void PublishedDataItem::SetAshmem(sptr<Ashmem> ashmem, bool isManaged)
120 {
121 AshmemNode node = { ashmem, isManaged };
122 value_ = std::move(node);
123 }
124
Clear()125 void PublishedDataItem::Clear()
126 {
127 AshmemNode *node = std::get_if<AshmemNode>(&value_);
128 if (node != nullptr) {
129 if (node->isManaged && node->ashmem != nullptr) {
130 node->ashmem->UnmapAshmem();
131 node->ashmem->CloseAshmem();
132 }
133 value_ = "";
134 }
135 }
136 } // namespace DataShare
137 } // namespace OHOS