1/*
2 * Copyright (c) 2024 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 "common_event.h"
17#include "native_log.h"
18#include "parameter_parse.h"
19
20namespace OHOS::CommonEventManager {
21    const int8_t STR_PTR_TYPE = 5;
22    std::atomic_ullong SubscriberImpl::subscriberID_ = 0;
23
24    SubscriberImpl::SubscriberImpl(std::shared_ptr<CommonEventSubscribeInfo> sp, int64_t infoId)
25        : CommonEventSubscriber(*sp)
26    {
27        id_ = ++subscriberID_;
28        LOGI("constructor SubscriberImpl");
29        valid_ = std::make_shared<bool>(false);
30        infoId_ = infoId;
31    }
32
33    SubscriberImpl::~SubscriberImpl()
34    {
35        LOGI("destructor SubscriberImpl[%{public}llu]", id_.load());
36        *valid_ = false;
37    }
38
39    static void FreeCCommonEventData(CCommonEventData &cData)
40    {
41        FreeCCommonEventDataCharPtr(cData);
42        for (int i = 0; i < cData.parameters.size; i++) {
43            auto ptr = cData.parameters.head[i];
44            free(ptr.key);
45            ptr.key = nullptr;
46            if (ptr.valueType == STR_PTR_TYPE) {
47                char **value = reinterpret_cast<char **>(ptr.value);
48                for (int j = 0; j < ptr.size; j++) {
49                    free(value[j]);
50                    value[j] = nullptr;
51                }
52            }
53            free(ptr.value);
54            ptr.value = nullptr;
55        }
56        free(cData.parameters.head);
57        cData.parameters.head = nullptr;
58    }
59
60    void SubscriberImpl::OnReceiveEvent(const CommonEventData &data)
61    {
62        LOGI("Receive event.")
63        if (valid_ == nullptr || *(valid_) == false) {
64            LOGE("OnReceiveEvent commonEventDataWorkerData or ref is invalid which may be freed before");
65            return;
66        }
67        if (this->IsOrderedCommonEvent()) {
68            LOGI("IsOrderedCommonEvent is true");
69            SetPublishResult(this);
70        }
71        LOGI("Subscribe callback start to run.")
72        CCommonEventData cData;
73        int32_t code = GetCommonEventData(data, cData);
74        if (code == ERR_NO_MEMORY || code == ERR_CES_FAILED) {
75            LOGE("Failed to excute callback: out of memory.");
76            return;
77        }
78        callback_(cData);
79        FreeCCommonEventData(cData);
80    }
81
82    unsigned long long SubscriberImpl::GetID()
83    {
84        return id_.load();
85    }
86
87    int64_t SubscriberImpl::GetSubscribeInfoId()
88    {
89        return infoId_;
90    }
91
92    void SubscriberImpl::SetSubscriberManagerId(int64_t id)
93    {
94        managerId_ = id;
95    }
96
97    int64_t SubscriberImpl::GetSubscriberManagerId()
98    {
99        return managerId_;
100    }
101
102    void SubscriberImpl::SetCallback(const std::function<void(CCommonEventData)> &callback)
103    {
104        callback_ = callback;
105        *valid_ = true;
106    }
107
108    SubscriberManager::SubscriberManager(std::shared_ptr<CommonEventSubscribeInfo> info, int64_t infoId)
109    {
110        auto objectInfo = new (std::nothrow) SubscriberImpl(info, infoId);
111        subscriber = std::shared_ptr<SubscriberImpl>(objectInfo);
112    }
113
114    SubscriberManager::~SubscriberManager()
115    {
116    }
117
118    std::shared_ptr<SubscriberImpl> SubscriberManager::GetSubscriber()
119    {
120        return subscriber;
121    }
122
123    int64_t SubscriberManager::GetSubscribeInfoId()
124    {
125        return subscriber->GetSubscribeInfoId();
126    }
127} // namespace OHOS::CommonEventManager