/** @file

  Copyright (c) 2017 - 2021, Arm Limited. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Glossary:
    - PFN   - Pointer to a Function

**/

#ifndef TABLE_HELPER_LIB_H_
#define TABLE_HELPER_LIB_H_

/** Is a character upper case
*/
#define IS_UPPER_CHAR(x) ((x >= 'A') && (x <= 'Z'))

/** Is a character a decimal digit
*/
#define IS_DIGIT(x) ((x >= '0') && (x <= '9'))

/** Is a character an upper case hexadecimal digit
*/
#define IS_UPPER_HEX(x) (((x >= 'A') && (x <= 'F')) || IS_DIGIT (x))

/** The GetCgfMgrInfo function gets the CM_STD_OBJ_CONFIGURATION_MANAGER_INFO
    object from the Configuration Manager.

  @param [in]  CfgMgrProtocol Pointer to the Configuration Manager protocol
                              interface.
  @param [out] CfgMfrInfo     Pointer to the Configuration Manager Info
                              object structure.

  @retval EFI_SUCCESS           The object is returned.
  @retval EFI_INVALID_PARAMETER The Object ID is invalid.
  @retval EFI_NOT_FOUND         The requested Object is not found.
  @retval EFI_BAD_BUFFER_SIZE   The size returned by the Configuration
                                Manager is less than the Object size.
**/
EFI_STATUS
EFIAPI
GetCgfMgrInfo (
  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL      * CONST  CfgMgrProtocol,
  OUT       CM_STD_OBJ_CONFIGURATION_MANAGER_INFO    **        CfgMfrInfo
  );

/** The AddAcpiHeader function updates the ACPI header structure. It uses the
    ACPI table Generator and the Configuration Manager protocol to obtain the
    information required for constructing the header.

  @param [in]     CfgMgrProtocol Pointer to the Configuration Manager
                                 protocol interface.
  @param [in]     Generator      Pointer to the ACPI table Generator.
  @param [in,out] AcpiHeader     Pointer to the ACPI table header to be
                                 updated.
  @param [in]     AcpiTableInfo  Pointer to the ACPI table info structure.
  @param [in]     Length         Length of the ACPI table.

  @retval EFI_SUCCESS           The ACPI table is updated successfully.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_NOT_FOUND         The required object information is not found.
  @retval EFI_BAD_BUFFER_SIZE   The size returned by the Configuration
                                Manager is less than the Object size for the
                                requested object.
**/
EFI_STATUS
EFIAPI
AddAcpiHeader (
  IN      CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  * CONST CfgMgrProtocol,
  IN      CONST ACPI_TABLE_GENERATOR                  * CONST Generator,
  IN OUT  EFI_ACPI_DESCRIPTION_HEADER                 * CONST AcpiHeader,
  IN      CONST CM_STD_OBJ_ACPI_TABLE_INFO            * CONST AcpiTableInfo,
  IN      CONST UINT32                                        Length
  );

/**
  Function prototype for testing if two arbitrary objects are equal.

  @param [in] Object1           Pointer to the first object to compare.
  @param [in] Object2           Pointer to the second object to compare.
  @param [in] Index1            Index of Object1. This value is optional and
                                can be ignored by the specified implementation.
  @param [in] Index2            Index of Object2. This value is optional and
                                can be ignored by the specified implementation.

  @retval TRUE                  Object1 and Object2 are equal.
  @retval FALSE                 Object1 and Object2 are NOT equal.
**/
typedef
BOOLEAN
(EFIAPI *PFN_IS_EQUAL)(
  IN CONST  VOID            * Object1,
  IN CONST  VOID            * Object2,
  IN        UINTN             Index1 OPTIONAL,
  IN        UINTN             Index2 OPTIONAL
  );

/**
  Test and report if a duplicate entry exists in the given array of comparable
  elements.

  @param [in] Array                 Array of elements to test for duplicates.
  @param [in] Count                 Number of elements in Array.
  @param [in] ElementSize           Size of an element in bytes
  @param [in] EqualTestFunction     The function to call to check if any two
                                    elements are equal.

  @retval TRUE                      A duplicate element was found or one of
                                    the input arguments is invalid.
  @retval FALSE                     Every element in Array is unique.
**/
BOOLEAN
EFIAPI
FindDuplicateValue (
  IN  CONST VOID          * Array,
  IN  CONST UINTN           Count,
  IN  CONST UINTN           ElementSize,
  IN        PFN_IS_EQUAL    EqualTestFunction
  );

/** Convert a hex number to its ASCII code.

 @param [in]  x   Hex number to convert.
                  Must be 0 <= x < 16.

 @return The ASCII code corresponding to x.
**/
UINT8
EFIAPI
AsciiFromHex (
  IN  UINT8   x
  );

/** Check if a HID is a valid PNP ID.

  @param     [in] Hid     The Hid to validate.

  @retval    TRUE         The Hid is a valid PNP ID.
  @retval    FALSE        The Hid is not a valid PNP ID.
**/
BOOLEAN
IsValidPnpId (
  IN  CONST CHAR8  * Hid
  );

/** Check if a HID is a valid ACPI ID.

  @param     [in] Hid     The Hid to validate.

  @retval    TRUE         The Hid is a valid ACPI ID.
  @retval    FALSE        The Hid is not a valid ACPI ID.
**/
BOOLEAN
IsValidAcpiId (
  IN  CONST CHAR8  * Hid
  );

#endif // TABLE_HELPER_LIB_H_