1 /*
2  * Copyright (c) 2021-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 #ifndef OHOS_ABILITY_BASE_USER_OBJECT_BASE_H
16 #define OHOS_ABILITY_BASE_USER_OBJECT_BASE_H
17 #include <unordered_map>
18 #include "parcel.h"
19 #include "string_ex.h"
20 namespace OHOS {
21 namespace AAFwk {
22 class UserObjectBase : public Parcelable {
23 public:
UserObjectBase(const std::string & className)24     UserObjectBase(const std::string &className) : class_name_(className)
25     {}
26     virtual ~UserObjectBase() = default;
27 
SetClassName(const std::string & className)28     inline void SetClassName(const std::string &className)
29     {
30         class_name_ = className;
31     }
GetClassName(void)32     inline std::string GetClassName(void)
33     {
34         return class_name_;
35     }
36     /**
37      * @brief The current object parameter is converted to a string
38      * @param none
39      * @return returns string of current object parameter
40      */
41     virtual std::string ToString() const = 0;
42 
43     /**
44      * @brief The current object parameter is converted to a string
45      * @param none
46      * @return returns string of current object parameter
47      */
48     virtual void Parse(const std::string &str) = 0;
49 
50     /**
51      * @brief Copy the data of the specified object to the current object with deepcopy
52      */
53     virtual void DeepCopy(std::shared_ptr<UserObjectBase> &other) = 0;
54 
55     /**
56      * @brief Indicates whether some other object is "equal to" this one.
57      * @param other The object with which to compare.
58      * @return true if this object is the same as the obj argument; false otherwise.
59      */
60     virtual bool Equals(std::shared_ptr<UserObjectBase> &other) = 0;
61 
62     /**
63      * @brief Writes a parcelable object to the given parcel.
64      * @param parcel indicates Parcel object
65      * @return Returns true being written on success or false if any error occur.
66      */
Marshalling(Parcel & parcel)67     virtual bool Marshalling(Parcel &parcel) const
68     {
69         std::string tostring = ToString();
70         return parcel.WriteString16(Str8ToStr16(tostring));
71     }
72     /**
73      * @brief Read a parcelable object to the given parcel.
74      * @param parcel indicates Parcel object
75      * @return Returns true being read on success or false if any error occur.
76      */
Unmarshalling(Parcel & parcel)77     virtual bool Unmarshalling(Parcel &parcel)
78     {
79         std::string tostring = Str16ToStr8(parcel.ReadString16());
80         Parse(tostring);
81         return true;
82     }
83 
84 protected:
85     std::string class_name_;
86 };
87 
88 using CreateUserObjectBase = std::function<UserObjectBase *(void)>;
89 class UserObjectBaseLoader {
90 public:
91     static UserObjectBaseLoader &GetInstance(void);
92     ~UserObjectBaseLoader() = default;
93     /**
94      * @brief Registered user-defined serialization class.
95      * @param objectName The name of the custom class.
96      * @param createFun Function object that creates an instance of a custom class.
97      */
98     void RegisterUserObject(const std::string &objectName, const CreateUserObjectBase &createFun);
99 
100     /**
101      * @brief Represents obtaining an instance of an object of a registered serialization class.
102      * @param className The name of the custom class {UserObjectBase subClass}.
103      *
104      * @return Returns an instance of the object, or nullptr on failure.
105      */
106     UserObjectBase *GetUserObjectByName(const std::string &className);
107 
108 private:
109     std::unordered_map<std::string, CreateUserObjectBase> register_class_list_;
110     UserObjectBaseLoader() = default;
111     UserObjectBaseLoader(const UserObjectBaseLoader &) = delete;
112     UserObjectBaseLoader &operator=(const UserObjectBaseLoader &) = delete;
113     UserObjectBaseLoader(UserObjectBaseLoader &&) = delete;
114     UserObjectBaseLoader &operator=(UserObjectBaseLoader &&) = delete;
115 };
116 
117 /**
118  * @brief Register the object's deserialization class, which must be a child UserObjectBase.
119  *
120  * @param className The name of class.
121  */
122 #define REGISTER_USER_OBJECT_BASE(className)                                                 \
123     static __attribute__((constructor)) void RegisterUserMapObject_##className()             \
124     {                                                                                        \
125         UserObjectBaseLoader::GetInstance().RegisterUserObject(                              \
126             #className, []()->UserObjectBase * { return new (std::nothrow)(className); });   \
127     }
128 }  // namespace AAFwk
129 }  // namespace OHOS
130 #endif  // OHOS_ABILITY_BASE_USER_OBJECT_BASE_H
131