/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @addtogroup Samgr
* @{
*
* @brief Manages system capabilities.
*
* This module provides the development framework base of the service-oriented architecture (SOA).
* You can develop your own abilities based on the Samgr development framework. \n
* This module provides basic models of services, features, and functions, and registration and
* discovery capabilities. \n
*
* @since 1.0
* @version 1.0
*/
/**
* @file iunknown.h
*
* @brief Provides the base class and default implementation for external functions of system capabilities.
*
* @since 1.0
* @version 1.0
*/
#ifndef LITE_IUNKOWN_H
#define LITE_IUNKOWN_H
#include "common.h"
#include "ohos_errno.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
typedef struct IUnknown IUnknown;
/**
* @brief Defines the default IUnknown version. You can customize the version.
*
* The IUnknown interface of the default version can be called only in the current process.
* Inter-process communication is not supported. \n
*
* @since 1.0
* @version 1.0
*/
#define DEFAULT_VERSION 0x20
/**
* @brief Defines the macro for inheriting the IUnknown interface.
*
* When developing a subclass of the IUnknown class, you can use this macro to inherit the
* structures of the IUnknown interface. \n
*
*/
#define INHERIT_IUNKNOWN \
int (*QueryInterface)(IUnknown *iUnknown, int version, void **target); \
int (*AddRef)(IUnknown *iUnknown); \
int (*Release)(IUnknown *iUnknown)
/**
* @brief Defines the macro for inheriting the classes that implement the IUnknown
* interface.
*
* When developing a subclass of a class that implements the IUnknown interface, you can use
* this macro to inherit the structures of the IUnknown implementation class. \n
*
*/
#define INHERIT_IUNKNOWNENTRY(T) \
uint16 ver; \
int16 ref; \
T iUnknown
/**
* @brief Defines the default marco for initializing the IUnknown interface.
*
* When creating a subclass object of the IUnknown interface, you can use this macro to
* initialize members of the IUnknown interface to their default values. \n
*
*/
#define DEFAULT_IUNKNOWN_IMPL \
.QueryInterface = IUNKNOWN_QueryInterface, \
.AddRef = IUNKNOWN_AddRef, \
.Release = IUNKNOWN_Release
/**
* @brief Defines the macro for initializing the classes that implement the IUnknown
* interface.
*
* When creating a subclass object of a class that implements the IUnknown interface, you
* can use this macro to initialize members of the IUnknown implementation class to their
* default values. \n
* You need to add the initialization of the customized member variable. \n
*
*/
#define IUNKNOWN_ENTRY_BEGIN(version) \
.ver = (version), \
.ref = 1, \
.iUnknown = { \
DEFAULT_IUNKNOWN_IMPL
/**
* @brief IUnknown Defines the end macro for initializing the IUnknown implementation
* object.
*
* This macro is used when a subclass object of the IUnknown implementation class is
* initialized. \n
*
*/
#define IUNKNOWN_ENTRY_END }
#define DEFAULT_IUNKNOWN_ENTRY_BEGIN IUNKNOWN_ENTRY_BEGIN(DEFAULT_VERSION)
#define DEFAULT_IUNKNOWN_ENTRY_END IUNKNOWN_ENTRY_END
/**
* @brief Obtains the pointer of the IUnknown interface object from the subclass object T
* (generic macro) of the IUnknown implementation class.
*
* Use this macro when registering IUnknown interfaces with Samgr so that you can obtain
* the interfaces from the subclass objects of different IUnknown implementation classes. \n
*
* @since 1.0
* @version 1.0
*/
#define GET_IUNKNOWN(T) (IUnknown *)(&((T).iUnknown))
/**
* @brief Defines the IUnknown class.
*
* You need to inherit this structure when developing a subclass of the IUnknown interface. \n
*
*/
struct IUnknown {
/**
* Queries the subclass object of the IUnknown interface of a specified version
* (downcasting).
*/
int (*QueryInterface)(IUnknown *iUnknown, int version, void **target);
/** Adds the reference count. */
int (*AddRef)(IUnknown *iUnknown);
/** Release the reference to an IUnknown interface. */
int (*Release)(IUnknown *iUnknown);
};
/**
* @brief Defines the IUnknown implementation class.
*
* You need to inherit this structure when developing a subclass of the IUnknown
* implementation class. \n
*
* Each IUnknown interface must correspond to one or more IUnknown implementation
* classes. \n
*
*/
typedef struct IUnknownEntry {
/** Version information of IUnknown interface. */
uint16 ver;
/** Reference count of IUnknown interface. */
int16 ref;
/**
* Implementation of IUnknown interface, which is related to the specific definition
* implementation.
*/
IUnknown iUnknown;
} IUnknownEntry;
/**
* @brief Increments the reference count in this IUnknown interface.
*
* This function is called in QueryInterface. Do not call this function in the
* IUnknown interface. \n
*
* When the QueryInterface function is re-implemented, you need to call this function
* in the new QueryInterface.
*
* The system does not provide a lock to protect functions. Therefore, you need to re-implement
* functions if multiple developers are using them. \n
*
* @param iUnknown Indicates the pointer to the IUnknown interface object.
* @return Indicates the number of objects that reference the IUnknown interface.
*
* @since 1.0
* @version 1.0
*/
int IUNKNOWN_AddRef(IUnknown *iUnknown);
/**
* @brief Queries the IUnknown interfaces of a specified version (downcasting).
*
* After obtaining the IUnknown interface object, the function caller uses
* QueryInterface to convert the object to the required subclass type. \n
* The system converts {@link DEFAULT_VERSION} into the subclass type required by the caller.
* If the type conversion requirements cannot be met, you need to re-implement this function. \n
*
* @param iUnknown Indicates the pointer to the IUnknown interface.
* @param version Indicates the version of the IUnknown interface object to be converted.
* @param target Indicates the IUnknown subclass type required by the caller. This is an
* output parameter.
* @return Returns EC_SUCCESS if the conversion is successful; returns other error codes
* if the conversion fails.
*
* @since 1.0
* @version 1.0
*/
int IUNKNOWN_QueryInterface(IUnknown *iUnknown, int ver, void **target);
/**
* @brief Releases a reference to an IUnknown interface that is no longer used.
*
* In the default implementation provided by the system, if the reference count is 0,
* the memory of the IUnknown interface object and implementation object is not released. \n
*
* If the memory of the IUnknown interface object and implementation object is dynamically
* allocated, this function needs to be re-implemented. \n
* If the reference count is 0, the memory of the IUnknown interface object and
* implementation object is released. \n
*
* @param iUnknown Indicates the pointer to the IUnknown interface object.
* @return Indicates the number of IUnknown interface objects that are referenced after the
* current reference is released.
*
* @since 1.0
* @version 1.0
*/
int IUNKNOWN_Release(IUnknown *iUnknown);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // LITE_IUNKOWN_H
/** @} */