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 "distributed_operation.h"
17#include "distributed_operation_builder.h"
18#include "parcel_macro_base.h"
19
20namespace OHOS {
21namespace DistributedSchedule {
22DistributedOperation::DistributedOperation() : flags_(0), uri_("")
23{
24}
25
26DistributedOperation::DistributedOperation(const DistributedOperation& other) : flags_(0), uri_(other.uri_.ToString())
27{
28    flags_ = other.flags_;
29    action_ = other.action_;
30    deviceId_ = other.deviceId_;
31    entities_ = other.entities_;
32    bundleName_ = other.bundleName_;
33    abilityName_ = other.abilityName_;
34    moduleName_ = other.moduleName_;
35    entities_.clear();
36}
37
38DistributedOperation::~DistributedOperation()
39{}
40
41std::string DistributedOperation::GetAbilityName() const
42{
43    return abilityName_;
44}
45
46std::string DistributedOperation::GetAction() const
47{
48    return action_;
49}
50
51void DistributedOperation::SetBundleName(const std::string& bundleName)
52{
53    bundleName_ = bundleName;
54}
55
56std::string DistributedOperation::GetBundleName() const
57{
58    return bundleName_;
59}
60
61std::string DistributedOperation::GetDeviceId() const
62{
63    return deviceId_;
64}
65
66const std::vector<std::string>& DistributedOperation::GetEntities() const
67{
68    return entities_;
69}
70
71std::string DistributedOperation::GetModuleName() const
72{
73    return moduleName_;
74}
75
76void DistributedOperation::AddEntity(const std::string& entity)
77{
78    if (!HasEntity(entity)) {
79        entities_.emplace_back(entity);
80    }
81}
82
83void DistributedOperation::RemoveEntity(const std::string& entity)
84{
85    if (!entities_.empty()) {
86        auto it = std::find(entities_.begin(), entities_.end(), entity);
87        if (it != entities_.end()) {
88            entities_.erase(it);
89        }
90    }
91}
92
93bool DistributedOperation::HasEntity(const std::string& entity) const
94{
95    return std::find(entities_.begin(), entities_.end(), entity) != entities_.end();
96}
97
98int DistributedOperation::CountEntities() const
99{
100    return entities_.size();
101}
102
103unsigned int DistributedOperation::GetFlags() const
104{
105    return flags_;
106}
107
108void DistributedOperation::SetFlags(unsigned int flags)
109{
110    flags_ = flags;
111}
112
113void DistributedOperation::AddFlags(unsigned int flags)
114{
115    flags_ |= flags;
116}
117
118void DistributedOperation::RemoveFlags(unsigned int flags)
119{
120    flags_ &= ~flags;
121}
122
123Uri DistributedOperation::GetUri() const
124{
125    return uri_;
126}
127
128bool DistributedOperation::operator==(const DistributedOperation& other) const
129{
130    if (abilityName_ != other.abilityName_) {
131        return false;
132    }
133    if (action_ != other.action_) {
134        return false;
135    }
136    if (bundleName_ != other.bundleName_) {
137        return false;
138    }
139    if (deviceId_ != other.deviceId_) {
140        return false;
141    }
142    if (moduleName_ != other.moduleName_) {
143        return false;
144    }
145
146    size_t dEntitiesCount = entities_.size();
147    size_t otherEntitiesCount = other.entities_.size();
148    if (dEntitiesCount != otherEntitiesCount) {
149        return false;
150    } else {
151        for (size_t i = 0; i < dEntitiesCount; i++) {
152            if (entities_[i] != other.entities_[i]) {
153                return false;
154            }
155        }
156    }
157    if (flags_ != other.flags_) {
158        return false;
159    }
160    if (uri_.ToString() != other.uri_.ToString()) {
161        return false;
162    }
163    return true;
164}
165
166DistributedOperation& DistributedOperation::operator=(const DistributedOperation& other)
167{
168    if (this != &other) {
169        uri_ = other.uri_;
170        flags_ = other.flags_;
171        action_ = other.action_;
172        deviceId_ = other.deviceId_;
173        entities_ = other.entities_;
174        bundleName_ = other.bundleName_;
175        abilityName_ = other.abilityName_;
176        moduleName_ = other.moduleName_;
177    }
178    return *this;
179}
180
181bool DistributedOperation::Marshalling(Parcel& parcel) const
182{
183    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(abilityName_));
184    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(action_));
185    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(bundleName_));
186    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(deviceId_));
187    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, entities_);
188    WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, flags_);
189
190    Uri dUri("");
191    if (uri_ == dUri) {
192        WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, VALUE_NULL);
193    } else {
194        if (!parcel.WriteInt32(VALUE_OBJECT)) {
195            return false;
196        }
197        if (!parcel.WriteParcelable(&uri_)) {
198            return false;
199        }
200    }
201    return true;
202}
203
204DistributedOperation* DistributedOperation::Unmarshalling(Parcel& parcel)
205{
206    DistributedOperation* operation = new (std::nothrow) DistributedOperation();
207    if (operation != nullptr && !operation->ReadFromParcel(parcel)) {
208        delete operation;
209        operation = nullptr;
210    }
211
212    return operation;
213}
214
215bool DistributedOperation::ReadFromParcel(Parcel& parcel)
216{
217    std::u16string dReadString16;
218    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, dReadString16);
219    abilityName_ = Str16ToStr8(dReadString16);
220    dReadString16.clear();
221
222    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, dReadString16);
223    action_ = Str16ToStr8(dReadString16);
224    dReadString16.clear();
225
226    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, dReadString16);
227    bundleName_ = Str16ToStr8(dReadString16);
228    dReadString16.clear();
229
230    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, dReadString16);
231    deviceId_ = Str16ToStr8(dReadString16);
232    dReadString16.clear();
233
234    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(StringVector, parcel, &entities_);
235    READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, flags_);
236
237    // uri_
238    int32_t value = VALUE_NULL;
239    if (!parcel.ReadInt32(value)) {
240        return false;
241    }
242
243    if (value == VALUE_OBJECT) {
244        auto uri = parcel.ReadParcelable<Uri>();
245        if (uri != nullptr) {
246            uri_ = *uri;
247            delete uri;
248            uri = nullptr;
249        } else {
250            return false;
251        }
252    }
253    return true;
254}
255
256void DistributedOperation::SetUri(const Uri& uri)
257{
258    uri_ = uri;
259}
260
261Uri& DistributedOperation::GetUri(const Uri& uri)
262{
263    return uri_;
264}
265
266void DistributedOperation::SetAbilityName(const std::string& abilityname)
267{
268    abilityName_ = abilityname;
269}
270
271void DistributedOperation::SetDeviceId(const std::string& deviceid)
272{
273    deviceId_ = deviceid;
274}
275
276void DistributedOperation::SetAction(const std::string& action)
277{
278    action_ = action;
279}
280
281void DistributedOperation::SetEntities(const std::vector<std::string>& entities)
282{
283    entities_.clear();
284    entities_ = entities;
285}
286
287void DistributedOperation::SetModuleName(const std::string& moduleName)
288{
289    moduleName_ = moduleName;
290}
291} // namespace DistributedSchedule
292} // namespace OHOS