public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v8 0/6] jansson edk2 port
@ 2020-12-17 13:18 Abner Chang
  2020-12-17 13:18 ` [PATCH v8 1/6] RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library Abner Chang
                   ` (6 more replies)
  0 siblings, 7 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-17 13:18 UTC (permalink / raw)
  To: devel
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Michael D Kinney, Liming Gao, Nickle Wang,
	Peter O'Hanley

In v8, - Assigne patch file order
       - Add Acked-by tags
In v7, - Remove C RTC header files to under [Include.Common.Private]
         in RedfishPkg.dec.
       - address comments given by Mike Kinney.
In v6, Remove JanssonJsonMapping.h
In v5, move BaseUcs2Utf8Lib to under RedfishPkg.
In v4,
       - Address review comments
       - Seperate CRT functions to a individule library CrtLib under
         RedfishPkg.
       - Seperate UCS2-UTF8 functions to a individule library
         BaseUcs2Utf8Lib under MdeModulePkg.

In v3, Add jansson library as the required submoudle in
       CiSettings.py for CI test.
In v2, JsonLib is moved to under RedfishPkg.

edk2 JSON library is based on jansson open source
(https://github.com/akheron/jansson) and wrapped as an edk2
library. edk2 JsonLib will be used by edk2 Redfish feature
drivers (not contributed yet) and the edk2 port of libredfish
library (not contributed yet) based on DMTF GitHub
(https://github.com/DMTF/libredfish).

Jansson is licensed under the MIT license(refer to ReadMe.rst under edk2).
It is used in production and its API is stable. In UEFI/EDKII environment,
Redfish project consumes jansson to achieve JSON operations.

* Jansson version on edk2: 2.13.1

* EDKII jansson library wrapper:
   - JsonLib.h:
     This is the denifitions of EDKII JSON APIs which are mapped to
     jannson funcitons accordingly.

   - JanssonJsonLibMapping.h:
     This is the wrapper file to map funcitons and definitions used in
     native jannson applications to edk2 JsonLib. This avoids the
     modifications on native jannson applications to be built under
     edk2 environment.

*Known issue:
  Build fail with jansson/src/load.c, overrride and add code in load.c
  to conditionally use stdin according to HAVE_UNISTD_H macro.
  The PR is submitted to jansson open source community.
  https://github.com/akheron/jansson/pull/558

Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>

Abner Chang (6):
  RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
  edk2: jansson submodule for edk2 JSON library
  RedfishPkg/CrtLib: C runtime library
  RedfishPkg/library: EDK2 port of jansson library
  RedfishPkg: Add EDK2 port of jansson library to build
  .pytool: Add required submodule for JsonLib

 .gitmodules                                   |    3 +
 .pytool/CISettings.py                         |    2 +
 ReadMe.rst                                    |    1 +
 RedfishPkg/Include/Crt/assert.h               |   16 +
 RedfishPkg/Include/Crt/errno.h                |   16 +
 RedfishPkg/Include/Crt/limits.h               |   16 +
 RedfishPkg/Include/Crt/math.h                 |   16 +
 RedfishPkg/Include/Crt/stdarg.h               |   15 +
 RedfishPkg/Include/Crt/stddef.h               |   16 +
 RedfishPkg/Include/Crt/stdio.h                |   15 +
 RedfishPkg/Include/Crt/stdlib.h               |   16 +
 RedfishPkg/Include/Crt/string.h               |   16 +
 RedfishPkg/Include/Crt/sys/time.h             |   15 +
 RedfishPkg/Include/Crt/sys/types.h            |   15 +
 RedfishPkg/Include/Crt/time.h                 |   15 +
 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
 RedfishPkg/Include/Library/CrtLib.h           |  191 +++
 RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
 .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
 .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
 RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
 RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
 RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
 RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
 RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
 RedfishPkg/Library/JsonLib/jansson            |    1 +
 RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
 .../Library/JsonLib/jansson_private_config.h  |   19 +
 RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
 RedfishPkg/RedfishLibs.dsc.inc                |    3 +
 RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
 RedfishPkg/RedfishPkg.dec                     |   25 +
 RedfishPkg/RedfishPkg.dsc                     |    3 +
 33 files changed, 4614 insertions(+)
 create mode 100644 RedfishPkg/Include/Crt/assert.h
 create mode 100644 RedfishPkg/Include/Crt/errno.h
 create mode 100644 RedfishPkg/Include/Crt/limits.h
 create mode 100644 RedfishPkg/Include/Crt/math.h
 create mode 100644 RedfishPkg/Include/Crt/stdarg.h
 create mode 100644 RedfishPkg/Include/Crt/stddef.h
 create mode 100644 RedfishPkg/Include/Crt/stdio.h
 create mode 100644 RedfishPkg/Include/Crt/stdlib.h
 create mode 100644 RedfishPkg/Include/Crt/string.h
 create mode 100644 RedfishPkg/Include/Crt/sys/time.h
 create mode 100644 RedfishPkg/Include/Crt/sys/types.h
 create mode 100644 RedfishPkg/Include/Crt/time.h
 create mode 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
 create mode 100644 RedfishPkg/Include/Library/CrtLib.h
 create mode 100644 RedfishPkg/Include/Library/JsonLib.h
 create mode 100644 RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
 create mode 100644 RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
 create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
 create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
 create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
 create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
 create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
 create mode 160000 RedfishPkg/Library/JsonLib/jansson
 create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
 create mode 100644 RedfishPkg/Library/JsonLib/jansson_private_config.h
 create mode 100644 RedfishPkg/Library/JsonLib/load.c

-- 
2.17.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v8 1/6] RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
  2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
@ 2020-12-17 13:18 ` Abner Chang
  2020-12-17 13:18 ` [PATCH v8 2/6] edk2: jansson submodule for edk2 JSON library Abner Chang
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-17 13:18 UTC (permalink / raw)
  To: devel; +Cc: Liming Gao, Leif Lindholm, Nickle Wang, Peter O'Hanley

This library provides UCS2 to UFT8 or vise versa functions to
manipulate UCS2/UTF8 strings. This library is currently used
by edk2 port of open source jansson library.

Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
Acked-by: Leif Lindholm <leif@nuviainc.com>
---
 RedfishPkg/RedfishPkg.dec                     |   4 +
 RedfishPkg/RedfishLibs.dsc.inc                |   1 +
 RedfishPkg/RedfishPkg.dsc                     |   1 +
 .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |  31 ++
 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |  61 +++
 .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c | 421 ++++++++++++++++++
 6 files changed, 519 insertions(+)
 create mode 100644 RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
 create mode 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
 create mode 100644 RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c

diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
index fc56b4fefb..3422fa6edf 100644
--- a/RedfishPkg/RedfishPkg.dec
+++ b/RedfishPkg/RedfishPkg.dec
@@ -20,6 +20,10 @@
   ##  @libraryclass Platform Redfish Host Interface Library
   #   Platform implementation-specific Redfish Host Interface.
   RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLib.h
+  ##  @libraryclass  This library provides UCS2 to UTF8 manipulation
+  #   functions.
+  #
+  Ucs2Utf8Lib|Include/Library/BaseUcs2Utf8Lib.h
 
   ##  @libraryclass Platform Redfish Credential Library
   #   Platform implementation-specific Redfish Credential Interface.
diff --git a/RedfishPkg/RedfishLibs.dsc.inc b/RedfishPkg/RedfishLibs.dsc.inc
index e780b5c270..d4c08e18ac 100644
--- a/RedfishPkg/RedfishLibs.dsc.inc
+++ b/RedfishPkg/RedfishLibs.dsc.inc
@@ -11,5 +11,6 @@
 #
 ##
 !if $(REDFISH_ENABLE) == TRUE
+  Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
 !endif
 
diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
index 0b5d8cdd4e..47fab33e3d 100644
--- a/RedfishPkg/RedfishPkg.dsc
+++ b/RedfishPkg/RedfishPkg.dsc
@@ -49,5 +49,6 @@
 [Components]
   RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf
   RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf
+  RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
 
   !include RedfishPkg/Redfish.dsc.inc
diff --git a/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf b/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
new file mode 100644
index 0000000000..ccd02ee320
--- /dev/null
+++ b/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
@@ -0,0 +1,31 @@
+## @file
+# UCS2 to UTF8 manipulation library.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = BaseUcs2Utf8Lib
+  FILE_GUID                      = 536646C3-46D0-4B12-ABC4-CDE1A33B5256
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = Ucs2Utf8Lib
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 RISCV64
+#
+
+[Sources.common]
+  BaseUcs2Utf8Lib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RedfishPkg/RedfishPkg.dec
+
+
diff --git a/RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h b/RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
new file mode 100644
index 0000000000..c6989617df
--- /dev/null
+++ b/RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
@@ -0,0 +1,61 @@
+/** @file
+  UCS2 to UTF8 manipulation library header file.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BASE_UCS2UTF8_LIB_H_
+#define BASE_UCS2UTF8_LIB_H_
+
+///
+///  L"\u0000"
+///
+#define UNICODE_FORMAT_LEN         6
+#define UNICODE_FORMAT_CHAR_LEN    2
+#define UNICODE_FORMAT_CHAR_SIZE   3
+
+#define UTF8_BUFFER_FOR_UCS2_MAX_SIZE   3
+
+/**
+  Convert a UCS2 string to a UTF8 encoded string.
+
+  @param[in]    Ucs2Str                The provided UCS2 string.
+  @param[out]   Utf8StrAddr            The converted UTF8 string address. Caller
+                                       is responsible for Free this string.
+
+  @retval       EFI_INVALID_PARAMETER  One or more parameters are invalid.
+  @retval       EFI_OUT_OF_RESOURCES   System runs out of resources.
+  @retval       EFI_SUCCESS            The UTF8 encoded string has been converted.
+
+**/
+EFI_STATUS
+UCS2StrToUTF8 (
+  IN  CHAR16     *Ucs2Str,
+  OUT CHAR8      **Utf8StrAddr
+  );
+
+/**
+  Convert a UTF8 encoded string to a UCS2 string.
+
+  @param[in]    Utf8Str                The provided UTF8 encoded string.
+  @param[out]   Ucs2StrAddr            The converted UCS2 string address. Caller
+                                       is responsible for Free this string.
+
+  @retval       EFI_INVALID_PARAMETER  The UTF8 encoded string is not valid to
+                                       convert to UCS2 string.
+                                       One or more parameters are invalid.
+  @retval       EFI_OUT_OF_RESOURCES   System runs out of resources.
+  @retval       EFI_SUCCESS            The UCS2 string has been converted.
+
+**/
+EFI_STATUS
+UTF8StrToUCS2 (
+  IN  CHAR8      *Utf8Str,
+  OUT CHAR16     **Ucs2StrAddr
+  );
+
+#endif
diff --git a/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c b/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
new file mode 100644
index 0000000000..891423734b
--- /dev/null
+++ b/RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
@@ -0,0 +1,421 @@
+/** @file
+  UCS2 to UTF8 manipulation library.
+
+  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseUcs2Utf8Lib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+/**
+  Since each UCS2 character can be represented by 1-3 UTF8 encoded characters,
+  this function is used to retrieve the UTF8 encoding size for a UCS2 character.
+
+  @param[in]   Utf8Buffer       The buffer for UTF8 encoded data.
+
+  @retval      Return the size of UTF8 encoding string or 0 if it is not for
+               UCS2 format.
+
+**/
+UINT8
+GetUTF8SizeForUCS2 (
+  IN    CHAR8      *Utf8Buffer
+  )
+{
+  CHAR8    TempChar;
+  UINT8    Utf8Size;
+
+  ASSERT (Utf8Buffer != NULL);
+
+  TempChar = *Utf8Buffer;
+  if ((TempChar & 0xF0) == 0xF0) {
+
+    //
+    // This format is not for UCS2.
+    //
+    return 0;
+  }
+
+  Utf8Size = 1;
+  if ((TempChar & 0x80) == 0x80) {
+    if ((TempChar & 0xC0) == 0xC0) {
+
+      Utf8Size ++;
+      if ((TempChar & 0xE0) == 0xE0) {
+
+        Utf8Size ++;
+      }
+    }
+  }
+
+  return Utf8Size;
+}
+
+/**
+  Since each UCS2 character can be represented by the format: \uXXXX, this function
+  is used to retrieve the UCS2 character from a Unicode format.
+  Call MUST make sure there are at least 6 Bytes in the input UTF8 buffer.
+
+  @param[in]    Utf8Buffer             The buffer for UTF8 encoded data.
+  @param[out]   Ucs2Char               The converted UCS2 character.
+
+  @retval       EFI_INVALID_PARAMETER  Non-Ascii characters found in the hexadecimal
+                                       digits string, and can't be converted to a UCS2
+                                       character.
+  @retval       EFI_SUCCESS            The UCS2 character has been retrieved.
+
+**/
+EFI_STATUS
+GetUCS2CharByFormat (
+  IN    CHAR8      *Utf8Buffer,
+  OUT   CHAR16     *Ucs2Char
+  )
+{
+  UINT8     Num1;
+  UINT8     Num2;
+  UINT8     Index;
+  CHAR8     Ucs2CharFormat[UNICODE_FORMAT_CHAR_SIZE];  /// two Hexadecimal digits Ascii string, like "3F"
+
+  for (Index = 0; Index < 4; Index ++) {
+    if ((*(Utf8Buffer + 2 + Index) & 0x80) != 0x00) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  ZeroMem (Ucs2CharFormat, UNICODE_FORMAT_CHAR_SIZE);
+
+  //
+  // Get the First Number, Offset is 2
+  //
+  CopyMem (Ucs2CharFormat, Utf8Buffer + 2, UNICODE_FORMAT_CHAR_LEN);
+  Num1 = (UINT8) AsciiStrHexToUintn (Ucs2CharFormat);
+
+  //
+  // Get the Second Number, Offset is 4
+  //
+  CopyMem (Ucs2CharFormat, Utf8Buffer + 4, UNICODE_FORMAT_CHAR_LEN);
+  Num2 = (UINT8) AsciiStrHexToUintn (Ucs2CharFormat);
+
+  //
+  // Ucs2Char is Little-Endian
+  //
+  *((CHAR8 *) Ucs2Char)        = Num2;
+  *(((CHAR8 *) Ucs2Char) + 1) = Num1;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Convert a UCS2 character to UTF8 encoding string.
+
+  @param[in]    Ucs2Char               The provided UCS2 character.
+  @param[out]   Utf8Buffer             The converted UTF8 encoded data.
+
+  @retval      Return the size of UTF8 encoding data for this UCS2 character.
+
+**/
+UINT8
+UCS2CharToUTF8 (
+  IN  CHAR16     Ucs2Char,
+  OUT CHAR8      *Utf8Buffer
+  )
+{
+  UINT16    Ucs2Number;
+
+  ASSERT (Utf8Buffer != NULL);
+
+  Ucs2Number = (UINT16) Ucs2Char;
+  if (Ucs2Number <= 0x007F) {
+
+    //
+    // UTF8 format: 0xxxxxxx
+    //
+    *Utf8Buffer = Ucs2Char & 0x7F;
+    return 1;
+
+  } else if (Ucs2Number >= 0x0080 && Ucs2Number <= 0x07FF) {
+
+    //
+    // UTF8 format: 110xxxxx 10xxxxxx
+    //
+    *(Utf8Buffer + 1) = (Ucs2Char & 0x3F) | 0x80;
+    *Utf8Buffer       = ((Ucs2Char >> 6) & 0x1F) | 0xC0;
+    return 2;
+
+  } else {  /// Ucs2Number >= 0x0800 && Ucs2Number <= 0xFFFF
+
+    //
+    // UTF8 format: 1110xxxx 10xxxxxx 10xxxxxx
+    //
+    *(Utf8Buffer + 2) = (Ucs2Char & 0x3F) | 0x80;
+    *(Utf8Buffer + 1) = ((Ucs2Char >> 6) & 0x3F) | 0x80;
+    *Utf8Buffer       = ((Ucs2Char >> 12) & 0x0F) | 0xE0;
+    return 3;
+  }
+}
+
+/**
+  Convert a UTF8 encoded data to a UCS2 character.
+
+  @param[in]    Utf8Buffer             The provided UTF8 encoded data.
+  @param[out]   Ucs2Char               The converted UCS2 character.
+
+  @retval       EFI_INVALID_PARAMETER  The UTF8 encoded string is not valid or
+                                       not for UCS2 character.
+  @retval       EFI_SUCCESS            The converted UCS2 character.
+
+**/
+EFI_STATUS
+UTF8ToUCS2Char (
+  IN   CHAR8      *Utf8Buffer,
+  OUT  CHAR16     *Ucs2Char
+  )
+{
+  UINT8    Utf8Size;
+  CHAR8    *Ucs2Buffer;
+  CHAR8    TempChar1;
+  CHAR8    TempChar2;
+  CHAR8    TempChar3;
+
+  ASSERT (Utf8Buffer != NULL && Ucs2Char != NULL);
+  ZeroMem (Ucs2Char, sizeof (CHAR16));
+  Ucs2Buffer = (CHAR8 *) Ucs2Char;
+
+  Utf8Size = GetUTF8SizeForUCS2 (Utf8Buffer);
+  switch (Utf8Size) {
+
+    case 1:
+
+      //
+      // UTF8 format: 0xxxxxxx
+      //
+      TempChar1 = *Utf8Buffer;
+      if ((TempChar1 & 0x80) != 0x00) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      *Ucs2Buffer       = TempChar1;
+      *(Ucs2Buffer + 1) = 0;
+      break;
+
+    case 2:
+
+      //
+      // UTF8 format: 110xxxxx 10xxxxxx
+      //
+      TempChar1 = *Utf8Buffer;
+      if ((TempChar1 & 0xE0) != 0xC0) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      TempChar2 = *(Utf8Buffer + 1);
+      if ((TempChar2 & 0xC0) != 0x80) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      *Ucs2Buffer       = (TempChar1 << 6) + (TempChar2 & 0x3F);
+      *(Ucs2Buffer + 1) = (TempChar1 >> 2) & 0x07;
+      break;
+
+    case 3:
+
+      //
+      // UTF8 format: 1110xxxx 10xxxxxx 10xxxxxx
+      //
+      TempChar1 = *Utf8Buffer;
+      if ((TempChar1 & 0xF0) != 0xE0) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      TempChar2 = *(Utf8Buffer + 1);
+      if ((TempChar2 & 0xC0) != 0x80) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      TempChar3 = *(Utf8Buffer + 2);
+      if ((TempChar3 & 0xC0) != 0x80) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      *Ucs2Buffer       = (TempChar2 << 6) + (TempChar3 & 0x3F);
+      *(Ucs2Buffer + 1) = (TempChar1 << 4) + ((TempChar2 >> 2) & 0x0F);
+
+      break;
+
+    default:
+
+      return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Convert a UCS2 string to a UTF8 encoded string.
+
+  @param[in]    Ucs2Str                The provided UCS2 string.
+  @param[out]   Utf8StrAddr            The converted UTF8 string address. Caller
+                                       is responsible for Free this string.
+
+  @retval       EFI_INVALID_PARAMETER  One or more parameters are invalid.
+  @retval       EFI_OUT_OF_RESOURCES   System runs out of resources.
+  @retval       EFI_SUCCESS            The UTF8 encoded string has been converted.
+
+**/
+EFI_STATUS
+UCS2StrToUTF8 (
+  IN  CHAR16     *Ucs2Str,
+  OUT CHAR8      **Utf8StrAddr
+  )
+{
+  UINTN    Ucs2StrIndex;
+  UINTN    Ucs2StrLength;
+  CHAR8    *Utf8Str;
+  UINTN    Utf8StrLength;
+  UINTN    Utf8StrIndex;
+  CHAR8    Utf8Buffer[UTF8_BUFFER_FOR_UCS2_MAX_SIZE];
+  UINT8    Utf8BufferSize;
+
+  if (Ucs2Str == NULL || Utf8StrAddr == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ucs2StrLength = StrLen (Ucs2Str);
+  Utf8StrLength = 0;
+
+  for (Ucs2StrIndex = 0; Ucs2StrIndex < Ucs2StrLength; Ucs2StrIndex ++) {
+
+    ZeroMem (Utf8Buffer, sizeof (Utf8Buffer));
+    Utf8BufferSize = UCS2CharToUTF8 (Ucs2Str[Ucs2StrIndex], Utf8Buffer);
+    Utf8StrLength += Utf8BufferSize;
+  }
+
+  Utf8Str = AllocateZeroPool (Utf8StrLength + 1);
+  if (Utf8Str == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Utf8StrIndex = 0;
+  for (Ucs2StrIndex = 0; Ucs2StrIndex < Ucs2StrLength; Ucs2StrIndex ++) {
+
+    ZeroMem (Utf8Buffer, sizeof (Utf8Buffer));
+    Utf8BufferSize = UCS2CharToUTF8 (Ucs2Str[Ucs2StrIndex], Utf8Buffer);
+
+    CopyMem (Utf8Str + Utf8StrIndex, Utf8Buffer, Utf8BufferSize);
+    Utf8StrIndex += Utf8BufferSize;
+  }
+
+  Utf8Str[Utf8StrIndex] = '\0';
+  *Utf8StrAddr = Utf8Str;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Convert a UTF8 encoded string to a UCS2 string.
+
+  @param[in]    Utf8Str                The provided UTF8 encoded string.
+  @param[out]   Ucs2StrAddr            The converted UCS2 string address. Caller
+                                       is responsible for Free this string.
+
+  @retval       EFI_INVALID_PARAMETER  The UTF8 encoded string is not valid to
+                                       convert to UCS2 string.
+                                       One or more parameters are invalid.
+  @retval       EFI_OUT_OF_RESOURCES   System runs out of resources.
+  @retval       EFI_SUCCESS            The UCS2 string has been converted.
+
+**/
+EFI_STATUS
+UTF8StrToUCS2 (
+  IN  CHAR8      *Utf8Str,
+  OUT CHAR16     **Ucs2StrAddr
+  )
+{
+  EFI_STATUS    Status;
+  UINTN         Utf8StrIndex;
+  UINTN         Utf8StrLength;
+  UINTN         Ucs2StrIndex;
+  UINT8         Utf8BufferSize;
+  CHAR16        *Ucs2StrTemp;
+
+  if (Utf8Str == NULL || Ucs2StrAddr == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // It is not an Ascii string, calculate string length.
+  //
+  Utf8StrLength = 0;
+  while (*(Utf8Str + Utf8StrLength) != '\0') {
+    Utf8StrLength ++;
+  }
+
+  //
+  // UCS2 string shall not be longer than the UTF8 string.
+  //
+  Ucs2StrTemp = AllocateZeroPool ((Utf8StrLength + 1) * sizeof (CHAR16));
+  if (Ucs2StrTemp == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Utf8StrIndex = 0;
+  Ucs2StrIndex = 0;
+  while (Utf8Str[Utf8StrIndex] != '\0') {
+
+    if (CompareMem (Utf8Str + Utf8StrIndex, "\\u", 2) == 0 &&
+      Utf8StrLength - Utf8StrIndex >= UNICODE_FORMAT_LEN) {
+
+      Status = GetUCS2CharByFormat (Utf8Str + Utf8StrIndex, Ucs2StrTemp + Ucs2StrIndex);
+      if (!EFI_ERROR (Status)) {
+
+        Utf8StrIndex += UNICODE_FORMAT_LEN;
+        Ucs2StrIndex ++;
+      } else {
+
+        StrCpyS (Ucs2StrTemp + Ucs2StrIndex, 3, L"\\u");
+
+        Ucs2StrIndex += 2;
+        Utf8StrIndex += 2;
+      }
+    } else {
+
+      Utf8BufferSize = GetUTF8SizeForUCS2 (Utf8Str + Utf8StrIndex);
+      if (Utf8BufferSize == 0 || Utf8StrLength - Utf8StrIndex < Utf8BufferSize) {
+
+        FreePool (Ucs2StrTemp);
+        return EFI_INVALID_PARAMETER;
+      }
+
+      Status = UTF8ToUCS2Char (Utf8Str + Utf8StrIndex, Ucs2StrTemp + Ucs2StrIndex);
+      if (EFI_ERROR (Status)) {
+
+        FreePool (Ucs2StrTemp);
+        return EFI_INVALID_PARAMETER;
+      }
+
+      Ucs2StrIndex ++;
+      Utf8StrIndex += Utf8BufferSize;
+    }
+  }
+
+  *Ucs2StrAddr = AllocateZeroPool ((Ucs2StrIndex + 1) * sizeof (CHAR16));
+  if (*Ucs2StrAddr == NULL) {
+
+    FreePool (Ucs2StrTemp);
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  StrCpyS (*Ucs2StrAddr, Ucs2StrIndex + 1, Ucs2StrTemp);
+  *(*Ucs2StrAddr + Ucs2StrIndex) = L'\0';
+  FreePool (Ucs2StrTemp);
+
+  return EFI_SUCCESS;
+}
+
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 2/6] edk2: jansson submodule for edk2 JSON library
  2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
  2020-12-17 13:18 ` [PATCH v8 1/6] RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library Abner Chang
@ 2020-12-17 13:18 ` Abner Chang
  2020-12-17 13:18 ` [PATCH v8 3/6] RedfishPkg/CrtLib: C runtime library Abner Chang
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-17 13:18 UTC (permalink / raw)
  To: devel
  Cc: Andrew Fish, Laszlo Ersek, Leif Lindholm, Michael D Kinney,
	Liming Gao, Nickle Wang, Peter O'Hanley

Add git submodule "jansson" library, which is the open
source project (https://github.com/akheron/jansson) used
to manipulate JSON data structure. jansson library is
wrapped as edk2 JsonLib and the use cases will be the
edk2 Redfish feature drivers and edk2 port of libredfish
(https://github.com/DMTF/libredfish).
jansson open source project is under MIT license.
(refer to ReadMe.rst under edk2).

Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Andrew Fish <afish@apple.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
Acked-by: Leif Lindholm <leif@nuviainc.com>
---
 .gitmodules                        | 3 +++
 ReadMe.rst                         | 1 +
 RedfishPkg/Library/JsonLib/jansson | 1 +
 3 files changed, 5 insertions(+)
 create mode 160000 RedfishPkg/Library/JsonLib/jansson

diff --git a/.gitmodules b/.gitmodules
index c3a4e4aeca..0f06c09a29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -17,3 +17,6 @@
 	path = BaseTools/Source/C/BrotliCompress/brotli
 	url = https://github.com/google/brotli
 	ignore = untracked
+[submodule "RedfishPkg/Library/JsonLib/jansson"]
+	path = RedfishPkg/Library/JsonLib/jansson
+	url = https://github.com/akheron/jansson
diff --git a/ReadMe.rst b/ReadMe.rst
index c3c8178373..b754378646 100644
--- a/ReadMe.rst
+++ b/ReadMe.rst
@@ -93,6 +93,7 @@ that are covered by additional licenses.
 -  `MdeModulePkg/Library/BrotliCustomDecompressLib/brotli <https://github.com/google/brotli/blob/666c3280cc11dc433c303d79a83d4ffbdd12cc8d/LICENSE>`__
 -  `MdeModulePkg/Universal/RegularExpressionDxe/oniguruma <https://github.com/kkos/oniguruma/blob/abfc8ff81df4067f309032467785e06975678f0d/COPYING>`__
 -  `UnitTestFrameworkPkg/Library/CmockaLib/cmocka <https://git.cryptomilk.org/projects/cmocka.git/tree/COPYING?h=cmocka-1.1.5&id=f5e2cd77c88d9f792562888d2b70c5a396bfbf7a>`__
+-  `RedfishPkg/Library/JsonLib/jansson <https://github.com/akheron/jansson/blob/2882ead5bb90cf12a01b07b2c2361e24960fae02/LICENSE>`__
 
 The EDK II Project is composed of packages. The maintainers for each package
 are listed in `Maintainers.txt <Maintainers.txt>`__.
diff --git a/RedfishPkg/Library/JsonLib/jansson b/RedfishPkg/Library/JsonLib/jansson
new file mode 160000
index 0000000000..e9ebfa7e77
--- /dev/null
+++ b/RedfishPkg/Library/JsonLib/jansson
@@ -0,0 +1 @@
+Subproject commit e9ebfa7e77a6bee77df44e096b100e7131044059
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 3/6] RedfishPkg/CrtLib: C runtime library
  2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
  2020-12-17 13:18 ` [PATCH v8 1/6] RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library Abner Chang
  2020-12-17 13:18 ` [PATCH v8 2/6] edk2: jansson submodule for edk2 JSON library Abner Chang
@ 2020-12-17 13:18 ` Abner Chang
  2020-12-17 13:18 ` [PATCH v8 4/6] RedfishPkg/library: EDK2 port of jansson library Abner Chang
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-17 13:18 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Nickle Wang, Peter O'Hanley

CRT library is currently used by edk2 JsonLib (open source
jansson project) and edk2 RedfishLib (libredfish open source
project). CrtLib library provides the necessary C runtime
equivalent edk2 functions for open source projects.

Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
Acked-by: Leif Lindholm <leif@nuviainc.com>
---
 RedfishPkg/RedfishPkg.dec            |  10 +
 RedfishPkg/RedfishLibs.dsc.inc       |   1 +
 RedfishPkg/RedfishPkg.dsc            |   1 +
 RedfishPkg/Library/CrtLib/CrtLib.inf |  38 ++
 RedfishPkg/Include/Crt/assert.h      |  16 +
 RedfishPkg/Include/Crt/errno.h       |  16 +
 RedfishPkg/Include/Crt/limits.h      |  16 +
 RedfishPkg/Include/Crt/math.h        |  16 +
 RedfishPkg/Include/Crt/stdarg.h      |  15 +
 RedfishPkg/Include/Crt/stddef.h      |  16 +
 RedfishPkg/Include/Crt/stdio.h       |  15 +
 RedfishPkg/Include/Crt/stdlib.h      |  16 +
 RedfishPkg/Include/Crt/string.h      |  16 +
 RedfishPkg/Include/Crt/sys/time.h    |  15 +
 RedfishPkg/Include/Crt/sys/types.h   |  15 +
 RedfishPkg/Include/Crt/time.h        |  15 +
 RedfishPkg/Include/Library/CrtLib.h  | 191 +++++++++
 RedfishPkg/Library/CrtLib/CrtLib.c   | 595 +++++++++++++++++++++++++++
 RedfishPkg/RedfishPkg.ci.yaml        |  19 +
 19 files changed, 1042 insertions(+)
 create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
 create mode 100644 RedfishPkg/Include/Crt/assert.h
 create mode 100644 RedfishPkg/Include/Crt/errno.h
 create mode 100644 RedfishPkg/Include/Crt/limits.h
 create mode 100644 RedfishPkg/Include/Crt/math.h
 create mode 100644 RedfishPkg/Include/Crt/stdarg.h
 create mode 100644 RedfishPkg/Include/Crt/stddef.h
 create mode 100644 RedfishPkg/Include/Crt/stdio.h
 create mode 100644 RedfishPkg/Include/Crt/stdlib.h
 create mode 100644 RedfishPkg/Include/Crt/string.h
 create mode 100644 RedfishPkg/Include/Crt/sys/time.h
 create mode 100644 RedfishPkg/Include/Crt/sys/types.h
 create mode 100644 RedfishPkg/Include/Crt/time.h
 create mode 100644 RedfishPkg/Include/Library/CrtLib.h
 create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c

diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
index 3422fa6edf..9a9a1190fb 100644
--- a/RedfishPkg/RedfishPkg.dec
+++ b/RedfishPkg/RedfishPkg.dec
@@ -16,10 +16,14 @@
 [Includes]
   Include
 
+[Includes.Common.Private]
+  Include/Crt                   # Header files for C RTL.
+
 [LibraryClasses]
   ##  @libraryclass Platform Redfish Host Interface Library
   #   Platform implementation-specific Redfish Host Interface.
   RedfishPlatformHostInterfaceLib|Include/Library/RedfishHostInterfaceLib.h
+
   ##  @libraryclass  This library provides UCS2 to UTF8 manipulation
   #   functions.
   #
@@ -29,6 +33,12 @@
   #   Platform implementation-specific Redfish Credential Interface.
   RedfishPlatformCredentialLib|Include/Library/RedfishCredentialLib.h
 
+  ##  @libraryclass  Provides the C runtime library functions
+  #   CRT library is currently used by edk2 JsonLib (open source
+  #   jansson project) and edk2 RedfishLib (libredfish open source
+  #   project).
+  CrtLib|Include/Library/CrtLib.h
+
 [Protocols]
   ## Include/Protocol/RedfishDiscover.h
   gEfiRedfishDiscoverProtocolGuid      = { 0x5db12509, 0x4550, 0x4347, { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }}
diff --git a/RedfishPkg/RedfishLibs.dsc.inc b/RedfishPkg/RedfishLibs.dsc.inc
index d4c08e18ac..2a951bd8fa 100644
--- a/RedfishPkg/RedfishLibs.dsc.inc
+++ b/RedfishPkg/RedfishLibs.dsc.inc
@@ -12,5 +12,6 @@
 ##
 !if $(REDFISH_ENABLE) == TRUE
   Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
+  CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
 !endif
 
diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
index 47fab33e3d..8df2c69390 100644
--- a/RedfishPkg/RedfishPkg.dsc
+++ b/RedfishPkg/RedfishPkg.dsc
@@ -50,5 +50,6 @@
   RedfishPkg/Library/PlatformHostInterfaceLibNull/PlatformHostInterfaceLibNull.inf
   RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf
   RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
+  RedfishPkg/Library/CrtLib/CrtLib.inf
 
   !include RedfishPkg/Redfish.dsc.inc
diff --git a/RedfishPkg/Library/CrtLib/CrtLib.inf b/RedfishPkg/Library/CrtLib/CrtLib.inf
new file mode 100644
index 0000000000..661822f148
--- /dev/null
+++ b/RedfishPkg/Library/CrtLib/CrtLib.inf
@@ -0,0 +1,38 @@
+## @file
+# EDK2 C Runtime Library for opensource project.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = CrtLib
+  FILE_GUID                      = 8263B8AC-D021-425D-B337-3EC96F5DC19B
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = CrtLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 RISCV64
+#
+
+[Sources]
+  CrtLib.c
+
+[LibraryClasses]
+  BaseLib
+  BaseSortLib
+  DebugLib
+  MemoryAllocationLib
+  UefiRuntimeServicesTableLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RedfishPkg/RedfishPkg.dec
+
+
diff --git a/RedfishPkg/Include/Crt/assert.h b/RedfishPkg/Include/Crt/assert.h
new file mode 100644
index 0000000000..f9ab7ef9ca
--- /dev/null
+++ b/RedfishPkg/Include/Crt/assert.h
@@ -0,0 +1,16 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_ASSERT_H_
+#define CRT_ASSERT_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/errno.h b/RedfishPkg/Include/Crt/errno.h
new file mode 100644
index 0000000000..d30aee14de
--- /dev/null
+++ b/RedfishPkg/Include/Crt/errno.h
@@ -0,0 +1,16 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_ERRNO_H_
+#define CRT_ERRNO_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/limits.h b/RedfishPkg/Include/Crt/limits.h
new file mode 100644
index 0000000000..f3bdd33f2a
--- /dev/null
+++ b/RedfishPkg/Include/Crt/limits.h
@@ -0,0 +1,16 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_LIMITS_H_
+#define CRT_LIMITS_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/math.h b/RedfishPkg/Include/Crt/math.h
new file mode 100644
index 0000000000..984c0ccc21
--- /dev/null
+++ b/RedfishPkg/Include/Crt/math.h
@@ -0,0 +1,16 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_MATH_H_
+#define CRT_MATH_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/stdarg.h b/RedfishPkg/Include/Crt/stdarg.h
new file mode 100644
index 0000000000..d5a314ad3b
--- /dev/null
+++ b/RedfishPkg/Include/Crt/stdarg.h
@@ -0,0 +1,15 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef CRT_STDARG_H_
+#define CRT_STDARG_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/stddef.h b/RedfishPkg/Include/Crt/stddef.h
new file mode 100644
index 0000000000..15a37bf50e
--- /dev/null
+++ b/RedfishPkg/Include/Crt/stddef.h
@@ -0,0 +1,16 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_STDDEF_H_
+#define CRT_STDDEF_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/stdio.h b/RedfishPkg/Include/Crt/stdio.h
new file mode 100644
index 0000000000..25e610be10
--- /dev/null
+++ b/RedfishPkg/Include/Crt/stdio.h
@@ -0,0 +1,15 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef CRT_STDIO_H_
+#define CRT_STDIO_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/stdlib.h b/RedfishPkg/Include/Crt/stdlib.h
new file mode 100644
index 0000000000..5b3dd273c8
--- /dev/null
+++ b/RedfishPkg/Include/Crt/stdlib.h
@@ -0,0 +1,16 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_STDLIB_H_
+#define CRT_STDLIB_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/string.h b/RedfishPkg/Include/Crt/string.h
new file mode 100644
index 0000000000..f60b87ccd2
--- /dev/null
+++ b/RedfishPkg/Include/Crt/string.h
@@ -0,0 +1,16 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_STRING_H_
+#define CRT_STRING_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/sys/time.h b/RedfishPkg/Include/Crt/sys/time.h
new file mode 100644
index 0000000000..4ced176cda
--- /dev/null
+++ b/RedfishPkg/Include/Crt/sys/time.h
@@ -0,0 +1,15 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef CRT_SYS_TIME_H_
+#define CRT_SYS_TIME_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/sys/types.h b/RedfishPkg/Include/Crt/sys/types.h
new file mode 100644
index 0000000000..c4f807214c
--- /dev/null
+++ b/RedfishPkg/Include/Crt/sys/types.h
@@ -0,0 +1,15 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef CRT_SYS_TYPES_H_
+#define CRT_SYS_TYPES_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Crt/time.h b/RedfishPkg/Include/Crt/time.h
new file mode 100644
index 0000000000..ca04ac8730
--- /dev/null
+++ b/RedfishPkg/Include/Crt/time.h
@@ -0,0 +1,15 @@
+/** @file
+  Include file to support building the third-party jansson library.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef CRT_TIME_H_
+#define CRT_TIME_H_
+
+#include <Library/CrtLib.h>
+
+#endif
diff --git a/RedfishPkg/Include/Library/CrtLib.h b/RedfishPkg/Include/Library/CrtLib.h
new file mode 100644
index 0000000000..79a16e3192
--- /dev/null
+++ b/RedfishPkg/Include/Library/CrtLib.h
@@ -0,0 +1,191 @@
+/** @file
+  CRT wrapper head functions for jansson system call.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CRT_LIB_H_
+#define CRT_LIB_H_
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+
+#define MAX_STRING_SIZE  0x10000000
+
+// Minimum value for an object of type long long int.
+#define LLONG_MIN   MIN_INT64
+
+// Maximum value for an object of type long long int.
+#define LLONG_MAX   MAX_INT64
+
+// We dont support double on edk2
+#define HUGE_VAL    0
+
+#if defined(MDE_CPU_X64) || defined(MDE_CPU_AARCH64) || defined(MDE_CPU_IA64) || defined(MDE_CPU_RISCV64)
+//
+// With GCC we would normally use SIXTY_FOUR_BIT_LONG, but MSVC needs
+// SIXTY_FOUR_BIT, because 'long' is 32-bit and only 'long long' is
+// 64-bit. Since using 'long long' works fine on GCC too, just do that.
+//
+#define SIXTY_FOUR_BIT
+#elif defined(MDE_CPU_IA32) || defined(MDE_CPU_ARM) || defined(MDE_CPU_EBC)
+#define THIRTY_TWO_BIT
+#endif
+
+//
+// Map all va_xxxx elements to VA_xxx defined in MdePkg/Include/Base.h
+//
+#if !defined(__CC_ARM) // if va_list is not already defined
+#define va_list   VA_LIST
+#define va_arg    VA_ARG
+#define va_start  VA_START
+#define va_end    VA_END
+#else // __CC_ARM
+#define va_start(Marker, Parameter)   __va_start(Marker, Parameter)
+#define va_arg(Marker, TYPE)          __va_arg(Marker, TYPE)
+#define va_end(Marker)                ((void)0)
+#endif
+
+//
+// Definitions for global constants used by CRT library routines
+//
+#define INT_MAX      MAX_INT32        /* Maximum (signed) int value */
+#define LONG_MAX     0X7FFFFFFFL      /* max value for a long */
+#define LONG_MIN     (-LONG_MAX-1)    /* min value for a long */
+#define ULONG_MAX    0xFFFFFFFF       /* Maximum unsigned long value */
+#define CHAR_BIT     8                /* Number of bits in a char */
+
+// Maximum value for an object of type unsigned long long int.
+#define ULLONG_MAX  0xFFFFFFFFFFFFFFFFULL // 2^64 - 1
+// Maximum value for an object of type unsigned char.
+#define UCHAR_MAX   255  // 2^8 - 1
+
+//
+// Basic types mapping
+//
+typedef UINTN          size_t;
+typedef INTN           ssize_t;
+typedef INT32          time_t;
+typedef UINT8          __uint8_t;
+typedef UINT8          sa_family_t;
+typedef UINT32         uid_t;
+typedef UINT32         gid_t;
+typedef INT32          int32_t;
+typedef UINT32         uint32_t;
+typedef UINT16         uint16_t;
+typedef UINT8          uint8_t;
+typedef enum {false, true} bool;
+
+//
+// File operations are not required for EFI building,
+// so FILE is mapped to VOID * to pass build
+//
+typedef VOID  *FILE;
+
+//
+// Global variables
+//
+extern int  errno;
+extern FILE *stderr;
+
+//
+// Function prototypes of CRT Library routines
+//
+void           *malloc     (size_t);
+void           *realloc    (void *, size_t);
+void           *calloc     (size_t Num, size_t Size);
+void           free        (void *);
+void           *memset     (void *, int, size_t);
+int            memcmp      (const void *, const void *, size_t);
+int            isdigit     (int);
+int            isspace     (int);
+int            tolower     (int);
+int            isupper     (int);
+int            isxdigit    (int);
+int            isalnum     (int);
+void           *memcpy     (void *, const void *, size_t);
+void           *memset     (void *, int, size_t);
+void           *memchr     (const void *, int, size_t);
+int            memcmp      (const void *, const void *, size_t);
+void           *memmove    (void *, const void *, size_t);
+int            strcmp      (const char *, const char *);
+int            strncmp     (const char *, const char *, size_t);
+char           *strcpy     (char *, const char *);
+size_t         strlen      (const char *);
+char           *strcat     (char *, const char *);
+char           *strchr     (const char *, int);
+int            strcasecmp  (const char *, const char *);
+int            strncasecmp (const char *, const char *, size_t);
+char           *strncpy    (char *, size_t, const char *, size_t);
+int            strncmp     (const char *, const char *, size_t);
+char           *strrchr    (const char *, int);
+unsigned long  strtoul     (const char *, char **, int);
+char *         strstr      (const char *s1 , const char *s2);
+long           strtol      (const char *, char **, int);
+char           *strerror   (int);
+size_t         strspn      (const char *, const char *);
+char *         strdup      (const char *str);
+char *         strpbrk     (const char *s1, const char *s2);
+unsigned long long strtoull(const char * nptr, char ** endptr, int base);
+long long      strtoll     (const char * nptr, char ** endptr, int base);
+long           strtol      (const char * nptr, char ** endptr, int base);
+double         strtod      (const char * __restrict nptr, char ** __restrict endptr);
+size_t         strcspn     (const char *, const char *);
+int            printf      (const char *, ...);
+int            sscanf      (const char *, const char *, ...);
+FILE           *fopen      (const char *, const char *);
+size_t         fread       (void *, size_t, size_t, FILE *);
+size_t         fwrite      (const void *, size_t, size_t, FILE *);
+int            fclose      (FILE *);
+int            fprintf     (FILE *, const char *, ...);
+int            fgetc       (FILE * _File);
+uid_t          getuid      (void);
+uid_t          geteuid     (void);
+gid_t          getgid      (void);
+gid_t          getegid     (void);
+void           qsort       (void *, size_t, size_t, int (*)(const void *, const void *));
+char           *getenv     (const char *);
+#if defined(__GNUC__) && (__GNUC__ >= 2)
+void           abort       (void) __attribute__((__noreturn__));
+#else
+void           abort       (void);
+#endif
+int            toupper     (int);
+int            Digit2Val   (int);
+time_t         time        (time_t *);
+
+//
+// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
+//
+#define strcmp                            AsciiStrCmp
+#define memcpy(dest,source,count)         CopyMem(dest,source,(UINTN)(count))
+#define memset(dest,ch,count)             SetMem(dest,(UINTN)(count),(UINT8)(ch))
+#define memchr(buf,ch,count)              ScanMem8(buf,(UINTN)(count),(UINT8)ch)
+#define memcmp(buf1,buf2,count)           (int)(CompareMem(buf1,buf2,(UINTN)(count)))
+#define memmove(dest,source,count)        CopyMem(dest,source,(UINTN)(count))
+#define strlen(str)                       (size_t)(AsciiStrnLenS(str,MAX_STRING_SIZE))
+#define strcpy(strDest,strSource)         AsciiStrCpyS(strDest,(strlen(strSource)+1),strSource)
+#define strncpy(strDest,strSource,count)  AsciiStrnCpyS(strDest,(UINTN)count,strSource,(UINTN)count)
+#define strncpys(strDest, DestLen, strSource,count)  AsciiStrnCpyS(strDest,DestLen,strSource,(UINTN)count)
+#define strcat(strDest,strSource)         AsciiStrCatS(strDest,(strlen(strSource)+strlen(strDest)+1),strSource)
+#define strchr(str,ch)                    ScanMem8((VOID *)(str),AsciiStrSize(str),(UINT8)ch)
+#define strcasecmp(str1,str2)             (int)AsciiStriCmp(str1,str2)
+#define strstr(s1,s2)                     AsciiStrStr(s1,s2)
+#define snprintf(buf,len,...)             AsciiSPrint(buf,len,__VA_ARGS__)
+#define vsnprintf(buf,len,format,marker)  AsciiVSPrint((buf),(len),(format),(marker))
+#define assert(expression)                ASSERT(expression)
+#define offsetof(type,member)             OFFSET_OF(type,member)
+
+#define EOF (-1)
+
+extern int  errno;
+
+#define ERANGE   34                /* 34   Result too large */
+
+#endif
diff --git a/RedfishPkg/Library/CrtLib/CrtLib.c b/RedfishPkg/Library/CrtLib/CrtLib.c
new file mode 100644
index 0000000000..d3705236c8
--- /dev/null
+++ b/RedfishPkg/Library/CrtLib/CrtLib.c
@@ -0,0 +1,595 @@
+/** @file
+  CRT wrapper functions for system call.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+#include <Library/CrtLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SortLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+int  errno = 0;
+
+/**
+  Determine if a particular character is an alphanumeric character
+  @return  Returns 1 if c is an alphanumeric character, otherwise returns 0.
+**/
+int isalnum (int c)
+{
+  //
+  // <alnum> ::= [0-9] | [a-z] | [A-Z]
+  //
+  return ((('0' <= (c)) && ((c) <= '9')) ||
+          (('a' <= (c)) && ((c) <= 'z')) ||
+          (('A' <= (c)) && ((c) <= 'Z')));
+}
+
+/**
+  Determine if a particular character is a digital character
+
+  @return  Returns 1 if c is an digital character, otherwise returns 0.
+**/
+int isdchar (int c)
+{
+  //
+  // [0-9] | [e +-.]
+  //
+  return ((('0' <= (c)) && ((c) <= '9')) ||
+          (c == 'e') || (c == 'E') ||
+          (c == '+') || (c == '-') ||
+          (c == '.'));
+}
+
+/**
+  Determine if a particular character is a space character
+
+  @return  Returns 1 if c is a space character
+**/
+int isspace (int c)
+{
+  //
+  // <space> ::= [ ]
+  //
+  return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') || ((c) == '\v')  || ((c) == '\f');
+}
+
+/**
+  Allocates memory blocks
+*/
+void *malloc (size_t size)
+{
+  return AllocatePool ((UINTN) size);
+}
+
+/**
+  De-allocates or frees a memory block
+*/
+void free (void *ptr)
+{
+  //
+  // In Standard C, free() handles a null pointer argument transparently. This
+  // is not true of FreePool() below, so protect it.
+  //
+  if (ptr != NULL) {
+    FreePool (ptr);
+  }
+}
+
+/**
+  NetBSD Compatibility Function strdup creates a duplicate copy of a string.
+
+  @return  Returns the pointer to duplicated string.
+**/
+char * strdup(const char *str)
+{
+  size_t len;
+  char *copy;
+
+  len = strlen(str) + 1;
+  if ((copy = malloc(len)) == NULL)
+    return (NULL);
+  memcpy(copy, str, len);
+  return (copy);
+}
+
+/** The toupper function converts a lowercase letter to a corresponding
+    uppercase letter.
+
+    @param[in]    c   The character to be converted.
+
+    @return   If the argument is a character for which islower is true and
+              there are one or more corresponding characters, as specified by
+              the current locale, for which isupper is true, the toupper
+              function returns one of the corresponding characters (always the
+              same one for any given locale); otherwise, the argument is
+              returned unchanged.
+**/
+int
+toupper(
+  IN  int c
+  )
+{
+  if ( (c >= 'a') && (c <= 'z') ) {
+    c = c - ('a' - 'A');
+  }
+  return c;
+}
+
+/**
+  Digit to a value.
+
+  @return  Returns the value of digit.
+**/
+int
+Digit2Val( int c)
+{
+  if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) {  /* If c is one of [A-Za-z]... */
+    c = toupper(c) - 7;   // Adjust so 'A' is ('9' + 1)
+  }
+  return c - '0';   // Value returned is between 0 and 35, inclusive.
+}
+
+
+/** The strtoll function converts the initial portion of the string pointed to
+    by nptr to long long int representation.
+
+    See the description for strtol for more information.
+
+  @return   The strtoll function returns the converted value, if any. If no
+            conversion could be performed, zero is returned. If the correct
+            value is outside the range of representable values, LLONG_MIN or
+            LLONG_MAX is returned (according to the sign of the value, if any),
+            and the value of the macro ERANGE is stored in errno.
+**/
+long long
+strtoll(const char * nptr, char ** endptr, int base)
+{
+  const char *pEnd;
+  long long   Result = 0;
+  long long   Previous;
+  int         temp;
+  BOOLEAN     Negative = FALSE;
+
+  pEnd = nptr;
+
+  if((base < 0) || (base == 1) || (base > 36)) {
+    if(endptr != NULL) {
+    *endptr = NULL;
+    }
+    return 0;
+  }
+  // Skip leading spaces.
+  while(isspace(*nptr))   ++nptr;
+
+  // Process Subject sequence: optional sign followed by digits.
+  if(*nptr == '+') {
+    Negative = FALSE;
+    ++nptr;
+  }
+  else if(*nptr == '-') {
+    Negative = TRUE;
+    ++nptr;
+  }
+
+  if(*nptr == '0') {  /* Might be Octal or Hex */
+    if(toupper(nptr[1]) == 'X') {   /* Looks like Hex */
+      if((base == 0) || (base == 16)) {
+        nptr += 2;  /* Skip the "0X"      */
+        base = 16;  /* In case base was 0 */
+      }
+    }
+    else {    /* Looks like Octal */
+      if((base == 0) || (base == 8)) {
+        ++nptr;     /* Skip the leading "0" */
+        base = 8;   /* In case base was 0   */
+      }
+    }
+  }
+  if(base == 0) {   /* If still zero then must be decimal */
+    base = 10;
+  }
+  if(*nptr  == '0') {
+    for( ; *nptr == '0'; ++nptr);  /* Skip any remaining leading zeros */
+    pEnd = nptr;
+  }
+
+  while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
+    Previous = Result;
+    Result = MultS64x64 (Result, base) + (long long int)temp;
+    if( Result <= Previous) {   // Detect Overflow
+      if(Negative) {
+        Result = LLONG_MIN;
+      }
+      else {
+        Result = LLONG_MAX;
+      }
+      Negative = FALSE;
+      errno = ERANGE;
+      break;
+    }
+    pEnd = ++nptr;
+  }
+  if(Negative) {
+    Result = -Result;
+  }
+
+  // Save pointer to final sequence
+  if(endptr != NULL) {
+    *endptr = (char *)pEnd;
+  }
+  return Result;
+}
+
+/** The strtol, strtoll, strtoul, and strtoull functions convert the initial
+    portion of the string pointed to by nptr to long int, long long int,
+    unsigned long int, and unsigned long long int representation, respectively.
+    First, they decompose the input string into three parts: an initial,
+    possibly empty, sequence of white-space characters (as specified by the
+    isspace function), a subject sequence resembling an integer represented in
+    some radix determined by the value of base, and a final string of one or
+    more unrecognized characters, including the terminating null character of
+    the input string. Then, they attempt to convert the subject sequence to an
+    integer, and return the result.
+
+    If the value of base is zero, the expected form of the subject sequence is
+    that of an integer constant, optionally preceded
+    by a plus or minus sign, but not including an integer suffix. If the value
+    of base is between 2 and 36 (inclusive), the expected form of the subject
+    sequence is a sequence of letters and digits representing an integer with
+    the radix specified by base, optionally preceded by a plus or minus sign,
+    but not including an integer suffix. The letters from a (or A) through z
+    (or Z) are ascribed the values 10 through 35; only letters and digits whose
+    ascribed values are less than that of base are permitted. If the value of
+    base is 16, the characters 0x or 0X may optionally precede the sequence of
+    letters and digits, following the sign if present.
+
+    The subject sequence is defined as the longest initial subsequence of the
+    input string, starting with the first non-white-space character, that is of
+    the expected form. The subject sequence contains no characters if the input
+    string is empty or consists entirely of white space, or if the first
+    non-white-space character is other than a sign or a permissible letter or digit.
+
+    If the subject sequence has the expected form and the value of base is
+    zero, the sequence of characters starting with the first digit is
+    interpreted as an integer constant. If the subject sequence has the
+    expected form and the value of base is between 2 and 36, it is used as the
+    base for conversion, ascribing to each letter its value as given above. If
+    the subject sequence begins with a minus sign, the value resulting from the
+    conversion is negated (in the return type). A pointer to the final string
+    is stored in the object pointed to by endptr, provided that endptr is
+    not a null pointer.
+
+    In other than the "C" locale, additional locale-specific subject sequence
+    forms may be accepted.
+
+    If the subject sequence is empty or does not have the expected form, no
+    conversion is performed; the value of nptr is stored in the object pointed
+    to by endptr, provided that endptr is not a null pointer.
+
+  @return   The strtol, strtoll, strtoul, and strtoull functions return the
+            converted value, if any. If no conversion could be performed, zero
+            is returned. If the correct value is outside the range of
+            representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
+            ULONG_MAX, or ULLONG_MAX is returned (according to the return type
+            and sign of the value, if any), and the value of the macro ERANGE
+            is stored in errno.
+**/
+long
+strtol(const char * nptr, char ** endptr, int base)
+{
+  const char *pEnd;
+  long        Result = 0;
+  long        Previous;
+  int         temp;
+  BOOLEAN     Negative = FALSE;
+
+  pEnd = nptr;
+
+  if((base < 0) || (base == 1) || (base > 36)) {
+    if(endptr != NULL) {
+    *endptr = NULL;
+    }
+    return 0;
+  }
+  // Skip leading spaces.
+  while(isspace(*nptr))   ++nptr;
+
+  // Process Subject sequence: optional sign followed by digits.
+  if(*nptr == '+') {
+    Negative = FALSE;
+    ++nptr;
+  }
+  else if(*nptr == '-') {
+    Negative = TRUE;
+    ++nptr;
+  }
+
+  if(*nptr == '0') {  /* Might be Octal or Hex */
+    if(toupper(nptr[1]) == 'X') {   /* Looks like Hex */
+      if((base == 0) || (base == 16)) {
+        nptr += 2;  /* Skip the "0X"      */
+        base = 16;  /* In case base was 0 */
+      }
+    }
+    else {    /* Looks like Octal */
+      if((base == 0) || (base == 8)) {
+        ++nptr;     /* Skip the leading "0" */
+        base = 8;   /* In case base was 0   */
+      }
+    }
+  }
+  if(base == 0) {   /* If still zero then must be decimal */
+    base = 10;
+  }
+  if(*nptr  == '0') {
+    for( ; *nptr == '0'; ++nptr);  /* Skip any remaining leading zeros */
+    pEnd = nptr;
+  }
+
+  while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
+    Previous = Result;
+    Result = (Result * base) + (long int)temp;
+    if( Result <= Previous) {   // Detect Overflow
+      if(Negative) {
+        Result = LONG_MIN;
+      }
+      else {
+        Result = LONG_MAX;
+      }
+      Negative = FALSE;
+      errno = ERANGE;
+      break;
+    }
+    pEnd = ++nptr;
+  }
+  if(Negative) {
+    Result = -Result;
+  }
+
+  // Save pointer to final sequence
+  if(endptr != NULL) {
+    *endptr = (char *)pEnd;
+  }
+  return Result;
+}
+
+/** The strtoull function converts the initial portion of the string pointed to
+    by nptr to unsigned long long int representation.
+
+    See the description for strtol for more information.
+
+  @return   The strtoull function returns the converted value, if any. If no
+            conversion could be performed, zero is returned. If the correct
+            value is outside the range of representable values, ULLONG_MAX is
+            returned and the value of the macro ERANGE is stored in errno.
+**/
+unsigned long long
+strtoull(const char * nptr, char ** endptr, int base)
+{
+  const char           *pEnd;
+  unsigned long long    Result = 0;
+  unsigned long long    Previous;
+  int                   temp;
+
+  pEnd = nptr;
+
+  if((base < 0) || (base == 1) || (base > 36)) {
+    if(endptr != NULL) {
+    *endptr = NULL;
+    }
+    return 0;
+  }
+  // Skip leading spaces.
+  while(isspace(*nptr))   ++nptr;
+
+  // Process Subject sequence: optional + sign followed by digits.
+  if(*nptr == '+') {
+    ++nptr;
+  }
+
+  if(*nptr == '0') {  /* Might be Octal or Hex */
+    if(toupper(nptr[1]) == 'X') {   /* Looks like Hex */
+      if((base == 0) || (base == 16)) {
+        nptr += 2;  /* Skip the "0X"      */
+        base = 16;  /* In case base was 0 */
+      }
+    }
+    else {    /* Looks like Octal */
+      if((base == 0) || (base == 8)) {
+        ++nptr;     /* Skip the leading "0" */
+        base = 8;   /* In case base was 0   */
+      }
+    }
+  }
+  if(base == 0) {   /* If still zero then must be decimal */
+    base = 10;
+  }
+  if(*nptr  == '0') {
+    for( ; *nptr == '0'; ++nptr);  /* Skip any remaining leading zeros */
+    pEnd = nptr;
+  }
+
+  while( isalnum(*nptr) && ((temp = Digit2Val(*nptr)) < base)) {
+    Previous = Result;
+    Result = DivU64x32 (Result, base) + (unsigned long long)temp;
+    if( Result < Previous)  {   // If we overflowed
+      Result = ULLONG_MAX;
+      errno = ERANGE;
+      break;
+    }
+    pEnd = ++nptr;
+  }
+
+  // Save pointer to final sequence
+  if(endptr != NULL) {
+    *endptr = (char *)pEnd;
+  }
+  return Result;
+}
+
+/**
+  edk2 Jansson port does not support doubles, simply return 0.
+
+  These conversion functions convert the initial portion of the string
+  pointed to by nptr to double, float, and long double representation,
+  respectively.
+
+  The strtod(), strtof(), and strtold() functions return the converted
+  value, if any.
+
+  If endptr is not NULL, a pointer to the character after the last charac-
+  ter used in the conversion is stored in the location referenced by
+  endptr.
+
+  If no conversion is performed, zero is returned and the value of nptr is
+  stored in the location referenced by endptr.
+
+  If the correct value would cause overflow, plus or minus HUGE_VAL,
+  HUGE_VALF, or HUGE_VALL is returned (according to the sign and type of
+  the return value), and ERANGE is stored in errno.  If the correct value
+  would cause underflow, zero is returned and ERANGE is stored in errno.
+
+  @return  Return 0.
+**/
+double
+strtod (const char * __restrict nptr, char ** __restrict endptr) {
+
+    DEBUG((DEBUG_INFO, "We don't supprot double type on edk2 yet!"));
+    ASSERT(FALSE);
+    return (double)0;
+}
+
+/**
+  Allocate and zero-initialize array.
+**/
+void *
+calloc(size_t Num, size_t Size)
+{
+  void       *RetVal;
+  size_t      NumSize;
+
+  NumSize = Num * Size;
+  RetVal  = NULL;
+  if (NumSize != 0) {
+  RetVal = malloc(NumSize);
+  if( RetVal != NULL) {
+    (VOID)ZeroMem( RetVal, NumSize);
+  }
+  }
+  DEBUG((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
+
+  return RetVal;
+}
+
+//
+//  The arrays give the cumulative number of days up to the first of the
+//  month number used as the index (1 -> 12) for regular and leap years.
+//  The value at index 13 is for the whole year.
+//
+UINTN CumulativeDays[2][14] = {
+  {
+    0,
+    0,
+    31,
+    31 + 28,
+    31 + 28 + 31,
+    31 + 28 + 31 + 30,
+    31 + 28 + 31 + 30 + 31,
+    31 + 28 + 31 + 30 + 31 + 30,
+    31 + 28 + 31 + 30 + 31 + 30 + 31,
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
+    31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
+  },
+  {
+    0,
+    0,
+    31,
+    31 + 29,
+    31 + 29 + 31,
+    31 + 29 + 31 + 30,
+    31 + 29 + 31 + 30 + 31,
+    31 + 29 + 31 + 30 + 31 + 30,
+    31 + 29 + 31 + 30 + 31 + 30 + 31,
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
+    31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
+  }
+};
+
+#define IsLeap(y)   (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
+#define SECSPERMIN  (60)
+#define SECSPERHOUR (60 * 60)
+#define SECSPERDAY  (24 * SECSPERHOUR)
+
+/**
+  Get the system time as seconds elapsed since midnight, January 1, 1970.
+**/
+time_t time (time_t *timer)
+{
+  EFI_TIME  Time;
+  time_t    CalTime;
+  UINTN     Year;
+
+  //
+  // Get the current time and date information
+  //
+  gRT->GetTime (&Time, NULL);
+
+  //
+  // Years Handling
+  // UTime should now be set to 00:00:00 on Jan 1 of the current year.
+  //
+  for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
+    CalTime = CalTime + (time_t)(CumulativeDays[IsLeap(Year)][13] * SECSPERDAY);
+  }
+
+  //
+  // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment
+  //
+  CalTime = CalTime +
+            (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +
+            (time_t)(CumulativeDays[IsLeap(Time.Year)][Time.Month] * SECSPERDAY) +
+            (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
+            (time_t)(Time.Hour * SECSPERHOUR) +
+            (time_t)(Time.Minute * 60) +
+            (time_t)Time.Second;
+
+  if (timer != NULL) {
+    *timer = CalTime;
+  }
+
+  return CalTime;
+}
+
+/**
+  Performs a quick sort
+**/
+void qsort (void *base, size_t num, size_t width, int (*compare)(const void *, const void *))
+{
+
+  ASSERT (base    != NULL);
+  ASSERT (compare != NULL);
+
+  PerformQuickSort (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare);
+  return;
+}
+
+/**
+  Get character from stream, we don't support file operastion on edk2 JSON library.
+
+  @return Returns the character currently pointed by the internal file position indicator of the specified stream
+
+**/
+int fgetc(FILE * _File){
+   return 0;
+}
diff --git a/RedfishPkg/RedfishPkg.ci.yaml b/RedfishPkg/RedfishPkg.ci.yaml
index 20c297ad22..9895fdac99 100644
--- a/RedfishPkg/RedfishPkg.ci.yaml
+++ b/RedfishPkg/RedfishPkg.ci.yaml
@@ -17,6 +17,25 @@
         ],
         ## Both file path and directory path are accepted.
         "IgnoreFiles": [
+            ## Below are files incorporated with open source which are
+            ## not edk2 coding standard compliant.
+            ##
+            ## EDK2 CRT library which is not edk2 coding
+            ## standard compliant.
+            ## C runtime library for EDKII JsonLib.
+            "Include/Crt/sys",
+            "Include/Crt/assert.h",
+            "Include/Crt/errno.h",
+            "Include/Crt/limits.h",
+            "Include/Crt/math.h",
+            "Include/Crt/stdarg.h",
+            "Include/Crt/stddef.h",
+            "Include/Crt/stdio.h",
+            "Include/Crt/stdlib.h",
+            "Include/Crt/string.h",
+            "Include/Crt/time.h",
+            "Include/Library/CrtLib.h",
+            "Library/CrtLib/CrtLib.c"
         ]
     },
     "CompilerPlugin": {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 4/6] RedfishPkg/library: EDK2 port of jansson library
  2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
                   ` (2 preceding siblings ...)
  2020-12-17 13:18 ` [PATCH v8 3/6] RedfishPkg/CrtLib: C runtime library Abner Chang
@ 2020-12-17 13:18 ` Abner Chang
  2020-12-18 11:19   ` Leif Lindholm
  2020-12-17 13:18 ` [PATCH v8 5/6] RedfishPkg: Add EDK2 port of jansson library to build Abner Chang
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 19+ messages in thread
From: Abner Chang @ 2020-12-17 13:18 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Nickle Wang, Peter O'Hanley

edk2 JsonLib which is the edk2 port of open source
jansson library.
(https://github.com/akheron/jansson)
jansson library is the open source project to manipulate
JSON data structure.

Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
---
 RedfishPkg/RedfishPkg.dec                     |   11 +
 RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
 RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
 RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
 .../Library/JsonLib/jansson_private_config.h  |   19 +
 RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
 RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
 RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
 RedfishPkg/RedfishPkg.ci.yaml                 |    8 +-
 9 files changed, 3045 insertions(+), 1 deletion(-)
 create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
 create mode 100644 RedfishPkg/Include/Library/JsonLib.h
 create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
 create mode 100644 RedfishPkg/Library/JsonLib/jansson_private_config.h
 create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
 create mode 100644 RedfishPkg/Library/JsonLib/load.c
 create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst

diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec
index 9a9a1190fb..6499d77f3e 100644
--- a/RedfishPkg/RedfishPkg.dec
+++ b/RedfishPkg/RedfishPkg.dec
@@ -18,6 +18,12 @@
 
 [Includes.Common.Private]
   Include/Crt                   # Header files for C RTL.
+  Library/JsonLib               # Header files for jansson configuration files.
+                                #  - jansson_config.h
+                                #  - jansson_private_config.h
+                                # jansson.h refers to above two configuration
+                                # files for building platform jansson library.
+  Library/JsonLib/jansson/src   # For referring to jannson.h
 
 [LibraryClasses]
   ##  @libraryclass Platform Redfish Host Interface Library
@@ -39,6 +45,11 @@
   #   project).
   CrtLib|Include/Library/CrtLib.h
 
+  ##  @libraryclass  Provides the library functions based on third party
+  #  jansson library to manipulate JSON data structure.
+  #
+  JsonLib|Include/Library/JsonLib.h
+
 [Protocols]
   ## Include/Protocol/RedfishDiscover.h
   gEfiRedfishDiscoverProtocolGuid      = { 0x5db12509, 0x4550, 0x4347, { 0x96, 0xb3, 0x73, 0xc0, 0xff, 0x6e, 0x86, 0x9f }}
diff --git a/RedfishPkg/Library/JsonLib/JsonLib.inf b/RedfishPkg/Library/JsonLib/JsonLib.inf
new file mode 100644
index 0000000000..3a54783081
--- /dev/null
+++ b/RedfishPkg/Library/JsonLib/JsonLib.inf
@@ -0,0 +1,89 @@
+## @file
+# Thirty party Jansson library for JSON operations.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001b
+  BASE_NAME                      = JsonLib
+  FILE_GUID                      = F5E36815-305A-4C5A-9D75-4F2149E45255
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = JsonLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 RISCV64
+#
+
+[Sources]
+  #
+  # Below are the source code of third
+  # party jansson library.
+  #
+  jansson/src/dump.c
+  jansson/src/error.c
+  jansson/src/hashtable.c
+  jansson/src/hashtable_seed.c
+  jansson/src/memory.c
+  jansson/src/pack_unpack.c
+  jansson/src/strbuffer.c
+  jansson/src/strconv.c
+  jansson/src/utf.c
+  jansson/src/value.c
+  jansson/src/version.c
+  #
+  # Below are the source of edk2 JsonLib.
+  #
+  JsonLib.c
+  jansson_config.h
+  jansson_private_config.h
+  #
+  # Below is the source code override to fix the build issue.
+  # Add code in load.c to conditionally use stdin according
+  # to HAVE_UNISTD_H macro. The PR is submitted to jansson
+  # open source community.
+  # https://github.com/akheron/jansson/pull/558
+  #
+  load.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RedfishPkg/RedfishPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  Ucs2Utf8Lib
+  CrtLib
+  DebugLib
+  MemoryAllocationLib
+  PrintLib
+  UefiRuntimeServicesTableLib
+  UefiLib
+
+[BuildOptions]
+  #
+  # Disables the following Visual Studio compiler warnings
+  # so we do not break the build with /WX option:
+  #   C4090: 'function' : different 'const' qualifiers
+  #   C4244: conversion from type1 to type2, possible loss of data
+  #   C4702: unreachable code
+  #   C4706: assignment within conditional expression
+  #   C4456: declaration hides previous local declaration
+  #   C4334: 32-bit shift implicitly converted to 64-bit
+  #   C4204: nonstandard extension used: non-constant aggregate initializer
+  #   C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data
+  #
+  # Define macro HAVE_CONFIG_H to include jansson_private_config.h to build.
+  # Undefined _WIN32, WIN64, _MSC_VER macros
+  # On GCC, no error on the unused-function and unused-but-set-variable.
+  #
+  MSFT:*_*_*_CC_FLAGS = /wd4204 /wd4267 /wd4702 /wd4706 /wd4244 /wd4090 /wd4456 /wd4334 /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
+  GCC:*_*_*_CC_FLAGS = -Wno-unused-function -Wno-unused-but-set-variable
+
diff --git a/RedfishPkg/Include/Library/JsonLib.h b/RedfishPkg/Include/Library/JsonLib.h
new file mode 100644
index 0000000000..9d77413419
--- /dev/null
+++ b/RedfishPkg/Include/Library/JsonLib.h
@@ -0,0 +1,763 @@
+/** @file
+  APIs for JSON operations.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef JSON_LIB_H_
+#define JSON_LIB_H_
+
+typedef    VOID*    EDKII_JSON_VALUE;
+typedef    VOID*    EDKII_JSON_ARRAY;
+typedef    VOID*    EDKII_JSON_OBJECT;
+
+///
+/// Map to json_int_t in jansson.h
+///
+typedef    INT64   EDKII_JSON_INT_T; // #JSON_INTEGER_IS_LONG_LONG is set to 1
+                                     // in jansson_Config.h
+
+///
+///  Map to the definitions in jansson.h
+///
+#define EDKII_JSON_MAX_INDENT        0x1F
+#define EDKII_JSON_INDENT(n)         ((n) & EDKII_JSON_MAX_INDENT)
+
+#define EDKII_JSON_COMPACT           0x20
+#define EDKII_JSON_ENSURE_ASCII      0x40
+#define EDKII_JSON_SORT_KEYS         0x80
+#define EDKII_JSON_PRESERVE_ORDER    0x100
+#define EDKII_JSON_ENCODE_ANY        0x200
+#define EDKII_JSON_ESCAPE_SLASH      0x400
+#define EDKII_JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11)
+#define EDKII_JSON_EMBED             0x10000
+
+#define EDKII_JSON_ARRAY_FOREACH(Array, Index, Value) \
+  for(Index = 0; \
+    Index < JsonArrayCount(Array) && (Value = JsonArrayGetValue(Array, Index)); \
+    Index++)
+
+///
+///  Map to the json_error_t in jansson.h
+///
+#define EDKII_JSON_ERROR_TEXT_LENGTH   160
+#define EDKII_JSON_ERROR_SOURCE_LENGTH 80
+typedef struct {
+    INTN    Line;
+    INTN    Column;
+    INTN    Position;
+    CHAR8   Source [EDKII_JSON_ERROR_SOURCE_LENGTH];
+    CHAR8   Text [EDKII_JSON_ERROR_TEXT_LENGTH];
+} EDKII_JSON_ERROR;
+
+///
+///  Map to the json_type in jansson.h
+///
+typedef enum {
+    EdkiiJsonTypeObject,
+    EdkiiJsonTypeArray,
+    EdkiiJsonTypeString,
+    EdkiiJsonTypeInteger,
+    EdkiiJsonTypeReal,
+    EdkiiJsonTypeTrue,
+    EdkiiJsonTypeFalse,
+    EdkiiJsonTypeNull
+} EDKII_JSON_TYPE;
+
+/**
+  The function is used to convert a NULL terminated UTF8 encoded string to a JSON
+  value. Only object and array represented strings can be converted successfully,
+  since they are the only valid root values of a JSON text for UEFI usage.
+
+  Real number and number with exponent part are not supportted by UEFI.
+
+  Caller needs to cleanup the root value by calling JsonValueFree().
+
+  @param[in]   Text             The NULL terminated UTF8 encoded string to convert
+
+  @retval      Array JSON value or object JSON value, or NULL when any error occurs.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+TextToJson (
+  IN    CHAR8*    Text
+  );
+
+/**
+  The function is used to convert the JSON root value to a UTF8 encoded string which
+  is terminated by NULL, or return NULL on error.
+
+  Only array JSON value or object JSON value is valid for converting, and caller is
+  responsible for free converted string.
+
+  @param[in]   Json               The JSON value to be converted
+
+  @retval      The JSON value converted UTF8 string or NULL.
+
+**/
+CHAR8*
+EFIAPI
+JsonToText (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON array,
+  or NULL on error. Initially, the array is empty.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @retval      The created JSON value which contains a JSON array or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitArray (
+  VOID
+  );
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON object,
+  or NULL on error. Initially, the object is empty.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @retval      The created JSON value which contains a JSON object or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitObject (
+  VOID
+  );
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON string,
+  or NULL on error.
+
+  The input string must be NULL terminated Ascii format, non-Ascii characters will
+  be processed as an error. Unicode characters can also be represented by Ascii string
+  as the format: \u + 4 hexadecimal digits, like \u3E5A, or \u003F.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   String      The Ascii string to initialize to JSON value
+
+  @retval      The created JSON value which contains a JSON string or NULL. Select a
+               Getter API for a specific encoding format.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitAsciiString (
+  IN    CONST CHAR8    *String
+  );
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON string,
+  or NULL on error.
+
+  The input must be a NULL terminated UCS2 format Unicode string.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   String      The Unicode string to initialize to JSON value
+
+  @retval      The created JSON value which contains a JSON string or NULL. Select a
+               Getter API for a specific encoding format.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitUnicodeString (
+  IN    CHAR16    *String
+  );
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON integer,
+  or NULL on error.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   Value       The integer to initialize to JSON value
+
+  @retval      The created JSON value which contains a JSON number or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitNumber (
+  IN    INT64    Value
+  );
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON boolean,
+  or NULL on error.
+
+  Boolean JSON value is kept as static value, and no need to do any cleanup work.
+
+  @param[in]   Value       The boolean value to initialize.
+
+  @retval      The created JSON value which contains a JSON boolean or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitBoolean (
+  IN    BOOLEAN    Value
+  );
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON NULL,
+  or NULL on error.
+
+  NULL JSON value is kept as static value, and no need to do any cleanup work.
+
+  @retval      The created NULL JSON value.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitNull (
+  VOID
+  );
+
+/**
+  The function is used to decrease the reference count of a JSON value by one, and once
+  this reference count drops to zero, the value is destroyed and it can no longer be used.
+  If this destroyed value is object type or array type, reference counts for all containing
+  JSON values will be decreased by 1. Boolean JSON value and NULL JSON value won't be destroyed
+  since they are static values kept in memory.
+
+  Reference Count Strategy: BaseJsonLib uses this strategy to track whether a value is still
+  in use or not. When a value is created, it's reference count is set to 1. If a reference to a
+  value is kept for use, its reference count is incremented, and when the value is no longer
+  needed, the reference count is decremented. When the reference count drops to zero, there are
+  no references left, and the value can be destroyed.
+
+  The given JSON value maybe NULL and not causing any problem. Just output the debug message
+  to inform caller the NULL value is passed in.
+
+  @param[in]   Json             The JSON value to be freed. json_decref may return without any
+                                changes if Json is NULL.
+
+**/
+VOID
+EFIAPI
+JsonValueFree (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to create a fresh copy of a JSON value, and all child values are deep
+  copied in a recursive fashion. It should be called when this JSON value might be modified
+  in later use, but the original still wants to be used in somewhere else.
+
+  Reference counts of the returned root JSON value and all child values will be set to 1, and
+  caller needs to cleanup the root value by calling JsonValueFree().
+
+  * Note: Since this function performs a copy from bottom to up, too many calls may cause some
+  performance issues, user should avoid unnecessary calls to this function unless it is really
+  needed.
+
+  @param[in]   Json             The JSON value to be cloned.
+
+  @retval      Return the cloned JSON value, or NULL on error.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueClone (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to return if the provided JSON value contains a JSON array.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON array.
+  @retval      FALSE            The JSON value doesn't contain a JSON array.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsArray (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to return if the provided JSON value contains a JSON object.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON object.
+  @retval      FALSE            The JSON value doesn't contain a JSON object.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsObject (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to return if the provided JSON Value contains a string, Ascii or
+  Unicode format is not differentiated.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON string.
+  @retval      FALSE            The JSON value doesn't contain a JSON string.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsString (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to return if the provided JSON value contains a JSON number.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value is contains JSON number.
+  @retval      FALSE            The JSON value doesn't contain a JSON number.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsNumber (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to return if the provided JSON value contains a JSON boolean.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON boolean.
+  @retval      FALSE            The JSON value doesn't contain a JSON boolean.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsBoolean (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to return if the provided JSON value contains a JSON NULL.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON NULL.
+  @retval      FALSE            The JSON value doesn't contain a JSON NULL.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsNull (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to retrieve the associated array in an array type JSON value.
+
+  Any changes to the returned array will impact the original JSON value.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated array in JSON value or NULL.
+
+**/
+EDKII_JSON_ARRAY
+EFIAPI
+JsonValueGetArray (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to retrieve the associated object in an object type JSON value.
+
+  Any changes to the returned object will impact the original JSON value.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated object in JSON value or NULL.
+
+**/
+EDKII_JSON_OBJECT
+EFIAPI
+JsonValueGetObject (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to retrieve the associated Ascii string in a string type JSON value.
+
+  Any changes to the returned string will impact the original JSON value.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated Ascii string in JSON value or NULL.
+
+**/
+CHAR8*
+EFIAPI
+JsonValueGetAsciiString (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to retrieve the associated Unicode string in a string type JSON value.
+
+  Caller can do any changes to the returned string without any impact to the original JSON
+  value, and caller needs to free the returned string.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated Unicode string in JSON value or NULL.
+
+**/
+CHAR16*
+EFIAPI
+JsonValueGetUnicodeString (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to retrieve the associated integer in a number type JSON value.
+
+  The input JSON value should not be NULL or contain no JSON number, otherwise it will
+  ASSERT() and return 0.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated number in JSON value.
+
+**/
+INT64
+EFIAPI
+JsonValueGetNumber (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to retrieve the associated boolean in a boolean type JSON value.
+
+  The input JSON value should not be NULL or contain no JSON boolean, otherwise it will
+  ASSERT() and return FALSE.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated value of JSON boolean.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueGetBoolean (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to retrieve the associated string in a string type JSON value.
+
+  Any changes to the returned string will impact the original JSON value.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated Ascii string in JSON value or NULL.
+
+**/
+CONST CHAR8*
+EFIAPI
+JsonValueGetString (
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to get the number of elements in a JSON object, or 0 if it is NULL or
+  not a JSON object.
+
+  @param[in]   JsonObject              The provided JSON object.
+
+  @retval      Return the number of elements in this JSON object or 0.
+
+**/
+UINTN
+EFIAPI
+JsonObjectSize (
+  IN    EDKII_JSON_OBJECT    JsonObject
+  );
+
+/**
+  The function is used to enumerate all keys in a JSON object.
+
+  Caller should be responsible to free the returned key array refference. But contained keys
+  are read only and must not be modified or freed.
+
+  @param[in]   JsonObj                The provided JSON object for enumeration.
+  @param[out]  KeyCount               The count of keys in this JSON object.
+
+  @retval      Return an array of the enumerated keys in this JSON object or NULL.
+
+**/
+CHAR8**
+JsonObjectGetKeys (
+  IN    EDKII_JSON_OBJECT    JsonObj,
+  OUT   UINTN                *KeyCount
+  );
+
+/**
+  The function is used to get a JSON value corresponding to the input key from a JSON object.
+
+  It only returns a reference to this value and any changes on this value will impact the
+  original JSON object. If that is not expected, please call JsonValueClone() to clone it to
+  use.
+
+  Input key must be a valid NULL terminated UTF8 encoded string. NULL will be returned when
+  Key-Value is not found in this JSON object.
+
+  @param[in]   JsonObj           The provided JSON object.
+  @param[in]   Key               The key of the JSON value to be retrieved.
+
+  @retval      Return the corresponding JSON value to key, or NULL on error.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonObjectGetValue (
+  IN    CONST EDKII_JSON_OBJECT    JsonObj,
+  IN    CONST CHAR8                *Key
+  );
+
+/**
+  The function is used to set a JSON value corresponding to the input key from a JSON object,
+  and the reference count of this value will be increased by 1.
+
+  Input key must be a valid NULL terminated UTF8 encoded string. If there already is a value for
+  this key, this key will be assigned to the new JSON value. The old JSON value will be removed
+  from this object and thus its' reference count will be decreased by 1.
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   JsonObj                The provided JSON object.
+  @param[in]   Key                    The key of the JSON value to be set.
+  @param[in]   Json                   The JSON value to set to this JSON object mapped by key.
+
+  @retval      EFI_ABORTED            Some error occur and operation aborted.
+  @retval      EFI_SUCCESS            The JSON value has been set to this JSON object.
+
+**/
+EFI_STATUS
+EFIAPI
+JsonObjectSetValue (
+  IN    EDKII_JSON_OBJECT    JsonObj,
+  IN    CONST CHAR8          *Key,
+  IN    EDKII_JSON_VALUE     Json
+  );
+
+/**
+  The function is used to get the number of elements in a JSON array, or 0 if it is NULL or
+  not a JSON array.
+
+  @param[in]   JsonArray              The provided JSON array.
+
+  @retval      Return the number of elements in this JSON array or 0.
+
+**/
+UINTN
+EFIAPI
+JsonArrayCount (
+  IN    EDKII_JSON_ARRAY    JsonArray
+  );
+
+/**
+  The function is used to return the JSON value in the array at position index. The valid range
+  for this index is from 0 to the return value of JsonArrayCount() minus 1.
+
+  It only returns a reference to this value and any changes on this value will impact the
+  original JSON object. If that is not expected, please call JsonValueClone() to clone it to
+  use.
+
+  If this array is NULL or not a JSON array, or if index is out of range, NULL will be returned.
+
+  @param[in]   JsonArray         The provided JSON Array.
+
+  @retval      Return the JSON value located in the Index position or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonArrayGetValue (
+  IN    EDKII_JSON_ARRAY    JsonArray,
+  IN    UINTN               Index
+  );
+
+/**
+  The function is used to append a JSON value to the end of the JSON array, and grow the size of
+  array by 1. The reference count of this value will be increased by 1.
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   JsonArray              The provided JSON object.
+  @param[in]   Json                   The JSON value to append.
+
+  @retval      EFI_ABORTED            Some error occur and operation aborted.
+  @retval      EFI_SUCCESS            JSON value has been appended to the end of the JSON array.
+
+**/
+EFI_STATUS
+EFIAPI
+JsonArrayAppendValue (
+  IN    EDKII_JSON_ARRAY    JsonArray,
+  IN    EDKII_JSON_VALUE    Json
+  );
+
+/**
+  The function is used to remove a JSON value at position index, shifting the elements after index
+  one position towards the start of the array. The reference count of this value will be decreased
+  by 1.
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   JsonArray              The provided JSON array.
+  @param[in]   Index                  The Index position before removement.
+
+  @retval      EFI_ABORTED            Some error occur and operation aborted.
+  @retval      EFI_SUCCESS            The JSON array has been removed at position index.
+
+**/
+EFI_STATUS
+EFIAPI
+JsonArrayRemoveValue (
+  IN    EDKII_JSON_ARRAY    JsonArray,
+  IN    UINTN               Index
+  );
+
+/**
+  Dump JSON to a buffer
+
+  @param[in]   JsonValue       The provided JSON array.
+  @param[in]   Index           The Index position before removement.
+
+  @retval      NULL            Dump fail if NULL returned, otherwise the buffer
+                               contain JSON paylaod in ASCII string.
+**/
+CHAR8 *
+EFIAPI
+JsonDumpString (
+  IN    EDKII_JSON_ARRAY    JsonValue,
+  IN    UINTN               Flags
+  );
+
+/**
+  Load JSON from a buffer
+
+  @param[in]   Buffer        Bufffer to the JSON payload
+  @param[in]   BufferLen     Length of the buffer
+  @param[in]   Flags         Flag of loading JSON buffer
+
+  @retval      EDKII_JSON_VALUE  NULL means fail to load JSON payload.
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonLoadBuffer (
+  IN    CONST CHAR8       *Buffer,
+  IN    UINTN             BufferLen,
+  IN    UINTN             Flags,
+  IN    EDKII_JSON_ERROR  *Error
+  );
+
+/**
+  Decrease reference
+
+  @param[in]   JsonValue      JSON value
+**/
+VOID
+EFIAPI
+JsonDecreaseReference (
+  IN EDKII_JSON_VALUE JsonValue
+  );
+
+/**
+  Increase reference
+
+  @param[in]   JsonValue      JSON value
+  @retval      EDKII_JSON_VALUE of itself
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonIncreaseReference (
+  IN EDKII_JSON_VALUE JsonValue
+  );
+/**
+  Returns an opaque iterator which can be used to iterate over all key-value pairs
+  in object, or NULL if object is empty
+
+  @param[in]   JsonValue      JSON value
+**/
+VOID *
+EFIAPI
+JsonObjectIterator (
+  IN EDKII_JSON_VALUE JsonValue
+  );
+
+/**
+  Extract the associated value from iterator.
+
+  @param[in]   Iterator   Iterator pointer
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonObjectIteratorValue (
+  IN VOID *Iterator
+  );
+
+/**
+  Returns an iterator pointing to the next key-value pair in object after iter,
+  or NULL if the whole object has been iterated through.
+
+  @param[in]   JsonValue  JSON value
+  @param[in]   Iterator   Iterator pointer
+  @retval      Iterator pointer
+**/
+VOID *
+JsonObjectIteratorNext (
+  IN EDKII_JSON_VALUE JsonValue,
+  IN VOID             *Iterator
+  );
+
+/**
+  Returns the json type of this json value
+
+  @param[in]   JsonValue  JSON value
+  @retval      JSON type returned
+**/
+EDKII_JSON_TYPE
+EFIAPI
+JsonGetType(
+  IN EDKII_JSON_VALUE JsonValue
+  );
+#endif
diff --git a/RedfishPkg/Library/JsonLib/jansson_config.h b/RedfishPkg/Library/JsonLib/jansson_config.h
new file mode 100644
index 0000000000..c66d3ced9b
--- /dev/null
+++ b/RedfishPkg/Library/JsonLib/jansson_config.h
@@ -0,0 +1,41 @@
+/** @file This is the configuration file for building jansson library.
+
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+ **/
+
+#ifndef JANSSON_CONFIG_H_
+#define JANSSON_CONFIG_H_
+
+///
+/// We don't support inline JSON on edk2
+///
+#define JSON_INLINE
+
+///
+/// We support long long on edk2
+///
+#define JSON_INTEGER_IS_LONG_LONG 1
+
+///
+/// We don't support locale on edk2
+///
+#define JSON_HAVE_LOCALECONV 0
+
+///
+/// We don't support atomic builtins on edk2
+///
+#define JSON_HAVE_ATOMIC_BUILTINS 0
+
+///
+/// We don't support sync builtins on edk2
+///
+#define JSON_HAVE_SYNC_BUILTINS 0
+
+///
+/// Mzximum deepth is set to 2048
+///
+#define JSON_PARSER_MAX_DEPTH 2048
+
+#endif
diff --git a/RedfishPkg/Library/JsonLib/jansson_private_config.h b/RedfishPkg/Library/JsonLib/jansson_private_config.h
new file mode 100644
index 0000000000..268f91ef8a
--- /dev/null
+++ b/RedfishPkg/Library/JsonLib/jansson_private_config.h
@@ -0,0 +1,19 @@
+/** @file
+  Jansson private configurations for UEFI support.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef JANSSON_PRIVATE_CONFIG_H_
+#define JANSSON_PRIVATE_CONFIG_H_
+
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+
+#define INITIAL_HASHTABLE_ORDER 3
+
+#endif
diff --git a/RedfishPkg/Library/JsonLib/JsonLib.c b/RedfishPkg/Library/JsonLib/JsonLib.c
new file mode 100644
index 0000000000..52a7dcc581
--- /dev/null
+++ b/RedfishPkg/Library/JsonLib/JsonLib.c
@@ -0,0 +1,964 @@
+/** @file
+  APIs for JSON operations.
+
+  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Uefi.h>
+#include <Library/JsonLib.h>
+#include <Library/BaseUcs2Utf8Lib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "jansson.h"
+
+/**
+  The function is used to convert a NULL terminated UTF8 encoded string to a JSON
+  value. Only object and array represented strings can be converted successfully,
+  since they are the only valid root values of a JSON text for UEFI usage.
+
+  Real number and number with exponent part are not supportted by UEFI.
+
+  Caller needs to cleanup the root value by calling JsonValueFree().
+
+  @param[in]   Text             The NULL terminated UTF8 encoded string to convert
+
+  @retval      Array JSON value or object JSON value, or NULL when any error occurs.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+TextToJson (
+  IN    CHAR8*    Text
+  )
+{
+  json_error_t    JsonError;
+
+  return (EDKII_JSON_VALUE) json_loads (Text, 0, &JsonError);
+}
+
+/**
+  The function is used to convert the JSON root value to a UTF8 encoded string which
+  is terminated by NULL, or return NULL on error.
+
+  Only array JSON value or object JSON value is valid for converting, and caller is
+  responsible for free converted string.
+
+  @param[in]   Json               The JSON value to be converted
+
+  @retval      The JSON value converted UTF8 string or NULL.
+
+**/
+CHAR8*
+EFIAPI
+JsonToText (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  if (!JsonValueIsArray (Json) && !JsonValueIsObject (Json)) {
+    return NULL;
+  }
+
+  return json_dumps ((json_t *)Json, 0);
+}
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON array,
+  or NULL on error. Initially, the array is empty.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @retval      The created JSON value which contains a JSON array or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitArray (
+  VOID
+  )
+{
+  return (EDKII_JSON_VALUE)json_array();
+}
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON object,
+  or NULL on error. Initially, the object is empty.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @retval      The created JSON value which contains a JSON object or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitObject (
+  VOID
+  )
+{
+  return (EDKII_JSON_VALUE)json_object();
+}
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON string,
+  or NULL on error.
+
+  The input string must be NULL terminated Ascii format, non-Ascii characters will
+  be processed as an error. Unicode characters can also be represented by Ascii string
+  as the format: \u + 4 hexadecimal digits, like \u3E5A, or \u003F.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   String      The Ascii string to initialize to JSON value
+
+  @retval      The created JSON value which contains a JSON string or NULL. Select a
+               Getter API for a specific encoding format.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitAsciiString (
+  IN    CONST CHAR8    *String
+  )
+{
+  UINTN    Index;
+
+  if (String == NULL) {
+    return NULL;
+  }
+
+  Index = 0;
+  while (*(String + Index) != '\0') {
+    if (((*(String + Index)) & 0x80) != 0x00) {
+      return NULL;
+    }
+
+    Index++;
+  }
+
+  return (EDKII_JSON_VALUE)json_string (String);
+}
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON string,
+  or NULL on error.
+
+  The input must be a NULL terminated UCS2 format Unicode string.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   String      The Unicode string to initialize to JSON value
+
+  @retval      The created JSON value which contains a JSON string or NULL. Select a
+               Getter API for a specific encoding format.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitUnicodeString (
+  IN    CHAR16    *String
+  )
+{
+  EFI_STATUS    Status;
+  CHAR8         *Utf8Str;
+
+  if (String == NULL) {
+    return NULL;
+  }
+
+  Utf8Str = NULL;
+  Status  = UCS2StrToUTF8 (String, &Utf8Str);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  return (EDKII_JSON_VALUE)json_string (Utf8Str);
+}
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON integer,
+  or NULL on error.
+
+  The reference count of this value will be set to 1, and caller needs to cleanup the
+  value by calling JsonValueFree().
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   Value       The integer to initialize to JSON value
+
+  @retval      The created JSON value which contains a JSON number or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitNumber (
+  IN    INT64    Value
+  )
+{
+  return (EDKII_JSON_VALUE)json_integer (Value);
+}
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON boolean,
+  or NULL on error.
+
+  Boolean JSON value is kept as static value, and no need to do any cleanup work.
+
+  @param[in]   Value       The boolean value to initialize.
+
+  @retval      The created JSON value which contains a JSON boolean or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitBoolean (
+  IN    BOOLEAN    Value
+  )
+{
+  return (EDKII_JSON_VALUE)json_boolean (Value);
+}
+
+/**
+  The function is used to initialize a JSON value which contains a new JSON NULL,
+  or NULL on error.
+
+  NULL JSON value is kept as static value, and no need to do any cleanup work.
+
+  @retval      The created NULL JSON value.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueInitNull (
+  VOID
+  )
+{
+  return (EDKII_JSON_VALUE)json_null();
+}
+
+/**
+  The function is used to decrease the reference count of a JSON value by one, and once
+  this reference count drops to zero, the value is destroyed and it can no longer be used.
+  If this destroyed value is object type or array type, reference counts for all containing
+  JSON values will be decreased by 1. Boolean JSON value and NULL JSON value won't be destroyed
+  since they are static values kept in memory.
+
+  Reference Count Strategy: BaseJsonLib uses this strategy to track whether a value is still
+  in use or not. When a value is created, it's reference count is set to 1. If a reference to a
+  value is kept for use, its reference count is incremented, and when the value is no longer
+  needed, the reference count is decremented. When the reference count drops to zero, there are
+  no references left, and the value can be destroyed.
+
+  The given JSON value maybe NULL and not causing any problem. Just output the debug message
+  to inform caller the NULL value is passed in.
+
+  @param[in]   Json             The JSON value to be freed. json_decref may return without any
+                                changes if Json is NULL.
+
+**/
+VOID
+EFIAPI
+JsonValueFree (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  json_decref((json_t *)Json);
+}
+
+/**
+  The function is used to create a fresh copy of a JSON value, and all child values are deep
+  copied in a recursive fashion. It should be called when this JSON value might be modified
+  in later use, but the original still wants to be used in somewhere else.
+
+  Reference counts of the returned root JSON value and all child values will be set to 1, and
+  caller needs to cleanup the root value by calling JsonValueFree().
+
+  * Note: Since this function performs a copy from bottom to up, too many calls may cause some
+  performance issues, user should avoid unnecessary calls to this function unless it is really
+  needed.
+
+  @param[in]   Json             The JSON value to be cloned.
+
+  @retval      Return the cloned JSON value, or NULL on error.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonValueClone (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return (EDKII_JSON_VALUE)json_deep_copy ((json_t *) Json);
+}
+
+/**
+  The function is used to return if the provided JSON value contains a JSON array.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON array.
+  @retval      FALSE            The JSON value doesn't contain a JSON array.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsArray (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return json_is_array ((json_t *) Json);
+}
+
+/**
+  The function is used to return if the provided JSON value contains a JSON object.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON object.
+  @retval      FALSE            The JSON value doesn't contain a JSON object.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsObject (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return json_is_object ((json_t *) Json);
+}
+
+/**
+  The function is used to return if the provided JSON Value contains a string, Ascii or
+  Unicode format is not differentiated.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON string.
+  @retval      FALSE            The JSON value doesn't contain a JSON string.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsString (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return json_is_string ((json_t *) Json);
+}
+
+/**
+  The function is used to return if the provided JSON value contains a JSON number.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value is contains JSON number.
+  @retval      FALSE            The JSON value doesn't contain a JSON number.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsNumber (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return json_is_integer ((json_t *) Json);
+}
+
+/**
+  The function is used to return if the provided JSON value contains a JSON boolean.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON boolean.
+  @retval      FALSE            The JSON value doesn't contain a JSON boolean.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsBoolean (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return json_is_boolean ((json_t *) Json);
+}
+
+/**
+  The function is used to return if the provided JSON value contains a JSON NULL.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      TRUE             The JSON value contains a JSON NULL.
+  @retval      FALSE            The JSON value doesn't contain a JSON NULL.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueIsNull (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return json_is_null ((json_t *) Json);
+}
+
+/**
+  The function is used to retrieve the associated array in an array type JSON value.
+
+  Any changes to the returned array will impact the original JSON value.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated array in JSON value or NULL.
+
+**/
+EDKII_JSON_ARRAY
+EFIAPI
+JsonValueGetArray (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  if (Json == NULL || !JsonValueIsArray (Json)) {
+    return NULL;
+  }
+
+  return (EDKII_JSON_ARRAY)Json;
+}
+
+/**
+  The function is used to retrieve the associated object in an object type JSON value.
+
+  Any changes to the returned object will impact the original JSON value.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated object in JSON value or NULL.
+
+**/
+EDKII_JSON_OBJECT
+EFIAPI
+JsonValueGetObject (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  if (Json == NULL || !JsonValueIsObject (Json)) {
+    return NULL;
+  }
+
+  return (EDKII_JSON_OBJECT)Json;
+}
+
+/**
+  The function is used to retrieve the associated Ascii string in a string type JSON value.
+
+  Any changes to the returned string will impact the original JSON value.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated Ascii string in JSON value or NULL.
+
+**/
+CHAR8*
+EFIAPI
+JsonValueGetAsciiString (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  CHAR8          *AsciiStr;
+  UINTN          Index;
+
+  AsciiStr = (CHAR8 *)  ((json_t *) Json);
+  if (AsciiStr == NULL) {
+    return NULL;
+  }
+
+  Index = 0;
+  while (*(AsciiStr + Index) != '\0') {
+    if (((*(AsciiStr + Index)) & 0x80) != 0x00) {
+      return NULL;
+    }
+
+    Index++;
+  }
+
+  return AsciiStr;
+}
+
+/**
+  The function is used to retrieve the associated Unicode string in a string type JSON value.
+
+  Caller can do any changes to the returned string without any impact to the original JSON
+  value, and caller needs to free the returned string.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated Unicode string in JSON value or NULL.
+
+**/
+CHAR16*
+EFIAPI
+JsonValueGetUnicodeString (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  EFI_STATUS     Status;
+  CONST CHAR8    *Utf8Str;
+  CHAR16         *Ucs2Str;
+
+  Utf8Str = json_string_value ((json_t *) Json);
+  if (Utf8Str == NULL) {
+    return NULL;
+  }
+
+  Status = UTF8StrToUCS2 ((CHAR8*)Utf8Str, &Ucs2Str);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+
+  return Ucs2Str;
+}
+
+/**
+  The function is used to retrieve the associated integer in a number type JSON value.
+
+  The input JSON value should not be NULL or contain no JSON number, otherwise it will
+  ASSERT() and return 0.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated number in JSON value.
+
+**/
+INT64
+EFIAPI
+JsonValueGetNumber (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  ASSERT (Json != NULL && JsonValueIsNumber (Json));
+  if (Json == NULL || !JsonValueIsNumber (Json)) {
+    return 0;
+  }
+
+  return json_integer_value ((json_t *) Json);
+}
+
+/**
+  The function is used to retrieve the associated boolean in a boolean type JSON value.
+
+  The input JSON value should not be NULL or contain no JSON boolean, otherwise it will
+  ASSERT() and return FALSE.
+
+  @param[in]   Json             The provided JSON value.
+
+  @retval      Return the associated value of JSON boolean.
+
+**/
+BOOLEAN
+EFIAPI
+JsonValueGetBoolean (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  ASSERT (Json != NULL && JsonValueIsBoolean (Json));
+  if (Json == NULL || !JsonValueIsBoolean (Json)) {
+    return FALSE;
+  }
+
+  return json_is_true ((json_t *) Json);
+}
+
+/**
+  The function is used to retrieve the associated string in a string type JSON value.
+
+  Any changes to the returned string will impact the original JSON value.
+
+  @param[in]   Json The provided JSON value.
+
+  @retval      Return the associated Ascii string in JSON value or NULL.
+
+**/
+CONST CHAR8*
+EFIAPI
+JsonValueGetString (
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  return json_string_value ((const json_t *)Json);
+}
+
+/**
+  The function is used to get the number of elements in a JSON object, or 0 if it is NULL or
+  not a JSON object.
+
+  @param[in]   JsonObject              The provided JSON object.
+
+  @retval      Return the number of elements in this JSON object or 0.
+
+**/
+UINTN
+EFIAPI
+JsonObjectSize (
+  IN    EDKII_JSON_OBJECT    JsonObject
+  )
+{
+  return json_object_size ((json_t *) JsonObject);
+}
+
+/**
+  The function is used to enumerate all keys in a JSON object.
+
+  Caller should be responsible to free the returned key array refference. But contained keys
+  are read only and must not be modified or freed.
+
+  @param[in]   JsonObj                The provided JSON object for enumeration.
+  @param[out]  KeyCount               The count of keys in this JSON object.
+
+  @retval      Return an array of the enumerated keys in this JSON object or NULL.
+
+**/
+CHAR8**
+JsonObjectGetKeys (
+  IN    EDKII_JSON_OBJECT    JsonObj,
+  OUT   UINTN                *KeyCount
+  )
+{
+
+  UINTN               Index;
+  CONST CHAR8         **KeyArray;
+  CONST CHAR8         *Key;
+  EDKII_JSON_VALUE    Value;
+
+  if (JsonObj == NULL || KeyCount == NULL) {
+    return NULL;
+  }
+
+  Index = 0;
+  json_object_foreach(JsonObj, Key, Value) {
+    Index++;
+  }
+  if (Index == 0) {
+    *KeyCount = 0;
+    return NULL;
+  }
+
+  *KeyCount = Index;
+  KeyArray = (CONST CHAR8 **) AllocateZeroPool (*KeyCount * sizeof (CHAR8 *));
+  if (KeyArray == NULL) {
+    return NULL;
+  }
+
+  Key   = NULL;
+  Value = NULL;
+  Index = 0;
+  json_object_foreach((json_t *) JsonObj, Key, Value) {
+    KeyArray[Index] = Key;
+    Index++;
+  }
+
+  return (CHAR8 **)KeyArray;
+}
+
+/**
+  The function is used to get a JSON value corresponding to the input key from a JSON object.
+
+  It only returns a reference to this value and any changes on this value will impact the
+  original JSON object. If that is not expected, please call JsonValueClone() to clone it to
+  use.
+
+  Input key must be a valid NULL terminated UTF8 encoded string. NULL will be returned when
+  Key-Value is not found in this JSON object.
+
+  @param[in]   JsonObj           The provided JSON object.
+  @param[in]   Key               The key of the JSON value to be retrieved.
+
+  @retval      Return the corresponding JSON value to key, or NULL on error.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonObjectGetValue (
+  IN    CONST EDKII_JSON_OBJECT    JsonObj,
+  IN    CONST CHAR8                *Key
+  )
+{
+  return (EDKII_JSON_VALUE)json_object_get ((const json_t *)JsonObj, (const char *)Key);
+}
+
+/**
+  The function is used to set a JSON value corresponding to the input key from a JSON object,
+  and the reference count of this value will be increased by 1.
+
+  Input key must be a valid NULL terminated UTF8 encoded string. If there already is a value for
+  this key, this key will be assigned to the new JSON value. The old JSON value will be removed
+  from this object and thus its' reference count will be decreased by 1.
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   JsonObj                The provided JSON object.
+  @param[in]   Key                    The key of the JSON value to be set.
+  @param[in]   Json                   The JSON value to set to this JSON object mapped by key.
+
+  @retval      EFI_ABORTED            Some error occur and operation aborted.
+  @retval      EFI_SUCCESS            The JSON value has been set to this JSON object.
+
+**/
+EFI_STATUS
+EFIAPI
+JsonObjectSetValue (
+  IN    EDKII_JSON_OBJECT    JsonObj,
+  IN    CONST CHAR8          *Key,
+  IN    EDKII_JSON_VALUE     Json
+  )
+{
+  if (json_object_set ((json_t *) JsonObj, Key, (json_t *) Json) != 0) {
+    return EFI_ABORTED;
+  } else {
+    return EFI_SUCCESS;
+  }
+}
+
+/**
+  The function is used to get the number of elements in a JSON array, or 0 if it is NULL or
+  not a JSON array.
+
+  @param[in]   JsonArray              The provided JSON array.
+
+  @retval      Return the number of elements in this JSON array or 0.
+
+**/
+UINTN
+EFIAPI
+JsonArrayCount (
+  IN    EDKII_JSON_ARRAY    JsonArray
+  )
+{
+  return json_array_size ((json_t *) JsonArray);
+}
+
+/**
+  The function is used to return the JSON value in the array at position index. The valid range
+  for this index is from 0 to the return value of JsonArrayCount() minus 1.
+
+  It only returns a reference to this value and any changes on this value will impact the
+  original JSON object. If that is not expected, please call JsonValueClone() to clone it to
+  use.
+
+  If this array is NULL or not a JSON array, or if index is out of range, NULL will be returned.
+
+  @param[in]   JsonArray         The provided JSON Array.
+
+  @retval      Return the JSON value located in the Index position or NULL.
+
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonArrayGetValue (
+  IN    EDKII_JSON_ARRAY    JsonArray,
+  IN    UINTN               Index
+  )
+{
+  return (EDKII_JSON_VALUE)json_array_get ((json_t *) JsonArray, Index);
+}
+
+/**
+  The function is used to append a JSON value to the end of the JSON array, and grow the size of
+  array by 1. The reference count of this value will be increased by 1.
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   JsonArray              The provided JSON object.
+  @param[in]   Json                   The JSON value to append.
+
+  @retval      EFI_ABORTED            Some error occur and operation aborted.
+  @retval      EFI_SUCCESS            JSON value has been appended to the end of the JSON array.
+
+**/
+EFI_STATUS
+EFIAPI
+JsonArrayAppendValue (
+  IN    EDKII_JSON_ARRAY    JsonArray,
+  IN    EDKII_JSON_VALUE    Json
+  )
+{
+  if (json_array_append ((json_t *) JsonArray, (json_t *) Json) != 0) {
+    return EFI_ABORTED;
+  } else {
+    return EFI_SUCCESS;
+  }
+}
+
+/**
+  The function is used to remove a JSON value at position index, shifting the elements after index
+  one position towards the start of the array. The reference count of this value will be decreased
+  by 1.
+
+  More details for reference count strategy can refer to the API description for JsonValueFree().
+
+  @param[in]   JsonArray              The provided JSON array.
+  @param[in]   Index                  The Index position before removement.
+
+  @retval      EFI_ABORTED            Some error occur and operation aborted.
+  @retval      EFI_SUCCESS            The JSON array has been removed at position index.
+
+**/
+EFI_STATUS
+EFIAPI
+JsonArrayRemoveValue (
+  IN    EDKII_JSON_ARRAY    JsonArray,
+  IN    UINTN               Index
+  )
+{
+  if (json_array_remove ((json_t *) JsonArray, Index) != 0) {
+    return EFI_ABORTED;
+  } else {
+    return EFI_SUCCESS;
+  }
+}
+
+/**
+  Dump JSON to a buffer.
+
+  @param[in]   JsonValue       The provided JSON array.
+  @param[in]   Flags           The Index position before removement.
+
+  @retval      NULL            Dump fail if NULL returned, otherwise the buffer
+                               contain JSON paylaod in ASCII string.
+**/
+CHAR8 *
+EFIAPI
+JsonDumpString (
+  IN    EDKII_JSON_ARRAY    JsonValue,
+  IN    UINTN               Flags
+  )
+{
+    if (JsonValue == NULL) {
+      return NULL;
+    }
+    return json_dumps((json_t *)JsonValue, Flags);
+}
+
+/**
+  Load JSON from a buffer.
+
+  @param[in]   Buffer        Bufffer to the JSON payload
+  @param[in]   BufferLen     Length of the buffer
+  @param[in]   Flags         Flag of loading JSON buffer
+  @param[in]   Error         Pointer to error structure
+
+  @retval      EDKII_JSON_VALUE  NULL means fail to load JSON payload.
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonLoadBuffer (
+  IN    CONST CHAR8       *Buffer,
+  IN    UINTN             BufferLen,
+  IN    UINTN             Flags,
+  IN    EDKII_JSON_ERROR  *Error
+  )
+{
+  return json_loadb(Buffer, BufferLen, Flags, (json_error_t *)Error);
+}
+
+/**
+  Decrease reference.
+
+  @param[in]   JsonValue      JSON value
+**/
+VOID
+EFIAPI
+JsonDecreaseReference (
+  IN EDKII_JSON_VALUE JsonValue
+  )
+{
+  json_decref (JsonValue);
+}
+
+/**
+  Increase reference.
+
+  @param[in]   JsonValue      JSON value
+  @retval      EDKII_JSON_VALUE of itself
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonIncreaseReference (
+  IN EDKII_JSON_VALUE JsonValue
+  )
+{
+  return json_incref (JsonValue);
+}
+
+/**
+  Returns an opaque iterator which can be used to iterate over all key-value pairs
+  in object, or NULL if object is empty.
+
+  @param[in]   JsonValue      JSON value
+  @retval      Iterator pointer
+**/
+VOID *
+EFIAPI
+JsonObjectIterator (
+  IN EDKII_JSON_VALUE JsonValue
+  )
+{
+  return json_object_iter (JsonValue);
+}
+
+/**
+  Extract the associated value from iterator.
+
+  @param[in]   Iterator   Iterator pointer
+  @retval      EDKII_JSON_VALUE
+**/
+EDKII_JSON_VALUE
+EFIAPI
+JsonObjectIteratorValue (
+  IN VOID *Iterator
+  )
+{
+  return json_object_iter_value(Iterator);
+}
+
+/**
+  Returns an iterator pointing to the next key-value pair in object after iter,
+  or NULL if the whole object has been iterated through.
+
+  @param[in]   JsonValue  JSON value
+  @param[in]   Iterator   Iterator pointer
+  @retval      Iterator pointer
+**/
+VOID *
+JsonObjectIteratorNext (
+  IN EDKII_JSON_VALUE JsonValue,
+  IN VOID             *Iterator
+  )
+{
+  return json_object_iter_next(JsonValue, Iterator);
+}
+
+/**
+  Returns the json type of this json value.
+
+  @param[in]   JsonValue  JSON value
+  @retval      JSON type returned
+**/
+EDKII_JSON_TYPE
+EFIAPI
+JsonGetType (
+  IN EDKII_JSON_VALUE JsonValue
+  )
+{
+  return ((json_t *)JsonValue)->type;
+}
diff --git a/RedfishPkg/Library/JsonLib/load.c b/RedfishPkg/Library/JsonLib/load.c
new file mode 100644
index 0000000000..37e0ba4271
--- /dev/null
+++ b/RedfishPkg/Library/JsonLib/load.c
@@ -0,0 +1,1111 @@
+/*
+ * Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
+ *
+ * Jansson is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
+
+    SPDX-License-Identifier: BSD-2-Clause-Patent AND MIT
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include "jansson_private.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "jansson.h"
+#include "strbuffer.h"
+#include "utf.h"
+
+#define STREAM_STATE_OK    0
+#define STREAM_STATE_EOF   -1
+#define STREAM_STATE_ERROR -2
+
+#define TOKEN_INVALID -1
+#define TOKEN_EOF     0
+#define TOKEN_STRING  256
+#define TOKEN_INTEGER 257
+#define TOKEN_REAL    258
+#define TOKEN_TRUE    259
+#define TOKEN_FALSE   260
+#define TOKEN_NULL    261
+
+/* Locale independent versions of isxxx() functions */
+#define l_isupper(c) ('A' <= (c) && (c) <= 'Z')
+#define l_islower(c) ('a' <= (c) && (c) <= 'z')
+#define l_isalpha(c) (l_isupper(c) || l_islower(c))
+#define l_isdigit(c) ('0' <= (c) && (c) <= '9')
+#define l_isxdigit(c)                                                                    \
+    (l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))
+
+/* Read one byte from stream, convert to unsigned char, then int, and
+   return. return EOF on end of file. This corresponds to the
+   behaviour of fgetc(). */
+typedef int (*get_func)(void *data);
+
+typedef struct {
+    get_func get;
+    void *data;
+    char buffer[5];
+    size_t buffer_pos;
+    int state;
+    int line;
+    int column, last_column;
+    size_t position;
+} stream_t;
+
+typedef struct {
+    stream_t stream;
+    strbuffer_t saved_text;
+    size_t flags;
+    size_t depth;
+    int token;
+    union {
+        struct {
+            char *val;
+            size_t len;
+        } string;
+        json_int_t integer;
+        double real;
+    } value;
+} lex_t;
+
+#define stream_to_lex(stream) container_of(stream, lex_t, stream)
+
+/*** error reporting ***/
+
+static void error_set(json_error_t *error, const lex_t *lex, enum json_error_code code,
+                      const char *msg, ...) {
+    va_list ap;
+    char msg_text[JSON_ERROR_TEXT_LENGTH];
+    char msg_with_context[JSON_ERROR_TEXT_LENGTH];
+
+    int line = -1, col = -1;
+    size_t pos = 0;
+    const char *result = msg_text;
+
+    if (!error)
+        return;
+
+    va_start(ap, msg);
+    vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap);
+    msg_text[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
+    va_end(ap);
+
+    if (lex) {
+        const char *saved_text = strbuffer_value(&lex->saved_text);
+
+        line = lex->stream.line;
+        col = lex->stream.column;
+        pos = lex->stream.position;
+
+        if (saved_text && saved_text[0]) {
+            if (lex->saved_text.length <= 20) {
+                snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near '%s'",
+                         msg_text, saved_text);
+                msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
+                result = msg_with_context;
+            }
+        } else {
+            if (code == json_error_invalid_syntax) {
+                /* More specific error code for premature end of file. */
+                code = json_error_premature_end_of_input;
+            }
+            if (lex->stream.state == STREAM_STATE_ERROR) {
+                /* No context for UTF-8 decoding errors */
+                result = msg_text;
+            } else {
+                snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH, "%s near end of file",
+                         msg_text);
+                msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
+                result = msg_with_context;
+            }
+        }
+    }
+
+    jsonp_error_set(error, line, col, pos, code, "%s", result);
+}
+
+/*** lexical analyzer ***/
+
+static void stream_init(stream_t *stream, get_func get, void *data) {
+    stream->get = get;
+    stream->data = data;
+    stream->buffer[0] = '\0';
+    stream->buffer_pos = 0;
+
+    stream->state = STREAM_STATE_OK;
+    stream->line = 1;
+    stream->column = 0;
+    stream->position = 0;
+}
+
+static int stream_get(stream_t *stream, json_error_t *error) {
+    int c;
+
+    if (stream->state != STREAM_STATE_OK)
+        return stream->state;
+
+    if (!stream->buffer[stream->buffer_pos]) {
+        c = stream->get(stream->data);
+        if (c == EOF) {
+            stream->state = STREAM_STATE_EOF;
+            return STREAM_STATE_EOF;
+        }
+
+        stream->buffer[0] = c;
+        stream->buffer_pos = 0;
+
+        if (0x80 <= c && c <= 0xFF) {
+            /* multi-byte UTF-8 sequence */
+            size_t i, count;
+
+            count = utf8_check_first(c);
+            if (!count)
+                goto out;
+
+            assert(count >= 2);
+
+            for (i = 1; i < count; i++)
+                stream->buffer[i] = stream->get(stream->data);
+
+            if (!utf8_check_full(stream->buffer, count, NULL))
+                goto out;
+
+            stream->buffer[count] = '\0';
+        } else
+            stream->buffer[1] = '\0';
+    }
+
+    c = stream->buffer[stream->buffer_pos++];
+
+    stream->position++;
+    if (c == '\n') {
+        stream->line++;
+        stream->last_column = stream->column;
+        stream->column = 0;
+    } else if (utf8_check_first(c)) {
+        /* track the Unicode character column, so increment only if
+           this is the first character of a UTF-8 sequence */
+        stream->column++;
+    }
+
+    return c;
+
+out:
+    stream->state = STREAM_STATE_ERROR;
+    error_set(error, stream_to_lex(stream), json_error_invalid_utf8,
+              "unable to decode byte 0x%x", c);
+    return STREAM_STATE_ERROR;
+}
+
+static void stream_unget(stream_t *stream, int c) {
+    if (c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR)
+        return;
+
+    stream->position--;
+    if (c == '\n') {
+        stream->line--;
+        stream->column = stream->last_column;
+    } else if (utf8_check_first(c))
+        stream->column--;
+
+    assert(stream->buffer_pos > 0);
+    stream->buffer_pos--;
+    assert(stream->buffer[stream->buffer_pos] == c);
+}
+
+static int lex_get(lex_t *lex, json_error_t *error) {
+    return stream_get(&lex->stream, error);
+}
+
+static void lex_save(lex_t *lex, int c) { strbuffer_append_byte(&lex->saved_text, c); }
+
+static int lex_get_save(lex_t *lex, json_error_t *error) {
+    int c = stream_get(&lex->stream, error);
+    if (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR)
+        lex_save(lex, c);
+    return c;
+}
+
+static void lex_unget(lex_t *lex, int c) { stream_unget(&lex->stream, c); }
+
+static void lex_unget_unsave(lex_t *lex, int c) {
+    if (c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
+/* Since we treat warnings as errors, when assertions are turned
+ * off the "d" variable would be set but never used. Which is
+ * treated as an error by GCC.
+ */
+#ifndef NDEBUG
+        char d;
+#endif
+        stream_unget(&lex->stream, c);
+#ifndef NDEBUG
+        d =
+#endif
+            strbuffer_pop(&lex->saved_text);
+        assert(c == d);
+    }
+}
+
+static void lex_save_cached(lex_t *lex) {
+    while (lex->stream.buffer[lex->stream.buffer_pos] != '\0') {
+        lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);
+        lex->stream.buffer_pos++;
+        lex->stream.position++;
+    }
+}
+
+static void lex_free_string(lex_t *lex) {
+    jsonp_free(lex->value.string.val);
+    lex->value.string.val = NULL;
+    lex->value.string.len = 0;
+}
+
+/* assumes that str points to 'u' plus at least 4 valid hex digits */
+static int32_t decode_unicode_escape(const char *str) {
+    int i;
+    int32_t value = 0;
+
+    assert(str[0] == 'u');
+
+    for (i = 1; i <= 4; i++) {
+        char c = str[i];
+        value <<= 4;
+        if (l_isdigit(c))
+            value += c - '0';
+        else if (l_islower(c))
+            value += c - 'a' + 10;
+        else if (l_isupper(c))
+            value += c - 'A' + 10;
+        else
+            return -1;
+    }
+
+    return value;
+}
+
+static void lex_scan_string(lex_t *lex, json_error_t *error) {
+    int c;
+    const char *p;
+    char *t;
+    int i;
+
+    lex->value.string.val = NULL;
+    lex->token = TOKEN_INVALID;
+
+    c = lex_get_save(lex, error);
+
+    while (c != '"') {
+        if (c == STREAM_STATE_ERROR)
+            goto out;
+
+        else if (c == STREAM_STATE_EOF) {
+            error_set(error, lex, json_error_premature_end_of_input,
+                      "premature end of input");
+            goto out;
+        }
+
+        else if (0 <= c && c <= 0x1F) {
+            /* control character */
+            lex_unget_unsave(lex, c);
+            if (c == '\n')
+                error_set(error, lex, json_error_invalid_syntax, "unexpected newline");
+            else
+                error_set(error, lex, json_error_invalid_syntax, "control character 0x%x",
+                          c);
+            goto out;
+        }
+
+        else if (c == '\\') {
+            c = lex_get_save(lex, error);
+            if (c == 'u') {
+                c = lex_get_save(lex, error);
+                for (i = 0; i < 4; i++) {
+                    if (!l_isxdigit(c)) {
+                        error_set(error, lex, json_error_invalid_syntax,
+                                  "invalid escape");
+                        goto out;
+                    }
+                    c = lex_get_save(lex, error);
+                }
+            } else if (c == '"' || c == '\\' || c == '/' || c == 'b' || c == 'f' ||
+                       c == 'n' || c == 'r' || c == 't')
+                c = lex_get_save(lex, error);
+            else {
+                error_set(error, lex, json_error_invalid_syntax, "invalid escape");
+                goto out;
+            }
+        } else
+            c = lex_get_save(lex, error);
+    }
+
+    /* the actual value is at most of the same length as the source
+       string, because:
+         - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
+         - a single \uXXXX escape (length 6) is converted to at most 3 bytes
+         - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
+           are converted to 4 bytes
+    */
+    t = jsonp_malloc(lex->saved_text.length + 1);
+    if (!t) {
+        /* this is not very nice, since TOKEN_INVALID is returned */
+        goto out;
+    }
+    lex->value.string.val = t;
+
+    /* + 1 to skip the " */
+    p = strbuffer_value(&lex->saved_text) + 1;
+
+    while (*p != '"') {
+        if (*p == '\\') {
+            p++;
+            if (*p == 'u') {
+                size_t length;
+                int32_t value;
+
+                value = decode_unicode_escape(p);
+                if (value < 0) {
+                    error_set(error, lex, json_error_invalid_syntax,
+                              "invalid Unicode escape '%.6s'", p - 1);
+                    goto out;
+                }
+                p += 5;
+
+                if (0xD800 <= value && value <= 0xDBFF) {
+                    /* surrogate pair */
+                    if (*p == '\\' && *(p + 1) == 'u') {
+                        int32_t value2 = decode_unicode_escape(++p);
+                        if (value2 < 0) {
+                            error_set(error, lex, json_error_invalid_syntax,
+                                      "invalid Unicode escape '%.6s'", p - 1);
+                            goto out;
+                        }
+                        p += 5;
+
+                        if (0xDC00 <= value2 && value2 <= 0xDFFF) {
+                            /* valid second surrogate */
+                            value =
+                                ((value - 0xD800) << 10) + (value2 - 0xDC00) + 0x10000;
+                        } else {
+                            /* invalid second surrogate */
+                            error_set(error, lex, json_error_invalid_syntax,
+                                      "invalid Unicode '\\u%04X\\u%04X'", value, value2);
+                            goto out;
+                        }
+                    } else {
+                        /* no second surrogate */
+                        error_set(error, lex, json_error_invalid_syntax,
+                                  "invalid Unicode '\\u%04X'", value);
+                        goto out;
+                    }
+                } else if (0xDC00 <= value && value <= 0xDFFF) {
+                    error_set(error, lex, json_error_invalid_syntax,
+                              "invalid Unicode '\\u%04X'", value);
+                    goto out;
+                }
+
+                if (utf8_encode(value, t, &length))
+                    assert(0);
+                t += length;
+            } else {
+                switch (*p) {
+                    case '"':
+                    case '\\':
+                    case '/':
+                        *t = *p;
+                        break;
+                    case 'b':
+                        *t = '\b';
+                        break;
+                    case 'f':
+                        *t = '\f';
+                        break;
+                    case 'n':
+                        *t = '\n';
+                        break;
+                    case 'r':
+                        *t = '\r';
+                        break;
+                    case 't':
+                        *t = '\t';
+                        break;
+                    default:
+                        assert(0);
+                }
+                t++;
+                p++;
+            }
+        } else
+            *(t++) = *(p++);
+    }
+    *t = '\0';
+    lex->value.string.len = t - lex->value.string.val;
+    lex->token = TOKEN_STRING;
+    return;
+
+out:
+    lex_free_string(lex);
+}
+
+#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
+#if JSON_INTEGER_IS_LONG_LONG
+#ifdef _MSC_VER /* Microsoft Visual Studio */
+#define json_strtoint _strtoi64
+#else
+#define json_strtoint strtoll
+#endif
+#else
+#define json_strtoint strtol
+#endif
+#endif
+
+static int lex_scan_number(lex_t *lex, int c, json_error_t *error) {
+    const char *saved_text;
+    char *end;
+    double doubleval;
+
+    lex->token = TOKEN_INVALID;
+
+    if (c == '-')
+        c = lex_get_save(lex, error);
+
+    if (c == '0') {
+        c = lex_get_save(lex, error);
+        if (l_isdigit(c)) {
+            lex_unget_unsave(lex, c);
+            goto out;
+        }
+    } else if (l_isdigit(c)) {
+        do
+            c = lex_get_save(lex, error);
+        while (l_isdigit(c));
+    } else {
+        lex_unget_unsave(lex, c);
+        goto out;
+    }
+
+    if (!(lex->flags & JSON_DECODE_INT_AS_REAL) && c != '.' && c != 'E' && c != 'e') {
+        json_int_t intval;
+
+        lex_unget_unsave(lex, c);
+
+        saved_text = strbuffer_value(&lex->saved_text);
+
+        errno = 0;
+        intval = json_strtoint(saved_text, &end, 10);
+        if (errno == ERANGE) {
+            if (intval < 0)
+                error_set(error, lex, json_error_numeric_overflow,
+                          "too big negative integer");
+            else
+                error_set(error, lex, json_error_numeric_overflow, "too big integer");
+            goto out;
+        }
+
+        assert(end == saved_text + lex->saved_text.length);
+
+        lex->token = TOKEN_INTEGER;
+        lex->value.integer = intval;
+        return 0;
+    }
+
+    if (c == '.') {
+        c = lex_get(lex, error);
+        if (!l_isdigit(c)) {
+            lex_unget(lex, c);
+            goto out;
+        }
+        lex_save(lex, c);
+
+        do
+            c = lex_get_save(lex, error);
+        while (l_isdigit(c));
+    }
+
+    if (c == 'E' || c == 'e') {
+        c = lex_get_save(lex, error);
+        if (c == '+' || c == '-')
+            c = lex_get_save(lex, error);
+
+        if (!l_isdigit(c)) {
+            lex_unget_unsave(lex, c);
+            goto out;
+        }
+
+        do
+            c = lex_get_save(lex, error);
+        while (l_isdigit(c));
+    }
+
+    lex_unget_unsave(lex, c);
+
+    if (jsonp_strtod(&lex->saved_text, &doubleval)) {
+        error_set(error, lex, json_error_numeric_overflow, "real number overflow");
+        goto out;
+    }
+
+    lex->token = TOKEN_REAL;
+    lex->value.real = doubleval;
+    return 0;
+
+out:
+    return -1;
+}
+
+static int lex_scan(lex_t *lex, json_error_t *error) {
+    int c;
+
+    strbuffer_clear(&lex->saved_text);
+
+    if (lex->token == TOKEN_STRING)
+        lex_free_string(lex);
+
+    do
+        c = lex_get(lex, error);
+    while (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+
+    if (c == STREAM_STATE_EOF) {
+        lex->token = TOKEN_EOF;
+        goto out;
+    }
+
+    if (c == STREAM_STATE_ERROR) {
+        lex->token = TOKEN_INVALID;
+        goto out;
+    }
+
+    lex_save(lex, c);
+
+    if (c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')
+        lex->token = c;
+
+    else if (c == '"')
+        lex_scan_string(lex, error);
+
+    else if (l_isdigit(c) || c == '-') {
+        if (lex_scan_number(lex, c, error))
+            goto out;
+    }
+
+    else if (l_isalpha(c)) {
+        /* eat up the whole identifier for clearer error messages */
+        const char *saved_text;
+
+        do
+            c = lex_get_save(lex, error);
+        while (l_isalpha(c));
+        lex_unget_unsave(lex, c);
+
+        saved_text = strbuffer_value(&lex->saved_text);
+
+        if (strcmp(saved_text, "true") == 0)
+            lex->token = TOKEN_TRUE;
+        else if (strcmp(saved_text, "false") == 0)
+            lex->token = TOKEN_FALSE;
+        else if (strcmp(saved_text, "null") == 0)
+            lex->token = TOKEN_NULL;
+        else
+            lex->token = TOKEN_INVALID;
+    }
+
+    else {
+        /* save the rest of the input UTF-8 sequence to get an error
+           message of valid UTF-8 */
+        lex_save_cached(lex);
+        lex->token = TOKEN_INVALID;
+    }
+
+out:
+    return lex->token;
+}
+
+static char *lex_steal_string(lex_t *lex, size_t *out_len) {
+    char *result = NULL;
+    if (lex->token == TOKEN_STRING) {
+        result = lex->value.string.val;
+        *out_len = lex->value.string.len;
+        lex->value.string.val = NULL;
+        lex->value.string.len = 0;
+    }
+    return result;
+}
+
+static int lex_init(lex_t *lex, get_func get, size_t flags, void *data) {
+    stream_init(&lex->stream, get, data);
+    if (strbuffer_init(&lex->saved_text))
+        return -1;
+
+    lex->flags = flags;
+    lex->token = TOKEN_INVALID;
+    return 0;
+}
+
+static void lex_close(lex_t *lex) {
+    if (lex->token == TOKEN_STRING)
+        lex_free_string(lex);
+    strbuffer_close(&lex->saved_text);
+}
+
+/*** parser ***/
+
+static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error);
+
+static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error) {
+    json_t *object = json_object();
+    if (!object)
+        return NULL;
+
+    lex_scan(lex, error);
+    if (lex->token == '}')
+        return object;
+
+    while (1) {
+        char *key;
+        size_t len;
+        json_t *value;
+
+        if (lex->token != TOKEN_STRING) {
+            error_set(error, lex, json_error_invalid_syntax, "string or '}' expected");
+            goto error;
+        }
+
+        key = lex_steal_string(lex, &len);
+        if (!key)
+            return NULL;
+        if (memchr(key, '\0', len)) {
+            jsonp_free(key);
+            error_set(error, lex, json_error_null_byte_in_key,
+                      "NUL byte in object key not supported");
+            goto error;
+        }
+
+        if (flags & JSON_REJECT_DUPLICATES) {
+            if (json_object_get(object, key)) {
+                jsonp_free(key);
+                error_set(error, lex, json_error_duplicate_key, "duplicate object key");
+                goto error;
+            }
+        }
+
+        lex_scan(lex, error);
+        if (lex->token != ':') {
+            jsonp_free(key);
+            error_set(error, lex, json_error_invalid_syntax, "':' expected");
+            goto error;
+        }
+
+        lex_scan(lex, error);
+        value = parse_value(lex, flags, error);
+        if (!value) {
+            jsonp_free(key);
+            goto error;
+        }
+
+        if (json_object_set_new_nocheck(object, key, value)) {
+            jsonp_free(key);
+            goto error;
+        }
+
+        jsonp_free(key);
+
+        lex_scan(lex, error);
+        if (lex->token != ',')
+            break;
+
+        lex_scan(lex, error);
+    }
+
+    if (lex->token != '}') {
+        error_set(error, lex, json_error_invalid_syntax, "'}' expected");
+        goto error;
+    }
+
+    return object;
+
+error:
+    json_decref(object);
+    return NULL;
+}
+
+static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error) {
+    json_t *array = json_array();
+    if (!array)
+        return NULL;
+
+    lex_scan(lex, error);
+    if (lex->token == ']')
+        return array;
+
+    while (lex->token) {
+        json_t *elem = parse_value(lex, flags, error);
+        if (!elem)
+            goto error;
+
+        if (json_array_append_new(array, elem)) {
+            goto error;
+        }
+
+        lex_scan(lex, error);
+        if (lex->token != ',')
+            break;
+
+        lex_scan(lex, error);
+    }
+
+    if (lex->token != ']') {
+        error_set(error, lex, json_error_invalid_syntax, "']' expected");
+        goto error;
+    }
+
+    return array;
+
+error:
+    json_decref(array);
+    return NULL;
+}
+
+static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error) {
+    json_t *json;
+
+    lex->depth++;
+    if (lex->depth > JSON_PARSER_MAX_DEPTH) {
+        error_set(error, lex, json_error_stack_overflow, "maximum parsing depth reached");
+        return NULL;
+    }
+
+    switch (lex->token) {
+        case TOKEN_STRING: {
+            const char *value = lex->value.string.val;
+            size_t len = lex->value.string.len;
+
+            if (!(flags & JSON_ALLOW_NUL)) {
+                if (memchr(value, '\0', len)) {
+                    error_set(error, lex, json_error_null_character,
+                              "\\u0000 is not allowed without JSON_ALLOW_NUL");
+                    return NULL;
+                }
+            }
+
+            json = jsonp_stringn_nocheck_own(value, len);
+            lex->value.string.val = NULL;
+            lex->value.string.len = 0;
+            break;
+        }
+
+        case TOKEN_INTEGER: {
+            json = json_integer(lex->value.integer);
+            break;
+        }
+
+        case TOKEN_REAL: {
+            json = json_real(lex->value.real);
+            break;
+        }
+
+        case TOKEN_TRUE:
+            json = json_true();
+            break;
+
+        case TOKEN_FALSE:
+            json = json_false();
+            break;
+
+        case TOKEN_NULL:
+            json = json_null();
+            break;
+
+        case '{':
+            json = parse_object(lex, flags, error);
+            break;
+
+        case '[':
+            json = parse_array(lex, flags, error);
+            break;
+
+        case TOKEN_INVALID:
+            error_set(error, lex, json_error_invalid_syntax, "invalid token");
+            return NULL;
+
+        default:
+            error_set(error, lex, json_error_invalid_syntax, "unexpected token");
+            return NULL;
+    }
+
+    if (!json)
+        return NULL;
+
+    lex->depth--;
+    return json;
+}
+
+static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) {
+    json_t *result;
+
+    lex->depth = 0;
+
+    lex_scan(lex, error);
+    if (!(flags & JSON_DECODE_ANY)) {
+        if (lex->token != '[' && lex->token != '{') {
+            error_set(error, lex, json_error_invalid_syntax, "'[' or '{' expected");
+            return NULL;
+        }
+    }
+
+    result = parse_value(lex, flags, error);
+    if (!result)
+        return NULL;
+
+    if (!(flags & JSON_DISABLE_EOF_CHECK)) {
+        lex_scan(lex, error);
+        if (lex->token != TOKEN_EOF) {
+            error_set(error, lex, json_error_end_of_input_expected,
+                      "end of file expected");
+            json_decref(result);
+            return NULL;
+        }
+    }
+
+    if (error) {
+        /* Save the position even though there was no error */
+        error->position = (int)lex->stream.position;
+    }
+
+    return result;
+}
+
+typedef struct {
+    const char *data;
+    size_t pos;
+} string_data_t;
+
+static int string_get(void *data) {
+    char c;
+    string_data_t *stream = (string_data_t *)data;
+    c = stream->data[stream->pos];
+    if (c == '\0')
+        return EOF;
+    else {
+        stream->pos++;
+        return (unsigned char)c;
+    }
+}
+
+json_t *json_loads(const char *string, size_t flags, json_error_t *error) {
+    lex_t lex;
+    json_t *result;
+    string_data_t stream_data;
+
+    jsonp_error_init(error, "<string>");
+
+    if (string == NULL) {
+        error_set(error, NULL, json_error_invalid_argument, "wrong arguments");
+        return NULL;
+    }
+
+    stream_data.data = string;
+    stream_data.pos = 0;
+
+    if (lex_init(&lex, string_get, flags, (void *)&stream_data))
+        return NULL;
+
+    result = parse_json(&lex, flags, error);
+
+    lex_close(&lex);
+    return result;
+}
+
+typedef struct {
+    const char *data;
+    size_t len;
+    size_t pos;
+} buffer_data_t;
+
+static int buffer_get(void *data) {
+    char c;
+    buffer_data_t *stream = data;
+    if (stream->pos >= stream->len)
+        return EOF;
+
+    c = stream->data[stream->pos];
+    stream->pos++;
+    return (unsigned char)c;
+}
+
+json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) {
+    lex_t lex;
+    json_t *result;
+    buffer_data_t stream_data;
+
+    jsonp_error_init(error, "<buffer>");
+
+    if (buffer == NULL) {
+        error_set(error, NULL, json_error_invalid_argument, "wrong arguments");
+        return NULL;
+    }
+
+    stream_data.data = buffer;
+    stream_data.pos = 0;
+    stream_data.len = buflen;
+
+    if (lex_init(&lex, buffer_get, flags, (void *)&stream_data))
+        return NULL;
+
+    result = parse_json(&lex, flags, error);
+
+    lex_close(&lex);
+    return result;
+}
+
+json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) {
+    lex_t lex;
+    const char *source;
+    json_t *result;
+#ifdef HAVE_UNISTD_H
+    if (input == stdin)
+        source = "<stdin>";
+    else
+#endif
+        source = "<stream>";
+
+    jsonp_error_init(error, source);
+
+    if (input == NULL) {
+        error_set(error, NULL, json_error_invalid_argument, "wrong arguments");
+        return NULL;
+    }
+
+    if (lex_init(&lex, (get_func)fgetc, flags, input))
+        return NULL;
+
+    result = parse_json(&lex, flags, error);
+
+    lex_close(&lex);
+    return result;
+}
+
+static int fd_get_func(int *fd) {
+#ifdef HAVE_UNISTD_H
+    uint8_t c;
+    if (read(*fd, &c, 1) == 1)
+        return c;
+#endif
+    return EOF;
+}
+
+json_t *json_loadfd(int input, size_t flags, json_error_t *error) {
+    lex_t lex;
+    const char *source;
+    json_t *result;
+
+#ifdef HAVE_UNISTD_H
+    if (input == STDIN_FILENO)
+        source = "<stdin>";
+    else
+#endif
+        source = "<stream>";
+
+    jsonp_error_init(error, source);
+
+    if (input < 0) {
+        error_set(error, NULL, json_error_invalid_argument, "wrong arguments");
+        return NULL;
+    }
+
+    if (lex_init(&lex, (get_func)fd_get_func, flags, &input))
+        return NULL;
+
+    result = parse_json(&lex, flags, error);
+
+    lex_close(&lex);
+    return result;
+}
+
+json_t *json_load_file(const char *path, size_t flags, json_error_t *error) {
+    json_t *result;
+    FILE *fp;
+
+    jsonp_error_init(error, path);
+
+    if (path == NULL) {
+        error_set(error, NULL, json_error_invalid_argument, "wrong arguments");
+        return NULL;
+    }
+
+    fp = fopen(path, "rb");
+    if (!fp) {
+        error_set(error, NULL, json_error_cannot_open_file, "unable to open %s: %s", path,
+                  strerror(errno));
+        return NULL;
+    }
+
+    result = json_loadf(fp, flags, error);
+
+    fclose(fp);
+    return result;
+}
+
+#define MAX_BUF_LEN 1024
+
+typedef struct {
+    char data[MAX_BUF_LEN];
+    size_t len;
+    size_t pos;
+    json_load_callback_t callback;
+    void *arg;
+} callback_data_t;
+
+static int callback_get(void *data) {
+    char c;
+    callback_data_t *stream = data;
+
+    if (stream->pos >= stream->len) {
+        stream->pos = 0;
+        stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg);
+        if (stream->len == 0 || stream->len == (size_t)-1)
+            return EOF;
+    }
+
+    c = stream->data[stream->pos];
+    stream->pos++;
+    return (unsigned char)c;
+}
+
+json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags,
+                           json_error_t *error) {
+    lex_t lex;
+    json_t *result;
+
+    callback_data_t stream_data;
+
+    memset(&stream_data, 0, sizeof(stream_data));
+    stream_data.callback = callback;
+    stream_data.arg = arg;
+
+    jsonp_error_init(error, "<callback>");
+
+    if (callback == NULL) {
+        error_set(error, NULL, json_error_invalid_argument, "wrong arguments");
+        return NULL;
+    }
+
+    if (lex_init(&lex, (get_func)callback_get, flags, &stream_data))
+        return NULL;
+
+    result = parse_json(&lex, flags, error);
+
+    lex_close(&lex);
+    return result;
+}
diff --git a/RedfishPkg/Library/JsonLib/Readme.rst b/RedfishPkg/Library/JsonLib/Readme.rst
new file mode 100644
index 0000000000..cc149196b9
--- /dev/null
+++ b/RedfishPkg/Library/JsonLib/Readme.rst
@@ -0,0 +1,40 @@
+=============================================================================
+                             Introduction
+=============================================================================
+  Jansson is a C library for encoding, decoding and manipulating JSON data.
+Its main features and design principles are:
+
+  - Simple and intuitive API and data model
+  - Comprehensive documentation
+  - No dependencies on other libraries
+  - Full Unicode support (UTF-8)
+  - Extensive test suite
+
+  Jansson is licensed under the MIT license(refer to ReadMe.rst under edk2).
+It is used in production and its API is stable. It works on numerous
+platforms, including numerous Unix like systems and Windows. It's suitable
+for use on any system, including desktop, server, and small embedded systems.
+
+  In UEFI/EDKII environment, Redfish project consumes jansson to achieve JSON
+operations.
+
+* Jansson version on edk2: 2.13.1
+
+* EDKII jansson library wrapper:
+   - JsonLib.h:
+     This is the denifitions of EDKII JSON APIs which are mapped to
+     jannson funcitons accordingly.
+
+   - JanssonJsonLibMapping.h:
+     This is the wrapper to map funcitons and definitions used in
+     native jannson applications to edk2 JsonLib. This avoids the
+     modifications on native jannson applications to be built under
+     edk2 environment.
+
+*Known issue:
+   Build fail with jansson/src/load.c, add code in load.c to conditionally
+   use stdin according to HAVE_UNISTD_H macro. The PR is submitted to
+   jansson open source community.
+   https://github.com/akheron/jansson/pull/558
+
+
diff --git a/RedfishPkg/RedfishPkg.ci.yaml b/RedfishPkg/RedfishPkg.ci.yaml
index 9895fdac99..2a26769536 100644
--- a/RedfishPkg/RedfishPkg.ci.yaml
+++ b/RedfishPkg/RedfishPkg.ci.yaml
@@ -35,7 +35,13 @@
             "Include/Crt/string.h",
             "Include/Crt/time.h",
             "Include/Library/CrtLib.h",
-            "Library/CrtLib/CrtLib.c"
+            "Library/CrtLib/CrtLib.c",
+            ##
+            ## For jansson library open source
+            ## load.c is overrided from open source.
+            "Library/JsonLib/load.c",
+            "Library/JsonLib/jansson_config.h",
+            "Library/JsonLib/jansson_private_config.h"
         ]
     },
     "CompilerPlugin": {
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 5/6] RedfishPkg: Add EDK2 port of jansson library to build
  2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
                   ` (3 preceding siblings ...)
  2020-12-17 13:18 ` [PATCH v8 4/6] RedfishPkg/library: EDK2 port of jansson library Abner Chang
@ 2020-12-17 13:18 ` Abner Chang
  2020-12-17 13:18 ` [PATCH v8 6/6] .pytool: Add required submodule for JsonLib Abner Chang
  2020-12-20 19:42 ` [PATCH v8 0/6] jansson edk2 port Michael D Kinney
  6 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-17 13:18 UTC (permalink / raw)
  To: devel; +Cc: Nickle Wang, Peter O'Hanley

Add EDK2 port jansson library (JsonLib) to RedfishPkg

Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
---
 RedfishPkg/RedfishLibs.dsc.inc | 1 +
 RedfishPkg/RedfishPkg.dsc      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/RedfishPkg/RedfishLibs.dsc.inc b/RedfishPkg/RedfishLibs.dsc.inc
index 2a951bd8fa..bc036a33e8 100644
--- a/RedfishPkg/RedfishLibs.dsc.inc
+++ b/RedfishPkg/RedfishLibs.dsc.inc
@@ -13,5 +13,6 @@
 !if $(REDFISH_ENABLE) == TRUE
   Ucs2Utf8Lib|RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
   CrtLib|RedfishPkg/Library/CrtLib/CrtLib.inf
+  JsonLib|RedfishPkg/Library/JsonLib/JsonLib.inf
 !endif
 
diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc
index 8df2c69390..61c0cdb642 100644
--- a/RedfishPkg/RedfishPkg.dsc
+++ b/RedfishPkg/RedfishPkg.dsc
@@ -51,5 +51,6 @@
   RedfishPkg/Library/PlatformCredentialLibNull/PlatformCredentialLibNull.inf
   RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
   RedfishPkg/Library/CrtLib/CrtLib.inf
+  RedfishPkg/Library/JsonLib/JsonLib.inf
 
   !include RedfishPkg/Redfish.dsc.inc
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v8 6/6] .pytool: Add required submodule for JsonLib
  2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
                   ` (4 preceding siblings ...)
  2020-12-17 13:18 ` [PATCH v8 5/6] RedfishPkg: Add EDK2 port of jansson library to build Abner Chang
@ 2020-12-17 13:18 ` Abner Chang
  2020-12-20 19:42 ` [PATCH v8 0/6] jansson edk2 port Michael D Kinney
  6 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-17 13:18 UTC (permalink / raw)
  To: devel; +Cc: Sean Brogan, Bret Barkelew, Nickle Wang, Peter O'Hanley

Open source project jansson is leveraged by edk2 JsonLib.
Add jansson to the required submodule in CiSettings.py.

Signed-off-by: Abner Chang <abner.chang@hpe.com>

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Nickle Wang <nickle.wang@hpe.com>
Cc: Peter O'Hanley <peter.ohanley@hpe.com>
---
 .pytool/CISettings.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py
index b337d046ae..416de023cc 100644
--- a/.pytool/CISettings.py
+++ b/.pytool/CISettings.py
@@ -158,6 +158,8 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
             "MdeModulePkg/Library/BrotliCustomDecompressLib/brotli", False))
         rs.append(RequiredSubmodule(
             "BaseTools/Source/C/BrotliCompress/brotli", False))
+        rs.append(RequiredSubmodule(
+            "RedfishPkg/Library/JsonLib/jansson", False))
         return rs
 
     def GetName(self):
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 4/6] RedfishPkg/library: EDK2 port of jansson library
  2020-12-17 13:18 ` [PATCH v8 4/6] RedfishPkg/library: EDK2 port of jansson library Abner Chang
@ 2020-12-18 11:19   ` Leif Lindholm
  0 siblings, 0 replies; 19+ messages in thread
From: Leif Lindholm @ 2020-12-18 11:19 UTC (permalink / raw)
  To: Abner Chang; +Cc: devel, Nickle Wang, Peter O'Hanley

On Thu, Dec 17, 2020 at 21:18:37 +0800, Abner Chang wrote:
> edk2 JsonLib which is the edk2 port of open source
> jansson library.
> (https://github.com/akheron/jansson)
> jansson library is the open source project to manipulate
> JSON data structure.
> 
> Signed-off-by: Abner Chang <abner.chang@hpe.com>

Acked-by: Leif Lindholm <leif@nuviainc.com>

> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Nickle Wang <nickle.wang@hpe.com>
> Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
> ---
>  RedfishPkg/RedfishPkg.dec                     |   11 +
>  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
>  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
>  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
>  .../Library/JsonLib/jansson_private_config.h  |   19 +
>  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
>  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
>  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
>  RedfishPkg/RedfishPkg.ci.yaml                 |    8 +-
>  9 files changed, 3045 insertions(+), 1 deletion(-)
>  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
>  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
>  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
>  create mode 100644 RedfishPkg/Library/JsonLib/jansson_private_config.h
>  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
>  create mode 100644 RedfishPkg/Library/JsonLib/load.c
>  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
                   ` (5 preceding siblings ...)
  2020-12-17 13:18 ` [PATCH v8 6/6] .pytool: Add required submodule for JsonLib Abner Chang
@ 2020-12-20 19:42 ` Michael D Kinney
  2020-12-21  8:17   ` Abner Chang
  6 siblings, 1 reply; 19+ messages in thread
From: Michael D Kinney @ 2020-12-20 19:42 UTC (permalink / raw)
  To: Abner Chang, devel@edk2.groups.io, Kinney, Michael D
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Nickle Wang, Peter O'Hanley

Hi Abner,

The include path in the [Include.Common.Private] section should not be 
in the same file path as the [Include] section.  This allows private include
files to be accessed.

Instead, you should create a new top level package directory called PrivateInclude
and put all non-public include content in that directory.  The UnitTestFrameworkPkg
is a good reference that demonstrates this design pattern.

The library class name CrtLib is very generic and the library class is in the 
public includes so it is exported as a public interface from the RedfishPkg.
This CrtLib implementation appears to be tuned to support the dependencies
for the jansson submodule.  I recommend changing the library class name and
the library instance name so it is clear that this CrtLib is only for jansson.
Perhaps 'JanssonCrtLib'.  Also, does this library class (CrtLib.h) need to 
be exported from RedfishPkg as a public interface?

* RedfishPkg/Include/Library/CrtLib.h
  + Remove reference to MDE_CPU_IA64.  This has been retired from the edk2 repo.
  + I do see one remaining reference to this in the CryptoPkg that need to be
    removed.

* RedfishPkg/Include/Library/JsonLib.h
  + Some of the function descriptions are very brief and I can not tell 
    how to use the service from the description and more importantly, I 
    would not know how to write a unit test to verify the expected behavior.
    Since these are a set of public APIs from this package that you 
    expect modules/libs from outside of RedfishPkg to use, then all of 
    these public APIs must be fully documented.
  + Are there any of these APIs that are not really needed by modules/libs
    outside the RedfishPkg?  It would be better to remove APIs that are
    not needed outside RedfishPkg from this public include file.
  + A couple examples that stood out are:
    JsonDecreaseReference()
    JsonIncreaseReference()
    JsonObjectIterator()
    JsonObjectIteratorValue()
    JsonObjectIteratorNext()
  + JsonDumpString() 
    func header params do not match func prototype
    Does not describe who allocates the return buffer and who
    is responsible for freeing the buffer returned.
    What do Flags do?  What is the difference between this
    function and JsonToText()?
  + JsonLoadBuffer() - Error param description missing
  + JsonArrayGetValue() does not describe the conditions NULL
    is returned.
  + JsonObjectGetKeys().  Return type is CHAR8**.  What
    function need to be called to free the array?
  + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
    are asymmetric.  The Ascii one states that change will
    modify the original string.  The Unicode one says that the
    caller needs to free the returned string.  Any reason we
    can not make them symmetric?  Also, if Ascii one should
    not be modified, why isn’t the return type CONST?

* RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
  + Change [Sources.common] to [Sources]

* RedfishPkg/Library/CrtLib/CrtLib.inf
  + Does this lib instance really depend on MdeModulePkg?
  + Have you reviewed the module types this lib instance is
    compatible with?  Why does it need to support DXE_CORE?
    Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
    If there are SMM use cases, then why is MM excluded?

* RedfishPkg/Library/JsonLib
  + Readme.rst still has references to JanssonJsonLibMapping.h
  + Have you reviewed the module types this lib instance is
    compatible with?  Why does it need to support DXE_CORE?
    Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
    If there are SMM use cases, then why is MM excluded?
  + JsonLib.inf has a [BuildOptions] section that disables some warnings that
    make me concerned that this library may have some issues with 32-bit builds.
    Have you fully validated all 32-bit CPU builds and validated the functionality
    of all services from the JsonLib for all ranges of input values?

* RedfishLibs.dsc.inc
  It is better to add [LibraryClasses] statement to this file, so it 
  can be include anywhere in a DSC file.  With current implementation
  if it is not included within a [LibraryClasses] section, it will
  generate a build error.  You might also consider changing the name
  of this file in case you want to add more than just lib mappings
  to this file in the future.  See UnitTestFramworkPkg for examples.

Best regards,

Mike

> -----Original Message-----
> From: Abner Chang <abner.chang@hpe.com>
> Sent: Thursday, December 17, 2020 5:19 AM
> To: devel@edk2.groups.io
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Kinney, Michael D <michael.d.kinney@intel.com>;
> Liming Gao <gaoliming@byosoft.com.cn>; Nickle Wang <nickle.wang@hpe.com>; Peter O'Hanley <peter.ohanley@hpe.com>
> Subject: [PATCH v8 0/6] jansson edk2 port
> 
> In v8, - Assigne patch file order
>        - Add Acked-by tags
> In v7, - Remove C RTC header files to under [Include.Common.Private]
>          in RedfishPkg.dec.
>        - address comments given by Mike Kinney.
> In v6, Remove JanssonJsonMapping.h
> In v5, move BaseUcs2Utf8Lib to under RedfishPkg.
> In v4,
>        - Address review comments
>        - Seperate CRT functions to a individule library CrtLib under
>          RedfishPkg.
>        - Seperate UCS2-UTF8 functions to a individule library
>          BaseUcs2Utf8Lib under MdeModulePkg.
> 
> In v3, Add jansson library as the required submoudle in
>        CiSettings.py for CI test.
> In v2, JsonLib is moved to under RedfishPkg.
> 
> edk2 JSON library is based on jansson open source
> (https://github.com/akheron/jansson) and wrapped as an edk2
> library. edk2 JsonLib will be used by edk2 Redfish feature
> drivers (not contributed yet) and the edk2 port of libredfish
> library (not contributed yet) based on DMTF GitHub
> (https://github.com/DMTF/libredfish).
> 
> Jansson is licensed under the MIT license(refer to ReadMe.rst under edk2).
> It is used in production and its API is stable. In UEFI/EDKII environment,
> Redfish project consumes jansson to achieve JSON operations.
> 
> * Jansson version on edk2: 2.13.1
> 
> * EDKII jansson library wrapper:
>    - JsonLib.h:
>      This is the denifitions of EDKII JSON APIs which are mapped to
>      jannson funcitons accordingly.
> 
>    - JanssonJsonLibMapping.h:
>      This is the wrapper file to map funcitons and definitions used in
>      native jannson applications to edk2 JsonLib. This avoids the
>      modifications on native jannson applications to be built under
>      edk2 environment.
> 
> *Known issue:
>   Build fail with jansson/src/load.c, overrride and add code in load.c
>   to conditionally use stdin according to HAVE_UNISTD_H macro.
>   The PR is submitted to jansson open source community.
>   https://github.com/akheron/jansson/pull/558
> 
> Signed-off-by: Abner Chang <abner.chang@hpe.com>
> 
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> Cc: Andrew Fish <afish@apple.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Nickle Wang <nickle.wang@hpe.com>
> Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> 
> Abner Chang (6):
>   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
>   edk2: jansson submodule for edk2 JSON library
>   RedfishPkg/CrtLib: C runtime library
>   RedfishPkg/library: EDK2 port of jansson library
>   RedfishPkg: Add EDK2 port of jansson library to build
>   .pytool: Add required submodule for JsonLib
> 
>  .gitmodules                                   |    3 +
>  .pytool/CISettings.py                         |    2 +
>  ReadMe.rst                                    |    1 +
>  RedfishPkg/Include/Crt/assert.h               |   16 +
>  RedfishPkg/Include/Crt/errno.h                |   16 +
>  RedfishPkg/Include/Crt/limits.h               |   16 +
>  RedfishPkg/Include/Crt/math.h                 |   16 +
>  RedfishPkg/Include/Crt/stdarg.h               |   15 +
>  RedfishPkg/Include/Crt/stddef.h               |   16 +
>  RedfishPkg/Include/Crt/stdio.h                |   15 +
>  RedfishPkg/Include/Crt/stdlib.h               |   16 +
>  RedfishPkg/Include/Crt/string.h               |   16 +
>  RedfishPkg/Include/Crt/sys/time.h             |   15 +
>  RedfishPkg/Include/Crt/sys/types.h            |   15 +
>  RedfishPkg/Include/Crt/time.h                 |   15 +
>  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
>  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
>  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
>  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
>  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
>  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
>  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
>  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
>  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
>  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
>  RedfishPkg/Library/JsonLib/jansson            |    1 +
>  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
>  .../Library/JsonLib/jansson_private_config.h  |   19 +
>  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
>  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
>  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
>  RedfishPkg/RedfishPkg.dec                     |   25 +
>  RedfishPkg/RedfishPkg.dsc                     |    3 +
>  33 files changed, 4614 insertions(+)
>  create mode 100644 RedfishPkg/Include/Crt/assert.h
>  create mode 100644 RedfishPkg/Include/Crt/errno.h
>  create mode 100644 RedfishPkg/Include/Crt/limits.h
>  create mode 100644 RedfishPkg/Include/Crt/math.h
>  create mode 100644 RedfishPkg/Include/Crt/stdarg.h
>  create mode 100644 RedfishPkg/Include/Crt/stddef.h
>  create mode 100644 RedfishPkg/Include/Crt/stdio.h
>  create mode 100644 RedfishPkg/Include/Crt/stdlib.h
>  create mode 100644 RedfishPkg/Include/Crt/string.h
>  create mode 100644 RedfishPkg/Include/Crt/sys/time.h
>  create mode 100644 RedfishPkg/Include/Crt/sys/types.h
>  create mode 100644 RedfishPkg/Include/Crt/time.h
>  create mode 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
>  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
>  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
>  create mode 100644 RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
>  create mode 100644 RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
>  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
>  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
>  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
>  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
>  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
>  create mode 160000 RedfishPkg/Library/JsonLib/jansson
>  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
>  create mode 100644 RedfishPkg/Library/JsonLib/jansson_private_config.h
>  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> 
> --
> 2.17.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-20 19:42 ` [PATCH v8 0/6] jansson edk2 port Michael D Kinney
@ 2020-12-21  8:17   ` Abner Chang
  2020-12-22 18:14     ` Michael D Kinney
  0 siblings, 1 reply; 19+ messages in thread
From: Abner Chang @ 2020-12-21  8:17 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)

Mike, response in below. Also v9 is sent.

Thanks for review this in detail.
Abner

> -----Original Message-----
> From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> Sent: Monday, December 21, 2020 3:43 AM
> To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> Hi Abner,
> 
> The include path in the [Include.Common.Private] section should not be in
> the same file path as the [Include] section.  This allows private include files to
> be accessed.
> 
> Instead, you should create a new top level package directory called
> PrivateInclude and put all non-public include content in that directory.  The
> UnitTestFrameworkPkg is a good reference that demonstrates this design
> pattern.
Yes, this looks better. All Crt header files and CrtLib.h will be moved to under PrivateInclude.
> 
> The library class name CrtLib is very generic and the library class is in the
> public includes so it is exported as a public interface from the RedfishPkg.
> This CrtLib implementation appears to be tuned to support the
> dependencies for the jansson submodule.  I recommend changing the library
> class name and the library instance name so it is clear that this CrtLib is only
> for jansson.
> Perhaps 'JanssonCrtLib'. 
The CrtLib is not used by jannson lib, libredfish as well (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a good naming, will keep that as it.

>Also, does this library class (CrtLib.h) need to be
> exported from RedfishPkg as a public interface?
No, it will be moved to under PrivateInclude.

If CrtLib.h is defined as a private library and CrtLib.h is in PrivateInclude which is not exposed to other packages, then why do we care about the naming of CrtLib is too generic? Which is the private library under RedfishPkg.
Move those header files to under PrivateInclude seems clear to people that CrtLib is only for RedfishPkg. I think we don’t have to change the naming in this case.

> 
> * RedfishPkg/Include/Library/CrtLib.h
>   + Remove reference to MDE_CPU_IA64.  This has been retired from the
> edk2 repo.
Ok.
>   + I do see one remaining reference to this in the CryptoPkg that need to be
>     removed.
> 
> * RedfishPkg/Include/Library/JsonLib.h
>   + Some of the function descriptions are very brief and I can not tell
>     how to use the service from the description and more importantly, I
>     would not know how to write a unit test to verify the expected behavior.
>     Since these are a set of public APIs from this package that you
>     expect modules/libs from outside of RedfishPkg to use, then all of
>     these public APIs must be fully documented.
Most of the API in JsonLib are wrappers of native jansson APIs. We can mention the URL to jansson API reference document in file header. https://jansson.readthedocs.io/en/2.13/index.html
I will review all function header again,  please check v9 patch later.

>   + Are there any of these APIs that are not really needed by modules/libs
>     outside the RedfishPkg?  It would be better to remove APIs that are
>     not needed outside RedfishPkg from this public include file.
>   + A couple examples that stood out are:
>     JsonDecreaseReference()
>     JsonIncreaseReference()
>     JsonObjectIterator()
>     JsonObjectIteratorValue()
>     JsonObjectIteratorNext()
The native jansson APIs of all above wrappers are used in libredfish. So that is the potential use case for other JSON applications.

>   + JsonDumpString()
>     func header params do not match func prototype
>     Does not describe who allocates the return buffer and who
>     is responsible for freeing the buffer returned.
>     What do Flags do?  What is the difference between this
>     function and JsonToText()?
In JsonToText, it only converts JSON array and object to text. We could just remove this for now because I don’t really remember the reason to create this function, it has been a while. Seems to me it is fine to remove this function.

>   + JsonLoadBuffer() - Error param description missing
>   + JsonArrayGetValue() does not describe the conditions NULL
>     is returned.
>   + JsonObjectGetKeys().  Return type is CHAR8**.  What
>     function need to be called to free the array?
All above addressed.

>   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
>     are asymmetric.  The Ascii one states that change will
>     modify the original string.  The Unicode one says that the
>     caller needs to free the returned string.  Any reason we
>     can not make them symmetric? 
Jansson doesn't support Unicode string. The memory of the unicode string returned by JsonValueGetUnicodeString
Is allocated by UTF8StrToUCS2().
 > Also, if Ascii one should
>     not be modified, why isn’t the return type CONST?
Yes. will do that.

> 
> * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
>   + Change [Sources.common] to [Sources]
done
> * RedfishPkg/Library/CrtLib/CrtLib.inf
>   + Does this lib instance really depend on MdeModulePkg?
Yes, SortLib
>   + Have you reviewed the module types this lib instance is
>     compatible with?  Why does it need to support DXE_CORE?
>     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
>     If there are SMM use cases, then why is MM excluded?
Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER. These are module types have potential use cases I can think of now.
> 
> * RedfishPkg/Library/JsonLib
>   + Readme.rst still has references to JanssonJsonLibMapping.h
done
>   + Have you reviewed the module types this lib instance is
>     compatible with?  Why does it need to support DXE_CORE?
>     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
>     If there are SMM use cases, then why is MM excluded?
Answered above
>   + JsonLib.inf has a [BuildOptions] section that disables some warnings that
>     make me concerned that this library may have some issues with 32-bit
> builds.
>     Have you fully validated all 32-bit CPU builds and validated the functionality
>     of all services from the JsonLib for all ranges of input values?
Yes, IA32 build is validated. But not validating on the functionalities IA32. I don't have that use case, we can get back to fix the issue if any when  someone runs this on IA32.
> 
> * RedfishLibs.dsc.inc
>   It is better to add [LibraryClasses] statement to this file, so it
>   can be include anywhere in a DSC file.  With current implementation
>   if it is not included within a [LibraryClasses] section, it will
>   generate a build error. 
I will separate this to another set of patch. Don’t mix up with jansson edk2 port.

>You might also consider changing the name
>   of this file in case you want to add more than just lib mappings
>   to this file in the future.  See UnitTestFramworkPkg for examples.
> 
> Best regards,
> 
> Mike
> 
> > -----Original Message-----
> > From: Abner Chang <abner.chang@hpe.com>
> > Sent: Thursday, December 17, 2020 5:19 AM
> > To: devel@edk2.groups.io
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Kinney,
> > Michael D <michael.d.kinney@intel.com>; Liming Gao
> > <gaoliming@byosoft.com.cn>; Nickle Wang <nickle.wang@hpe.com>;
> Peter
> > O'Hanley <peter.ohanley@hpe.com>
> > Subject: [PATCH v8 0/6] jansson edk2 port
> >
> > In v8, - Assigne patch file order
> >        - Add Acked-by tags
> > In v7, - Remove C RTC header files to under [Include.Common.Private]
> >          in RedfishPkg.dec.
> >        - address comments given by Mike Kinney.
> > In v6, Remove JanssonJsonMapping.h
> > In v5, move BaseUcs2Utf8Lib to under RedfishPkg.
> > In v4,
> >        - Address review comments
> >        - Seperate CRT functions to a individule library CrtLib under
> >          RedfishPkg.
> >        - Seperate UCS2-UTF8 functions to a individule library
> >          BaseUcs2Utf8Lib under MdeModulePkg.
> >
> > In v3, Add jansson library as the required submoudle in
> >        CiSettings.py for CI test.
> > In v2, JsonLib is moved to under RedfishPkg.
> >
> > edk2 JSON library is based on jansson open source
> > (https://github.com/akheron/jansson) and wrapped as an edk2 library.
> > edk2 JsonLib will be used by edk2 Redfish feature drivers (not
> > contributed yet) and the edk2 port of libredfish library (not
> > contributed yet) based on DMTF GitHub
> > (https://github.com/DMTF/libredfish).
> >
> > Jansson is licensed under the MIT license(refer to ReadMe.rst under edk2).
> > It is used in production and its API is stable. In UEFI/EDKII
> > environment, Redfish project consumes jansson to achieve JSON
> operations.
> >
> > * Jansson version on edk2: 2.13.1
> >
> > * EDKII jansson library wrapper:
> >    - JsonLib.h:
> >      This is the denifitions of EDKII JSON APIs which are mapped to
> >      jannson funcitons accordingly.
> >
> >    - JanssonJsonLibMapping.h:
> >      This is the wrapper file to map funcitons and definitions used in
> >      native jannson applications to edk2 JsonLib. This avoids the
> >      modifications on native jannson applications to be built under
> >      edk2 environment.
> >
> > *Known issue:
> >   Build fail with jansson/src/load.c, overrride and add code in load.c
> >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> >   The PR is submitted to jansson open source community.
> >   https://github.com/akheron/jansson/pull/558
> >
> > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> >
> > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > Cc: Andrew Fish <afish@apple.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Cc: Nickle Wang <nickle.wang@hpe.com>
> > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> >
> > Abner Chang (6):
> >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> >   edk2: jansson submodule for edk2 JSON library
> >   RedfishPkg/CrtLib: C runtime library
> >   RedfishPkg/library: EDK2 port of jansson library
> >   RedfishPkg: Add EDK2 port of jansson library to build
> >   .pytool: Add required submodule for JsonLib
> >
> >  .gitmodules                                   |    3 +
> >  .pytool/CISettings.py                         |    2 +
> >  ReadMe.rst                                    |    1 +
> >  RedfishPkg/Include/Crt/assert.h               |   16 +
> >  RedfishPkg/Include/Crt/errno.h                |   16 +
> >  RedfishPkg/Include/Crt/limits.h               |   16 +
> >  RedfishPkg/Include/Crt/math.h                 |   16 +
> >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> >  RedfishPkg/Include/Crt/string.h               |   16 +
> >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> >  RedfishPkg/Include/Crt/time.h                 |   15 +
> >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
> >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> >  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
> >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> >  RedfishPkg/RedfishPkg.dec                     |   25 +
> >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> >  33 files changed, 4614 insertions(+)
> >  create mode 100644 RedfishPkg/Include/Crt/assert.h  create mode
> > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > RedfishPkg/Include/Crt/math.h  create mode 100644
> > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > RedfishPkg/Include/Crt/string.h  create mode 100644
> > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > RedfishPkg/Include/Crt/sys/types.h
> >  create mode 100644 RedfishPkg/Include/Crt/time.h  create mode 100644
> > RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> >  create mode 100644
> > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> >  create mode 100644
> > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> >  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
> >  create mode 100644
> > RedfishPkg/Library/JsonLib/jansson_private_config.h
> >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> >
> > --
> > 2.17.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-21  8:17   ` Abner Chang
@ 2020-12-22 18:14     ` Michael D Kinney
  2020-12-23  3:42       ` Abner Chang
                         ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Michael D Kinney @ 2020-12-22 18:14 UTC (permalink / raw)
  To: Chang, Abner (HPS SW/FW Technologist), devel@edk2.groups.io,
	Kinney, Michael D
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)

Hi Abner,

A few comments below.

Best regards,

Mike

> -----Original Message-----
> From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
> Sent: Monday, December 21, 2020 12:17 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle
> (HPS SW) <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> Mike, response in below. Also v9 is sent.
> 
> Thanks for review this in detail.
> Abner
> 
> > -----Original Message-----
> > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > Sent: Monday, December 21, 2020 3:43 AM
> > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> > <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> > Hi Abner,
> >
> > The include path in the [Include.Common.Private] section should not be in
> > the same file path as the [Include] section.  This allows private include files to
> > be accessed.
> >
> > Instead, you should create a new top level package directory called
> > PrivateInclude and put all non-public include content in that directory.  The
> > UnitTestFrameworkPkg is a good reference that demonstrates this design
> > pattern.
> Yes, this looks better. All Crt header files and CrtLib.h will be moved to under PrivateInclude.
> >
> > The library class name CrtLib is very generic and the library class is in the
> > public includes so it is exported as a public interface from the RedfishPkg.
> > This CrtLib implementation appears to be tuned to support the
> > dependencies for the jansson submodule.  I recommend changing the library
> > class name and the library instance name so it is clear that this CrtLib is only
> > for jansson.
> > Perhaps 'JanssonCrtLib'.
> The CrtLib is not used by jannson lib, libredfish as well (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a
> good naming, will keep that as it.
> 
> >Also, does this library class (CrtLib.h) need to be
> > exported from RedfishPkg as a public interface?
> No, it will be moved to under PrivateInclude.
> 
> If CrtLib.h is defined as a private library and CrtLib.h is in PrivateInclude which is not exposed to other packages, then
> why do we care about the naming of CrtLib is too generic? Which is the private library under RedfishPkg.
> Move those header files to under PrivateInclude seems clear to people that CrtLib is only for RedfishPkg. I think we don’t
> have to change the naming in this case.

In general I agree, but there is one place where the lib mapping has wider scope, and that is in a platform DSC
file.  The lib class name CrtLib has to be listed in the DSC file.  If more than one package defines a library
class called CrtLib, then the last mapping used will be used for all modules if it is listed in the [LibraryClasses]
section of the DSC file.  The only was to handle this type of name collision is to use a module scoped 
library mapping in the <LibraryClasses> section of each individual module that uses a CrtLib.  I am only
trying to avoid the potential for future name collisions for a library class/instance that is specific to
the JSON use case.  

We recognize that several modules in edk2 have this type of gasket between an EDK II env and a standard C
lib.  We may find a we to implement a more generic gasket and retire the use of the implementation specific
ones.  This is another reason to use an implementation specific name in this use case and be able to
introduce a more generic name in the future.

Another comment below to see if there is a way to avoid introducing a CrtLib class.

> 
> >
> > * RedfishPkg/Include/Library/CrtLib.h
> >   + Remove reference to MDE_CPU_IA64.  This has been retired from the
> > edk2 repo.
> Ok.
> >   + I do see one remaining reference to this in the CryptoPkg that need to be
> >     removed.
> >
> > * RedfishPkg/Include/Library/JsonLib.h
> >   + Some of the function descriptions are very brief and I can not tell
> >     how to use the service from the description and more importantly, I
> >     would not know how to write a unit test to verify the expected behavior.
> >     Since these are a set of public APIs from this package that you
> >     expect modules/libs from outside of RedfishPkg to use, then all of
> >     these public APIs must be fully documented.
> Most of the API in JsonLib are wrappers of native jansson APIs. We can mention the URL to jansson API reference document
> in file header. https://jansson.readthedocs.io/en/2.13/index.html
> I will review all function header again,  please check v9 patch later.
> 
> >   + Are there any of these APIs that are not really needed by modules/libs
> >     outside the RedfishPkg?  It would be better to remove APIs that are
> >     not needed outside RedfishPkg from this public include file.
> >   + A couple examples that stood out are:
> >     JsonDecreaseReference()
> >     JsonIncreaseReference()
> >     JsonObjectIterator()
> >     JsonObjectIteratorValue()
> >     JsonObjectIteratorNext()
> The native jansson APIs of all above wrappers are used in libredfish. So that is the potential use case for other JSON
> applications.

Can you provide a pointer to an example of this use case?

I am trying to make sure we are doing the right design of RedfishPkg with respect to CrtLib
for this use case.  Are these are JSON apps that do not use JsonLib, but are expected to build
in an EDK II build environment?  Would these JSON apps require more standard C lib services 
than the CrtLib used to build JsonLib?  Where would those additional C lib services come from?

There is a standard C lib in edk2-libc.  Would that be required to build the JSON apps.

In other uses of submodules with C lib dependencies, a new CrtLib like lib class was not
added and instead the support was added directly to the EDK II wrapper APIs. Some examples are:
  * MdeModulePkg\Library\BrotliCustomDecompressLib
  * MdeModulePkg\Universal\RegularExpressionDxe

If there are use cases where the CrtLib will be added to an INF outside the RedfishPkg, then 
I still think the name needs to be changed to be specific to the JSON use case.

If the use of CrtLib is only within the RedfishPkg, then the Library Class can be 
declared in a [LibraryClasses.Common.Private] section of the DEC file.  See
UnitTestFrameworkPkg for examples.

> 
> >   + JsonDumpString()
> >     func header params do not match func prototype
> >     Does not describe who allocates the return buffer and who
> >     is responsible for freeing the buffer returned.
> >     What do Flags do?  What is the difference between this
> >     function and JsonToText()?
> In JsonToText, it only converts JSON array and object to text. We could just remove this for now because I don’t really
> remember the reason to create this function, it has been a while. Seems to me it is fine to remove this function.
> 
> >   + JsonLoadBuffer() - Error param description missing
> >   + JsonArrayGetValue() does not describe the conditions NULL
> >     is returned.
> >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> >     function need to be called to free the array?
> All above addressed.
> 
> >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> >     are asymmetric.  The Ascii one states that change will
> >     modify the original string.  The Unicode one says that the
> >     caller needs to free the returned string.  Any reason we
> >     can not make them symmetric?
> Jansson doesn't support Unicode string. The memory of the unicode string returned by JsonValueGetUnicodeString
> Is allocated by UTF8StrToUCS2().
>  > Also, if Ascii one should
> >     not be modified, why isn’t the return type CONST?
> Yes. will do that.
> 
> >
> > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> >   + Change [Sources.common] to [Sources]
> done
> > * RedfishPkg/Library/CrtLib/CrtLib.inf
> >   + Does this lib instance really depend on MdeModulePkg?
> Yes, SortLib
> >   + Have you reviewed the module types this lib instance is
> >     compatible with?  Why does it need to support DXE_CORE?
> >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> >     If there are SMM use cases, then why is MM excluded?
> Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER. These are module types have potential use cases I can think of
> now.
> >
> > * RedfishPkg/Library/JsonLib
> >   + Readme.rst still has references to JanssonJsonLibMapping.h
> done
> >   + Have you reviewed the module types this lib instance is
> >     compatible with?  Why does it need to support DXE_CORE?
> >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> >     If there are SMM use cases, then why is MM excluded?
> Answered above
> >   + JsonLib.inf has a [BuildOptions] section that disables some warnings that
> >     make me concerned that this library may have some issues with 32-bit
> > builds.
> >     Have you fully validated all 32-bit CPU builds and validated the functionality
> >     of all services from the JsonLib for all ranges of input values?
> Yes, IA32 build is validated. But not validating on the functionalities IA32. I don't have that use case, we can get back
> to fix the issue if any when  someone runs this on IA32.

I did some local testing with VS2019.  I found that a much smaller set of warning disables
are required for IA32 and X64 and the set is different for IA32 and X64.  Can you review
what is needed and minimize the required set of each supported arch?

  MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334 /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
  MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090 /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER

> >
> > * RedfishLibs.dsc.inc
> >   It is better to add [LibraryClasses] statement to this file, so it
> >   can be include anywhere in a DSC file.  With current implementation
> >   if it is not included within a [LibraryClasses] section, it will
> >   generate a build error.
> I will separate this to another set of patch. Don’t mix up with jansson edk2 port.
> 
> >You might also consider changing the name
> >   of this file in case you want to add more than just lib mappings
> >   to this file in the future.  See UnitTestFramworkPkg for examples.
> >
> > Best regards,
> >
> > Mike
> >
> > > -----Original Message-----
> > > From: Abner Chang <abner.chang@hpe.com>
> > > Sent: Thursday, December 17, 2020 5:19 AM
> > > To: devel@edk2.groups.io
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Kinney,
> > > Michael D <michael.d.kinney@intel.com>; Liming Gao
> > > <gaoliming@byosoft.com.cn>; Nickle Wang <nickle.wang@hpe.com>;
> > Peter
> > > O'Hanley <peter.ohanley@hpe.com>
> > > Subject: [PATCH v8 0/6] jansson edk2 port
> > >
> > > In v8, - Assigne patch file order
> > >        - Add Acked-by tags
> > > In v7, - Remove C RTC header files to under [Include.Common.Private]
> > >          in RedfishPkg.dec.
> > >        - address comments given by Mike Kinney.
> > > In v6, Remove JanssonJsonMapping.h
> > > In v5, move BaseUcs2Utf8Lib to under RedfishPkg.
> > > In v4,
> > >        - Address review comments
> > >        - Seperate CRT functions to a individule library CrtLib under
> > >          RedfishPkg.
> > >        - Seperate UCS2-UTF8 functions to a individule library
> > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > >
> > > In v3, Add jansson library as the required submoudle in
> > >        CiSettings.py for CI test.
> > > In v2, JsonLib is moved to under RedfishPkg.
> > >
> > > edk2 JSON library is based on jansson open source
> > > (https://github.com/akheron/jansson) and wrapped as an edk2 library.
> > > edk2 JsonLib will be used by edk2 Redfish feature drivers (not
> > > contributed yet) and the edk2 port of libredfish library (not
> > > contributed yet) based on DMTF GitHub
> > > (https://github.com/DMTF/libredfish).
> > >
> > > Jansson is licensed under the MIT license(refer to ReadMe.rst under edk2).
> > > It is used in production and its API is stable. In UEFI/EDKII
> > > environment, Redfish project consumes jansson to achieve JSON
> > operations.
> > >
> > > * Jansson version on edk2: 2.13.1
> > >
> > > * EDKII jansson library wrapper:
> > >    - JsonLib.h:
> > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > >      jannson funcitons accordingly.
> > >
> > >    - JanssonJsonLibMapping.h:
> > >      This is the wrapper file to map funcitons and definitions used in
> > >      native jannson applications to edk2 JsonLib. This avoids the
> > >      modifications on native jannson applications to be built under
> > >      edk2 environment.
> > >
> > > *Known issue:
> > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > >   The PR is submitted to jansson open source community.
> > >   https://github.com/akheron/jansson/pull/558
> > >
> > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > >
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > Cc: Andrew Fish <afish@apple.com>
> > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > >
> > > Abner Chang (6):
> > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > >   edk2: jansson submodule for edk2 JSON library
> > >   RedfishPkg/CrtLib: C runtime library
> > >   RedfishPkg/library: EDK2 port of jansson library
> > >   RedfishPkg: Add EDK2 port of jansson library to build
> > >   .pytool: Add required submodule for JsonLib
> > >
> > >  .gitmodules                                   |    3 +
> > >  .pytool/CISettings.py                         |    2 +
> > >  ReadMe.rst                                    |    1 +
> > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
> > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > >  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
> > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > >  33 files changed, 4614 insertions(+)
> > >  create mode 100644 RedfishPkg/Include/Crt/assert.h  create mode
> > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > RedfishPkg/Include/Crt/sys/types.h
> > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create mode 100644
> > > RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > >  create mode 100644
> > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > >  create mode 100644
> > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > >  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
> > >  create mode 100644
> > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > >
> > > --
> > > 2.17.1
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-22 18:14     ` Michael D Kinney
@ 2020-12-23  3:42       ` Abner Chang
  2020-12-23  4:28       ` Abner Chang
  2020-12-23  4:39       ` Abner Chang
  2 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-23  3:42 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)



> -----Original Message-----
> From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> Sent: Wednesday, December 23, 2020 2:14 AM
> To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> Hi Abner,
> 
> A few comments below.
> 
> Best regards,
> 
> Mike
> 
> > -----Original Message-----
> > From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
> > Sent: Monday, December 21, 2020 12:17 AM
> > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > devel@edk2.groups.io
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> > Mike, response in below. Also v9 is sent.
> >
> > Thanks for review this in detail.
> > Abner
> >
> > > -----Original Message-----
> > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > Sent: Monday, December 21, 2020 3:43 AM
> > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > > Hi Abner,
> > >
> > > The include path in the [Include.Common.Private] section should not
> > > be in the same file path as the [Include] section.  This allows
> > > private include files to be accessed.
> > >
> > > Instead, you should create a new top level package directory called
> > > PrivateInclude and put all non-public include content in that
> > > directory.  The UnitTestFrameworkPkg is a good reference that
> > > demonstrates this design pattern.
> > Yes, this looks better. All Crt header files and CrtLib.h will be moved to
> under PrivateInclude.
> > >
> > > The library class name CrtLib is very generic and the library class
> > > is in the public includes so it is exported as a public interface from the
> RedfishPkg.
> > > This CrtLib implementation appears to be tuned to support the
> > > dependencies for the jansson submodule.  I recommend changing the
> > > library class name and the library instance name so it is clear that
> > > this CrtLib is only for jansson.
> > > Perhaps 'JanssonCrtLib'.
> > The CrtLib is not used by jannson lib, libredfish as well
> > (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a good
> naming, will keep that as it.
> >
> > >Also, does this library class (CrtLib.h) need to be  exported from
> > >RedfishPkg as a public interface?
> > No, it will be moved to under PrivateInclude.
> >
> > If CrtLib.h is defined as a private library and CrtLib.h is in
> > PrivateInclude which is not exposed to other packages, then why do we
> care about the naming of CrtLib is too generic? Which is the private library
> under RedfishPkg.
> > Move those header files to under PrivateInclude seems clear to people
> > that CrtLib is only for RedfishPkg. I think we don’t have to change the
> naming in this case.
> 
> In general I agree, but there is one place where the lib mapping has wider
> scope, and that is in a platform DSC file.  The lib class name CrtLib has to be
> listed in the DSC file.  If more than one package defines a library class called
> CrtLib, then the last mapping used will be used for all modules if it is listed in
> the [LibraryClasses] section of the DSC file.  The only was to handle this type
> of name collision is to use a module scoped library mapping in the
> <LibraryClasses> section of each individual module that uses a CrtLib.  I am
> only trying to avoid the potential for future name collisions for a library
> class/instance that is specific to the JSON use case.
> 
> We recognize that several modules in edk2 have this type of gasket between
> an EDK II env and a standard C lib.  We may find a we to implement a more
> generic gasket and retire the use of the implementation specific ones.  This is
> another reason to use an implementation specific name in this use case and
> be able to introduce a more generic name in the future.
> 
> Another comment below to see if there is a way to avoid introducing a CrtLib
> class.
Responses all together in below,
> 
> >
> > >
> > > * RedfishPkg/Include/Library/CrtLib.h
> > >   + Remove reference to MDE_CPU_IA64.  This has been retired from
> > > the
> > > edk2 repo.
> > Ok.
> > >   + I do see one remaining reference to this in the CryptoPkg that need to
> be
> > >     removed.
> > >
> > > * RedfishPkg/Include/Library/JsonLib.h
> > >   + Some of the function descriptions are very brief and I can not tell
> > >     how to use the service from the description and more importantly, I
> > >     would not know how to write a unit test to verify the expected
> behavior.
> > >     Since these are a set of public APIs from this package that you
> > >     expect modules/libs from outside of RedfishPkg to use, then all of
> > >     these public APIs must be fully documented.
> > Most of the API in JsonLib are wrappers of native jansson APIs. We can
> > mention the URL to jansson API reference document in file header.
> > INVALID URI REMOVED
> 3A__jansson.readthedo
> >
> cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> SN6FZBN4
> > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > I will review all function header again,  please check v9 patch later.
> >
> > >   + Are there any of these APIs that are not really needed by modules/libs
> > >     outside the RedfishPkg?  It would be better to remove APIs that are
> > >     not needed outside RedfishPkg from this public include file.
> > >   + A couple examples that stood out are:
> > >     JsonDecreaseReference()
> > >     JsonIncreaseReference()
> > >     JsonObjectIterator()
> > >     JsonObjectIteratorValue()
> > >     JsonObjectIteratorNext()
> > The native jansson APIs of all above wrappers are used in libredfish.
> > So that is the potential use case for other JSON applications.
> 
> Can you provide a pointer to an example of this use case?
Again, those are used in open source project published by DMTF to access to Redfish service. https://github.com/DMTF/libredfish
Not sure if you can access to it, I just created an a branch of RedfishLib for your convenience. Take a look at the last commit on below link if you can't access to libredfish on DMTF GitHub.
https://github.com/changab/edk2/tree/RedfishLib
you can search above APIs (the native ones) in payload.c and service.c.

> 
> I am trying to make sure we are doing the right design of RedfishPkg with
> respect to CrtLib for this use case.  Are these are JSON apps that do not use
> JsonLib, but are expected to build in an EDK II build environment? 
No, libredfish uses native jansson APIs.

>Would
> these JSON apps require more standard C lib services than the CrtLib used to
> build JsonLib?  Where would those additional C lib services come from?
CrtLib is created for both jansson and libredfish. C services are ready in CrtLib for both open source projects.
> 
> There is a standard C lib in edk2-libc.  Would that be required to build the
> JSON apps
No requirements for edk2-libc, at least for jansson and libredfish. And above two open source projects are what we need for Redfish.
Any other edk2 based JSON apps/drivers should use JsonLib.
> 
> In other uses of submodules with C lib dependencies, a new CrtLib like lib
> class was not added and instead the support was added directly to the EDK II
> wrapper APIs. Some examples are:
>   * MdeModulePkg\Library\BrotliCustomDecompressLib
>   * MdeModulePkg\Universal\RegularExpressionDxe
We have two libraries under RedfishPkg require CRT library. To have one instance for both makes sense to me.
> 
> If there are use cases where the CrtLib will be added to an INF outside the
> RedfishPkg, then I still think the name needs to be changed to be specific to
> the JSON use case.
No, CrtLib shouldn’t be published to outside RedfishPkg. That is only used for those two open source projects.

> If the use of CrtLib is only within the RedfishPkg, then the Library Class can be
> declared in a [LibraryClasses.Common.Private] section of the DEC file.  See
> UnitTestFrameworkPkg for examples.
I like this way. Will adopt this method and send v10 for review.

> 
> >
> > >   + JsonDumpString()
> > >     func header params do not match func prototype
> > >     Does not describe who allocates the return buffer and who
> > >     is responsible for freeing the buffer returned.
> > >     What do Flags do?  What is the difference between this
> > >     function and JsonToText()?
> > In JsonToText, it only converts JSON array and object to text. We
> > could just remove this for now because I don’t really remember the reason
> to create this function, it has been a while. Seems to me it is fine to remove
> this function.
> >
> > >   + JsonLoadBuffer() - Error param description missing
> > >   + JsonArrayGetValue() does not describe the conditions NULL
> > >     is returned.
> > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > >     function need to be called to free the array?
> > All above addressed.
> >
> > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > >     are asymmetric.  The Ascii one states that change will
> > >     modify the original string.  The Unicode one says that the
> > >     caller needs to free the returned string.  Any reason we
> > >     can not make them symmetric?
> > Jansson doesn't support Unicode string. The memory of the unicode
> > string returned by JsonValueGetUnicodeString Is allocated by
> UTF8StrToUCS2().
> >  > Also, if Ascii one should
> > >     not be modified, why isn’t the return type CONST?
> > Yes. will do that.
> >
> > >
> > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > >   + Change [Sources.common] to [Sources]
> > done
> > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > >   + Does this lib instance really depend on MdeModulePkg?
> > Yes, SortLib
> > >   + Have you reviewed the module types this lib instance is
> > >     compatible with?  Why does it need to support DXE_CORE?
> > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > >     If there are SMM use cases, then why is MM excluded?
> > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER. These
> are
> > module types have potential use cases I can think of now.
> > >
> > > * RedfishPkg/Library/JsonLib
> > >   + Readme.rst still has references to JanssonJsonLibMapping.h
> > done
> > >   + Have you reviewed the module types this lib instance is
> > >     compatible with?  Why does it need to support DXE_CORE?
> > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > >     If there are SMM use cases, then why is MM excluded?
> > Answered above
> > >   + JsonLib.inf has a [BuildOptions] section that disables some warnings
> that
> > >     make me concerned that this library may have some issues with
> > > 32-bit builds.
> > >     Have you fully validated all 32-bit CPU builds and validated the
> functionality
> > >     of all services from the JsonLib for all ranges of input values?
> > Yes, IA32 build is validated. But not validating on the
> > functionalities IA32. I don't have that use case, we can get back to fix the
> issue if any when  someone runs this on IA32.
> 
> I did some local testing with VS2019.  I found that a much smaller set of
> warning disables are required for IA32 and X64 and the set is different for
> IA32 and X64.  Can you review what is needed and minimize the required set
> of each supported arch?
> 
>   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
>   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090 /DHAVE_CONFIG_H=1
> /U_WIN32 /UWIN64 /U_MSC_VER
> 
> > >
> > > * RedfishLibs.dsc.inc
> > >   It is better to add [LibraryClasses] statement to this file, so it
> > >   can be include anywhere in a DSC file.  With current implementation
> > >   if it is not included within a [LibraryClasses] section, it will
> > >   generate a build error.
> > I will separate this to another set of patch. Don’t mix up with jansson edk2
> port.
> >
> > >You might also consider changing the name
> > >   of this file in case you want to add more than just lib mappings
> > >   to this file in the future.  See UnitTestFramworkPkg for examples.
> > >
> > > Best regards,
> > >
> > > Mike
> > >
> > > > -----Original Message-----
> > > > From: Abner Chang <abner.chang@hpe.com>
> > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > To: devel@edk2.groups.io
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > <leif@nuviainc.com>; Kinney, Michael D
> > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > <gaoliming@byosoft.com.cn>; Nickle Wang <nickle.wang@hpe.com>;
> > > Peter
> > > > O'Hanley <peter.ohanley@hpe.com>
> > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > > In v8, - Assigne patch file order
> > > >        - Add Acked-by tags
> > > > In v7, - Remove C RTC header files to under [Include.Common.Private]
> > > >          in RedfishPkg.dec.
> > > >        - address comments given by Mike Kinney.
> > > > In v6, Remove JanssonJsonMapping.h In v5, move BaseUcs2Utf8Lib to
> > > > under RedfishPkg.
> > > > In v4,
> > > >        - Address review comments
> > > >        - Seperate CRT functions to a individule library CrtLib under
> > > >          RedfishPkg.
> > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > >
> > > > In v3, Add jansson library as the required submoudle in
> > > >        CiSettings.py for CI test.
> > > > In v2, JsonLib is moved to under RedfishPkg.
> > > >
> > > > edk2 JSON library is based on jansson open source
> > > > (https://github.com/akheron/jansson) and wrapped as an edk2 library.
> > > > edk2 JsonLib will be used by edk2 Redfish feature drivers (not
> > > > contributed yet) and the edk2 port of libredfish library (not
> > > > contributed yet) based on DMTF GitHub
> > > > (https://github.com/DMTF/libredfish).
> > > >
> > > > Jansson is licensed under the MIT license(refer to ReadMe.rst under
> edk2).
> > > > It is used in production and its API is stable. In UEFI/EDKII
> > > > environment, Redfish project consumes jansson to achieve JSON
> > > operations.
> > > >
> > > > * Jansson version on edk2: 2.13.1
> > > >
> > > > * EDKII jansson library wrapper:
> > > >    - JsonLib.h:
> > > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > > >      jannson funcitons accordingly.
> > > >
> > > >    - JanssonJsonLibMapping.h:
> > > >      This is the wrapper file to map funcitons and definitions used in
> > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > >      modifications on native jannson applications to be built under
> > > >      edk2 environment.
> > > >
> > > > *Known issue:
> > > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > > >   The PR is submitted to jansson open source community.
> > > >   https://github.com/akheron/jansson/pull/558
> > > >
> > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > >
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > Cc: Andrew Fish <afish@apple.com>
> > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > >
> > > > Abner Chang (6):
> > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > >   edk2: jansson submodule for edk2 JSON library
> > > >   RedfishPkg/CrtLib: C runtime library
> > > >   RedfishPkg/library: EDK2 port of jansson library
> > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > >   .pytool: Add required submodule for JsonLib
> > > >
> > > >  .gitmodules                                   |    3 +
> > > >  .pytool/CISettings.py                         |    2 +
> > > >  ReadMe.rst                                    |    1 +
> > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
> > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > >  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
> > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > >  33 files changed, 4614 insertions(+)  create mode 100644
> > > > RedfishPkg/Include/Crt/assert.h  create mode
> > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > RedfishPkg/Include/Crt/sys/types.h
> > > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create mode
> > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > >  create mode 100644
> > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > >  create mode 100644
> > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
> > > >  create mode 100644
> > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > >
> > > > --
> > > > 2.17.1
> >


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-22 18:14     ` Michael D Kinney
  2020-12-23  3:42       ` Abner Chang
@ 2020-12-23  4:28       ` Abner Chang
  2020-12-23  4:39       ` Abner Chang
  2 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-23  4:28 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)



> -----Original Message-----
> From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> Sent: Wednesday, December 23, 2020 2:14 AM
> To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> Hi Abner,
> 
> A few comments below.
> 
> Best regards,
> 
> Mike
> 
> > -----Original Message-----
> > From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
> > Sent: Monday, December 21, 2020 12:17 AM
> > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > devel@edk2.groups.io
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> > Mike, response in below. Also v9 is sent.
> >
> > Thanks for review this in detail.
> > Abner
> >
> > > -----Original Message-----
> > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > Sent: Monday, December 21, 2020 3:43 AM
> > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > > Hi Abner,
> > >
> > > The include path in the [Include.Common.Private] section should not
> > > be in the same file path as the [Include] section.  This allows
> > > private include files to be accessed.
> > >
> > > Instead, you should create a new top level package directory called
> > > PrivateInclude and put all non-public include content in that
> > > directory.  The UnitTestFrameworkPkg is a good reference that
> > > demonstrates this design pattern.
> > Yes, this looks better. All Crt header files and CrtLib.h will be moved to
> under PrivateInclude.
> > >
> > > The library class name CrtLib is very generic and the library class
> > > is in the public includes so it is exported as a public interface from the
> RedfishPkg.
> > > This CrtLib implementation appears to be tuned to support the
> > > dependencies for the jansson submodule.  I recommend changing the
> > > library class name and the library instance name so it is clear that
> > > this CrtLib is only for jansson.
> > > Perhaps 'JanssonCrtLib'.
> > The CrtLib is not used by jannson lib, libredfish as well
> > (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a good
> naming, will keep that as it.
> >
> > >Also, does this library class (CrtLib.h) need to be  exported from
> > >RedfishPkg as a public interface?
> > No, it will be moved to under PrivateInclude.
> >
> > If CrtLib.h is defined as a private library and CrtLib.h is in
> > PrivateInclude which is not exposed to other packages, then why do we
> care about the naming of CrtLib is too generic? Which is the private library
> under RedfishPkg.
> > Move those header files to under PrivateInclude seems clear to people
> > that CrtLib is only for RedfishPkg. I think we don’t have to change the
> naming in this case.
> 
> In general I agree, but there is one place where the lib mapping has wider
> scope, and that is in a platform DSC file.  The lib class name CrtLib has to be
> listed in the DSC file.  If more than one package defines a library class called
> CrtLib, then the last mapping used will be used for all modules if it is listed in
> the [LibraryClasses] section of the DSC file.  The only was to handle this type
> of name collision is to use a module scoped library mapping in the
> <LibraryClasses> section of each individual module that uses a CrtLib.  I am
> only trying to avoid the potential for future name collisions for a library
> class/instance that is specific to the JSON use case.
> 
> We recognize that several modules in edk2 have this type of gasket between
> an EDK II env and a standard C lib.  We may find a we to implement a more
> generic gasket and retire the use of the implementation specific ones.  This is
> another reason to use an implementation specific name in this use case and
> be able to introduce a more generic name in the future.
> 
> Another comment below to see if there is a way to avoid introducing a CrtLib
> class.
> 
> >
> > >
> > > * RedfishPkg/Include/Library/CrtLib.h
> > >   + Remove reference to MDE_CPU_IA64.  This has been retired from
> > > the
> > > edk2 repo.
> > Ok.
> > >   + I do see one remaining reference to this in the CryptoPkg that need to
> be
> > >     removed.
> > >
> > > * RedfishPkg/Include/Library/JsonLib.h
> > >   + Some of the function descriptions are very brief and I can not tell
> > >     how to use the service from the description and more importantly, I
> > >     would not know how to write a unit test to verify the expected
> behavior.
> > >     Since these are a set of public APIs from this package that you
> > >     expect modules/libs from outside of RedfishPkg to use, then all of
> > >     these public APIs must be fully documented.
> > Most of the API in JsonLib are wrappers of native jansson APIs. We can
> > mention the URL to jansson API reference document in file header.
> > INVALID URI REMOVED
> 3A__jansson.readthedo
> >
> cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> SN6FZBN4
> > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > I will review all function header again,  please check v9 patch later.
> >
> > >   + Are there any of these APIs that are not really needed by modules/libs
> > >     outside the RedfishPkg?  It would be better to remove APIs that are
> > >     not needed outside RedfishPkg from this public include file.
> > >   + A couple examples that stood out are:
> > >     JsonDecreaseReference()
> > >     JsonIncreaseReference()
> > >     JsonObjectIterator()
> > >     JsonObjectIteratorValue()
> > >     JsonObjectIteratorNext()
> > The native jansson APIs of all above wrappers are used in libredfish.
> > So that is the potential use case for other JSON applications.
> 
> Can you provide a pointer to an example of this use case?
> 
> I am trying to make sure we are doing the right design of RedfishPkg with
> respect to CrtLib for this use case.  Are these are JSON apps that do not use
> JsonLib, but are expected to build in an EDK II build environment?  Would
> these JSON apps require more standard C lib services than the CrtLib used to
> build JsonLib?  Where would those additional C lib services come from?
> 
> There is a standard C lib in edk2-libc.  Would that be required to build the
> JSON apps.
> 
> In other uses of submodules with C lib dependencies, a new CrtLib like lib
> class was not added and instead the support was added directly to the EDK II
> wrapper APIs. Some examples are:
>   * MdeModulePkg\Library\BrotliCustomDecompressLib
>   * MdeModulePkg\Universal\RegularExpressionDxe
> 
> If there are use cases where the CrtLib will be added to an INF outside the
> RedfishPkg, then I still think the name needs to be changed to be specific to
> the JSON use case.
> 
> If the use of CrtLib is only within the RedfishPkg, then the Library Class can be
> declared in a [LibraryClasses.Common.Private] section of the DEC file.  See
> UnitTestFrameworkPkg for examples.
> 
> >
> > >   + JsonDumpString()
> > >     func header params do not match func prototype
> > >     Does not describe who allocates the return buffer and who
> > >     is responsible for freeing the buffer returned.
> > >     What do Flags do?  What is the difference between this
> > >     function and JsonToText()?
> > In JsonToText, it only converts JSON array and object to text. We
> > could just remove this for now because I don’t really remember the reason
> to create this function, it has been a while. Seems to me it is fine to remove
> this function.
> >
> > >   + JsonLoadBuffer() - Error param description missing
> > >   + JsonArrayGetValue() does not describe the conditions NULL
> > >     is returned.
> > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > >     function need to be called to free the array?
> > All above addressed.
> >
> > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > >     are asymmetric.  The Ascii one states that change will
> > >     modify the original string.  The Unicode one says that the
> > >     caller needs to free the returned string.  Any reason we
> > >     can not make them symmetric?
> > Jansson doesn't support Unicode string. The memory of the unicode
> > string returned by JsonValueGetUnicodeString Is allocated by
> UTF8StrToUCS2().
> >  > Also, if Ascii one should
> > >     not be modified, why isn’t the return type CONST?
> > Yes. will do that.
> >
> > >
> > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > >   + Change [Sources.common] to [Sources]
> > done
> > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > >   + Does this lib instance really depend on MdeModulePkg?
> > Yes, SortLib
> > >   + Have you reviewed the module types this lib instance is
> > >     compatible with?  Why does it need to support DXE_CORE?
> > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > >     If there are SMM use cases, then why is MM excluded?
> > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER. These
> are
> > module types have potential use cases I can think of now.
> > >
> > > * RedfishPkg/Library/JsonLib
> > >   + Readme.rst still has references to JanssonJsonLibMapping.h
> > done
> > >   + Have you reviewed the module types this lib instance is
> > >     compatible with?  Why does it need to support DXE_CORE?
> > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > >     If there are SMM use cases, then why is MM excluded?
> > Answered above
> > >   + JsonLib.inf has a [BuildOptions] section that disables some warnings
> that
> > >     make me concerned that this library may have some issues with
> > > 32-bit builds.
> > >     Have you fully validated all 32-bit CPU builds and validated the
> functionality
> > >     of all services from the JsonLib for all ranges of input values?
> > Yes, IA32 build is validated. But not validating on the
> > functionalities IA32. I don't have that use case, we can get back to fix the
> issue if any when  someone runs this on IA32.
> 
> I did some local testing with VS2019.  I found that a much smaller set of
> warning disables are required for IA32 and X64 and the set is different for
> IA32 and X64.  Can you review what is needed and minimize the required set
> of each supported arch?
> 
>   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
>   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090 /DHAVE_CONFIG_H=1
> /U_WIN32 /UWIN64 /U_MSC_VER
Ok
Abner
> 
> > >
> > > * RedfishLibs.dsc.inc
> > >   It is better to add [LibraryClasses] statement to this file, so it
> > >   can be include anywhere in a DSC file.  With current implementation
> > >   if it is not included within a [LibraryClasses] section, it will
> > >   generate a build error.
> > I will separate this to another set of patch. Don’t mix up with jansson edk2
> port.
> >
> > >You might also consider changing the name
> > >   of this file in case you want to add more than just lib mappings
> > >   to this file in the future.  See UnitTestFramworkPkg for examples.
> > >
> > > Best regards,
> > >
> > > Mike
> > >
> > > > -----Original Message-----
> > > > From: Abner Chang <abner.chang@hpe.com>
> > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > To: devel@edk2.groups.io
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > <leif@nuviainc.com>; Kinney, Michael D
> > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > <gaoliming@byosoft.com.cn>; Nickle Wang <nickle.wang@hpe.com>;
> > > Peter
> > > > O'Hanley <peter.ohanley@hpe.com>
> > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > > In v8, - Assigne patch file order
> > > >        - Add Acked-by tags
> > > > In v7, - Remove C RTC header files to under [Include.Common.Private]
> > > >          in RedfishPkg.dec.
> > > >        - address comments given by Mike Kinney.
> > > > In v6, Remove JanssonJsonMapping.h In v5, move BaseUcs2Utf8Lib to
> > > > under RedfishPkg.
> > > > In v4,
> > > >        - Address review comments
> > > >        - Seperate CRT functions to a individule library CrtLib under
> > > >          RedfishPkg.
> > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > >
> > > > In v3, Add jansson library as the required submoudle in
> > > >        CiSettings.py for CI test.
> > > > In v2, JsonLib is moved to under RedfishPkg.
> > > >
> > > > edk2 JSON library is based on jansson open source
> > > > (https://github.com/akheron/jansson) and wrapped as an edk2 library.
> > > > edk2 JsonLib will be used by edk2 Redfish feature drivers (not
> > > > contributed yet) and the edk2 port of libredfish library (not
> > > > contributed yet) based on DMTF GitHub
> > > > (https://github.com/DMTF/libredfish).
> > > >
> > > > Jansson is licensed under the MIT license(refer to ReadMe.rst under
> edk2).
> > > > It is used in production and its API is stable. In UEFI/EDKII
> > > > environment, Redfish project consumes jansson to achieve JSON
> > > operations.
> > > >
> > > > * Jansson version on edk2: 2.13.1
> > > >
> > > > * EDKII jansson library wrapper:
> > > >    - JsonLib.h:
> > > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > > >      jannson funcitons accordingly.
> > > >
> > > >    - JanssonJsonLibMapping.h:
> > > >      This is the wrapper file to map funcitons and definitions used in
> > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > >      modifications on native jannson applications to be built under
> > > >      edk2 environment.
> > > >
> > > > *Known issue:
> > > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > > >   The PR is submitted to jansson open source community.
> > > >   https://github.com/akheron/jansson/pull/558
> > > >
> > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > >
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > Cc: Andrew Fish <afish@apple.com>
> > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > >
> > > > Abner Chang (6):
> > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > >   edk2: jansson submodule for edk2 JSON library
> > > >   RedfishPkg/CrtLib: C runtime library
> > > >   RedfishPkg/library: EDK2 port of jansson library
> > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > >   .pytool: Add required submodule for JsonLib
> > > >
> > > >  .gitmodules                                   |    3 +
> > > >  .pytool/CISettings.py                         |    2 +
> > > >  ReadMe.rst                                    |    1 +
> > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
> > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > >  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
> > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > >  33 files changed, 4614 insertions(+)  create mode 100644
> > > > RedfishPkg/Include/Crt/assert.h  create mode
> > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > RedfishPkg/Include/Crt/sys/types.h
> > > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create mode
> > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > >  create mode 100644
> > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > >  create mode 100644
> > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
> > > >  create mode 100644
> > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > >
> > > > --
> > > > 2.17.1
> >


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-22 18:14     ` Michael D Kinney
  2020-12-23  3:42       ` Abner Chang
  2020-12-23  4:28       ` Abner Chang
@ 2020-12-23  4:39       ` Abner Chang
  2020-12-23  6:10         ` Michael D Kinney
  2 siblings, 1 reply; 19+ messages in thread
From: Abner Chang @ 2020-12-23  4:39 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)



> -----Original Message-----
> From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> Sent: Wednesday, December 23, 2020 2:14 AM
> To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> Hi Abner,
> 
> A few comments below.
> 
> Best regards,
> 
> Mike
> 
> > -----Original Message-----
> > From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
> > Sent: Monday, December 21, 2020 12:17 AM
> > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > devel@edk2.groups.io
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> > Mike, response in below. Also v9 is sent.
> >
> > Thanks for review this in detail.
> > Abner
> >
> > > -----Original Message-----
> > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > Sent: Monday, December 21, 2020 3:43 AM
> > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > > Hi Abner,
> > >
> > > The include path in the [Include.Common.Private] section should not
> > > be in the same file path as the [Include] section.  This allows
> > > private include files to be accessed.
> > >
> > > Instead, you should create a new top level package directory called
> > > PrivateInclude and put all non-public include content in that
> > > directory.  The UnitTestFrameworkPkg is a good reference that
> > > demonstrates this design pattern.
> > Yes, this looks better. All Crt header files and CrtLib.h will be moved to
> under PrivateInclude.
> > >
> > > The library class name CrtLib is very generic and the library class
> > > is in the public includes so it is exported as a public interface from the
> RedfishPkg.
> > > This CrtLib implementation appears to be tuned to support the
> > > dependencies for the jansson submodule.  I recommend changing the
> > > library class name and the library instance name so it is clear that
> > > this CrtLib is only for jansson.
> > > Perhaps 'JanssonCrtLib'.
> > The CrtLib is not used by jannson lib, libredfish as well
> > (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a good
> naming, will keep that as it.
> >
> > >Also, does this library class (CrtLib.h) need to be  exported from
> > >RedfishPkg as a public interface?
> > No, it will be moved to under PrivateInclude.
> >
> > If CrtLib.h is defined as a private library and CrtLib.h is in
> > PrivateInclude which is not exposed to other packages, then why do we
> care about the naming of CrtLib is too generic? Which is the private library
> under RedfishPkg.
> > Move those header files to under PrivateInclude seems clear to people
> > that CrtLib is only for RedfishPkg. I think we don’t have to change the
> naming in this case.
> 
> In general I agree, but there is one place where the lib mapping has wider
> scope, and that is in a platform DSC file.  The lib class name CrtLib has to be
> listed in the DSC file.  If more than one package defines a library class called
> CrtLib, then the last mapping used will be used for all modules if it is listed in
> the [LibraryClasses] section of the DSC file.  The only was to handle this type
> of name collision is to use a module scoped library mapping in the
> <LibraryClasses> section of each individual module that uses a CrtLib.  I am
> only trying to avoid the potential for future name collisions for a library
> class/instance that is specific to the JSON use case.
> 
> We recognize that several modules in edk2 have this type of gasket between
> an EDK II env and a standard C lib.  We may find a we to implement a more
> generic gasket and retire the use of the implementation specific ones.  This is
> another reason to use an implementation specific name in this use case and
> be able to introduce a more generic name in the future.
> 
> Another comment below to see if there is a way to avoid introducing a CrtLib
> class.
> 
> >
> > >
> > > * RedfishPkg/Include/Library/CrtLib.h
> > >   + Remove reference to MDE_CPU_IA64.  This has been retired from
> > > the
> > > edk2 repo.
> > Ok.
> > >   + I do see one remaining reference to this in the CryptoPkg that need to
> be
> > >     removed.
> > >
> > > * RedfishPkg/Include/Library/JsonLib.h
> > >   + Some of the function descriptions are very brief and I can not tell
> > >     how to use the service from the description and more importantly, I
> > >     would not know how to write a unit test to verify the expected
> behavior.
> > >     Since these are a set of public APIs from this package that you
> > >     expect modules/libs from outside of RedfishPkg to use, then all of
> > >     these public APIs must be fully documented.
> > Most of the API in JsonLib are wrappers of native jansson APIs. We can
> > mention the URL to jansson API reference document in file header.
> > INVALID URI REMOVED
> 3A__jansson.readthedo
> >
> cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> SN6FZBN4
> > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > I will review all function header again,  please check v9 patch later.
> >
> > >   + Are there any of these APIs that are not really needed by modules/libs
> > >     outside the RedfishPkg?  It would be better to remove APIs that are
> > >     not needed outside RedfishPkg from this public include file.
> > >   + A couple examples that stood out are:
> > >     JsonDecreaseReference()
> > >     JsonIncreaseReference()
> > >     JsonObjectIterator()
> > >     JsonObjectIteratorValue()
> > >     JsonObjectIteratorNext()
> > The native jansson APIs of all above wrappers are used in libredfish.
> > So that is the potential use case for other JSON applications.
> 
> Can you provide a pointer to an example of this use case?
> 
> I am trying to make sure we are doing the right design of RedfishPkg with
> respect to CrtLib for this use case.  Are these are JSON apps that do not use
> JsonLib, but are expected to build in an EDK II build environment?  Would
> these JSON apps require more standard C lib services than the CrtLib used to
> build JsonLib?  Where would those additional C lib services come from?
> 
> There is a standard C lib in edk2-libc.  Would that be required to build the
> JSON apps.
> 
> In other uses of submodules with C lib dependencies, a new CrtLib like lib
> class was not added and instead the support was added directly to the EDK II
> wrapper APIs. Some examples are:
>   * MdeModulePkg\Library\BrotliCustomDecompressLib
>   * MdeModulePkg\Universal\RegularExpressionDxe
> 
> If there are use cases where the CrtLib will be added to an INF outside the
> RedfishPkg, then I still think the name needs to be changed to be specific to
> the JSON use case.
CrtLib should not be added to INF outside RedfishPkg, but it will be added to platform DSC file.
> 
> If the use of CrtLib is only within the RedfishPkg, then the Library Class can be
> declared in a [LibraryClasses.Common.Private] section of the DEC file.  See
> UnitTestFrameworkPkg for examples
Because CrtLib, JsonLib and other RedfishPkg modules will be included in other package dsc file (e.g. EmulatorPkg).
What if in EmulatorPkg one CrtLib libraryclass maps to the private one under RedfishPkg, but another with the same name is the public library provided by other package (e.g. MdeModulePkg) and used by modules other than RedfishPkg?
Is edk2 build tool that smart to link the private CrtLib for RedfishPkg modules and all other non RedfishPkg modules are linked with the public one?

Abner

> 
> >
> > >   + JsonDumpString()
> > >     func header params do not match func prototype
> > >     Does not describe who allocates the return buffer and who
> > >     is responsible for freeing the buffer returned.
> > >     What do Flags do?  What is the difference between this
> > >     function and JsonToText()?
> > In JsonToText, it only converts JSON array and object to text. We
> > could just remove this for now because I don’t really remember the reason
> to create this function, it has been a while. Seems to me it is fine to remove
> this function.
> >
> > >   + JsonLoadBuffer() - Error param description missing
> > >   + JsonArrayGetValue() does not describe the conditions NULL
> > >     is returned.
> > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > >     function need to be called to free the array?
> > All above addressed.
> >
> > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > >     are asymmetric.  The Ascii one states that change will
> > >     modify the original string.  The Unicode one says that the
> > >     caller needs to free the returned string.  Any reason we
> > >     can not make them symmetric?
> > Jansson doesn't support Unicode string. The memory of the unicode
> > string returned by JsonValueGetUnicodeString Is allocated by
> UTF8StrToUCS2().
> >  > Also, if Ascii one should
> > >     not be modified, why isn’t the return type CONST?
> > Yes. will do that.
> >
> > >
> > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > >   + Change [Sources.common] to [Sources]
> > done
> > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > >   + Does this lib instance really depend on MdeModulePkg?
> > Yes, SortLib
> > >   + Have you reviewed the module types this lib instance is
> > >     compatible with?  Why does it need to support DXE_CORE?
> > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > >     If there are SMM use cases, then why is MM excluded?
> > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER. These
> are
> > module types have potential use cases I can think of now.
> > >
> > > * RedfishPkg/Library/JsonLib
> > >   + Readme.rst still has references to JanssonJsonLibMapping.h
> > done
> > >   + Have you reviewed the module types this lib instance is
> > >     compatible with?  Why does it need to support DXE_CORE?
> > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > >     If there are SMM use cases, then why is MM excluded?
> > Answered above
> > >   + JsonLib.inf has a [BuildOptions] section that disables some warnings
> that
> > >     make me concerned that this library may have some issues with
> > > 32-bit builds.
> > >     Have you fully validated all 32-bit CPU builds and validated the
> functionality
> > >     of all services from the JsonLib for all ranges of input values?
> > Yes, IA32 build is validated. But not validating on the
> > functionalities IA32. I don't have that use case, we can get back to fix the
> issue if any when  someone runs this on IA32.
> 
> I did some local testing with VS2019.  I found that a much smaller set of
> warning disables are required for IA32 and X64 and the set is different for
> IA32 and X64.  Can you review what is needed and minimize the required set
> of each supported arch?
> 
>   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
>   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090 /DHAVE_CONFIG_H=1
> /U_WIN32 /UWIN64 /U_MSC_VER
> 
> > >
> > > * RedfishLibs.dsc.inc
> > >   It is better to add [LibraryClasses] statement to this file, so it
> > >   can be include anywhere in a DSC file.  With current implementation
> > >   if it is not included within a [LibraryClasses] section, it will
> > >   generate a build error.
> > I will separate this to another set of patch. Don’t mix up with jansson edk2
> port.
> >
> > >You might also consider changing the name
> > >   of this file in case you want to add more than just lib mappings
> > >   to this file in the future.  See UnitTestFramworkPkg for examples.
> > >
> > > Best regards,
> > >
> > > Mike
> > >
> > > > -----Original Message-----
> > > > From: Abner Chang <abner.chang@hpe.com>
> > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > To: devel@edk2.groups.io
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > <leif@nuviainc.com>; Kinney, Michael D
> > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > <gaoliming@byosoft.com.cn>; Nickle Wang <nickle.wang@hpe.com>;
> > > Peter
> > > > O'Hanley <peter.ohanley@hpe.com>
> > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > > In v8, - Assigne patch file order
> > > >        - Add Acked-by tags
> > > > In v7, - Remove C RTC header files to under [Include.Common.Private]
> > > >          in RedfishPkg.dec.
> > > >        - address comments given by Mike Kinney.
> > > > In v6, Remove JanssonJsonMapping.h In v5, move BaseUcs2Utf8Lib to
> > > > under RedfishPkg.
> > > > In v4,
> > > >        - Address review comments
> > > >        - Seperate CRT functions to a individule library CrtLib under
> > > >          RedfishPkg.
> > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > >
> > > > In v3, Add jansson library as the required submoudle in
> > > >        CiSettings.py for CI test.
> > > > In v2, JsonLib is moved to under RedfishPkg.
> > > >
> > > > edk2 JSON library is based on jansson open source
> > > > (https://github.com/akheron/jansson) and wrapped as an edk2 library.
> > > > edk2 JsonLib will be used by edk2 Redfish feature drivers (not
> > > > contributed yet) and the edk2 port of libredfish library (not
> > > > contributed yet) based on DMTF GitHub
> > > > (https://github.com/DMTF/libredfish).
> > > >
> > > > Jansson is licensed under the MIT license(refer to ReadMe.rst under
> edk2).
> > > > It is used in production and its API is stable. In UEFI/EDKII
> > > > environment, Redfish project consumes jansson to achieve JSON
> > > operations.
> > > >
> > > > * Jansson version on edk2: 2.13.1
> > > >
> > > > * EDKII jansson library wrapper:
> > > >    - JsonLib.h:
> > > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > > >      jannson funcitons accordingly.
> > > >
> > > >    - JanssonJsonLibMapping.h:
> > > >      This is the wrapper file to map funcitons and definitions used in
> > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > >      modifications on native jannson applications to be built under
> > > >      edk2 environment.
> > > >
> > > > *Known issue:
> > > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > > >   The PR is submitted to jansson open source community.
> > > >   https://github.com/akheron/jansson/pull/558
> > > >
> > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > >
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > Cc: Andrew Fish <afish@apple.com>
> > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > >
> > > > Abner Chang (6):
> > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > >   edk2: jansson submodule for edk2 JSON library
> > > >   RedfishPkg/CrtLib: C runtime library
> > > >   RedfishPkg/library: EDK2 port of jansson library
> > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > >   .pytool: Add required submodule for JsonLib
> > > >
> > > >  .gitmodules                                   |    3 +
> > > >  .pytool/CISettings.py                         |    2 +
> > > >  ReadMe.rst                                    |    1 +
> > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
> > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > >  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
> > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > >  33 files changed, 4614 insertions(+)  create mode 100644
> > > > RedfishPkg/Include/Crt/assert.h  create mode
> > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > RedfishPkg/Include/Crt/sys/types.h
> > > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create mode
> > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > >  create mode 100644
> > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > >  create mode 100644
> > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
> > > >  create mode 100644
> > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > >
> > > > --
> > > > 2.17.1
> >


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-23  4:39       ` Abner Chang
@ 2020-12-23  6:10         ` Michael D Kinney
  2020-12-23  7:53           ` Abner Chang
  0 siblings, 1 reply; 19+ messages in thread
From: Michael D Kinney @ 2020-12-23  6:10 UTC (permalink / raw)
  To: Chang, Abner (HPS SW/FW Technologist), devel@edk2.groups.io,
	Kinney, Michael D
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)

Hi Abner,

Response below.

Mike


> -----Original Message-----
> From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
> Sent: Tuesday, December 22, 2020 8:40 PM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle
> (HPS SW) <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> 
> 
> > -----Original Message-----
> > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > Sent: Wednesday, December 23, 2020 2:14 AM
> > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> > <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> > Hi Abner,
> >
> > A few comments below.
> >
> > Best regards,
> >
> > Mike
> >
> > > -----Original Message-----
> > > From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
> > > Sent: Monday, December 21, 2020 12:17 AM
> > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > devel@edk2.groups.io
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > > Mike, response in below. Also v9 is sent.
> > >
> > > Thanks for review this in detail.
> > > Abner
> > >
> > > > -----Original Message-----
> > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > Sent: Monday, December 21, 2020 3:43 AM
> > > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > Laszlo
> > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > <peter.ohanley@hpe.com>
> > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > > Hi Abner,
> > > >
> > > > The include path in the [Include.Common.Private] section should not
> > > > be in the same file path as the [Include] section.  This allows
> > > > private include files to be accessed.
> > > >
> > > > Instead, you should create a new top level package directory called
> > > > PrivateInclude and put all non-public include content in that
> > > > directory.  The UnitTestFrameworkPkg is a good reference that
> > > > demonstrates this design pattern.
> > > Yes, this looks better. All Crt header files and CrtLib.h will be moved to
> > under PrivateInclude.
> > > >
> > > > The library class name CrtLib is very generic and the library class
> > > > is in the public includes so it is exported as a public interface from the
> > RedfishPkg.
> > > > This CrtLib implementation appears to be tuned to support the
> > > > dependencies for the jansson submodule.  I recommend changing the
> > > > library class name and the library instance name so it is clear that
> > > > this CrtLib is only for jansson.
> > > > Perhaps 'JanssonCrtLib'.
> > > The CrtLib is not used by jannson lib, libredfish as well
> > > (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a good
> > naming, will keep that as it.
> > >
> > > >Also, does this library class (CrtLib.h) need to be  exported from
> > > >RedfishPkg as a public interface?
> > > No, it will be moved to under PrivateInclude.
> > >
> > > If CrtLib.h is defined as a private library and CrtLib.h is in
> > > PrivateInclude which is not exposed to other packages, then why do we
> > care about the naming of CrtLib is too generic? Which is the private library
> > under RedfishPkg.
> > > Move those header files to under PrivateInclude seems clear to people
> > > that CrtLib is only for RedfishPkg. I think we don’t have to change the
> > naming in this case.
> >
> > In general I agree, but there is one place where the lib mapping has wider
> > scope, and that is in a platform DSC file.  The lib class name CrtLib has to be
> > listed in the DSC file.  If more than one package defines a library class called
> > CrtLib, then the last mapping used will be used for all modules if it is listed in
> > the [LibraryClasses] section of the DSC file.  The only was to handle this type
> > of name collision is to use a module scoped library mapping in the
> > <LibraryClasses> section of each individual module that uses a CrtLib.  I am
> > only trying to avoid the potential for future name collisions for a library
> > class/instance that is specific to the JSON use case.
> >
> > We recognize that several modules in edk2 have this type of gasket between
> > an EDK II env and a standard C lib.  We may find a we to implement a more
> > generic gasket and retire the use of the implementation specific ones.  This is
> > another reason to use an implementation specific name in this use case and
> > be able to introduce a more generic name in the future.
> >
> > Another comment below to see if there is a way to avoid introducing a CrtLib
> > class.
> >
> > >
> > > >
> > > > * RedfishPkg/Include/Library/CrtLib.h
> > > >   + Remove reference to MDE_CPU_IA64.  This has been retired from
> > > > the
> > > > edk2 repo.
> > > Ok.
> > > >   + I do see one remaining reference to this in the CryptoPkg that need to
> > be
> > > >     removed.
> > > >
> > > > * RedfishPkg/Include/Library/JsonLib.h
> > > >   + Some of the function descriptions are very brief and I can not tell
> > > >     how to use the service from the description and more importantly, I
> > > >     would not know how to write a unit test to verify the expected
> > behavior.
> > > >     Since these are a set of public APIs from this package that you
> > > >     expect modules/libs from outside of RedfishPkg to use, then all of
> > > >     these public APIs must be fully documented.
> > > Most of the API in JsonLib are wrappers of native jansson APIs. We can
> > > mention the URL to jansson API reference document in file header.
> > > https://urldefense.proofpoint.com/v2/url?u=https-
> > 3A__jansson.readthedo
> > >
> > cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> > SN6FZBN4
> > > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> > uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > > zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > > I will review all function header again,  please check v9 patch later.
> > >
> > > >   + Are there any of these APIs that are not really needed by modules/libs
> > > >     outside the RedfishPkg?  It would be better to remove APIs that are
> > > >     not needed outside RedfishPkg from this public include file.
> > > >   + A couple examples that stood out are:
> > > >     JsonDecreaseReference()
> > > >     JsonIncreaseReference()
> > > >     JsonObjectIterator()
> > > >     JsonObjectIteratorValue()
> > > >     JsonObjectIteratorNext()
> > > The native jansson APIs of all above wrappers are used in libredfish.
> > > So that is the potential use case for other JSON applications.
> >
> > Can you provide a pointer to an example of this use case?
> >
> > I am trying to make sure we are doing the right design of RedfishPkg with
> > respect to CrtLib for this use case.  Are these are JSON apps that do not use
> > JsonLib, but are expected to build in an EDK II build environment?  Would
> > these JSON apps require more standard C lib services than the CrtLib used to
> > build JsonLib?  Where would those additional C lib services come from?
> >
> > There is a standard C lib in edk2-libc.  Would that be required to build the
> > JSON apps.
> >
> > In other uses of submodules with C lib dependencies, a new CrtLib like lib
> > class was not added and instead the support was added directly to the EDK II
> > wrapper APIs. Some examples are:
> >   * MdeModulePkg\Library\BrotliCustomDecompressLib
> >   * MdeModulePkg\Universal\RegularExpressionDxe
> >
> > If there are use cases where the CrtLib will be added to an INF outside the
> > RedfishPkg, then I still think the name needs to be changed to be specific to
> > the JSON use case.
> CrtLib should not be added to INF outside RedfishPkg, but it will be added to platform DSC file.
> >
> > If the use of CrtLib is only within the RedfishPkg, then the Library Class can be
> > declared in a [LibraryClasses.Common.Private] section of the DEC file.  See
> > UnitTestFrameworkPkg for examples
> Because CrtLib, JsonLib and other RedfishPkg modules will be included in other package dsc file (e.g. EmulatorPkg).
> What if in EmulatorPkg one CrtLib libraryclass maps to the private one under RedfishPkg, but another with the same name is
> the public library provided by other package (e.g. MdeModulePkg) and used by modules other than RedfishPkg?
> Is edk2 build tool that smart to link the private CrtLib for RedfishPkg modules and all other non RedfishPkg modules are
> linked with the public one?
> 
> Abner
> 

No.  Not that smart.

There are global lib class -> lib instance mapping in [LibraryClasses] sections of DSC files.  If the same lib class
is listed more than once, then the last mapping wins.

If a module scoped <LibraryClasses> section is used, then then last mapping in the scope of that module wins.

If the same lib class name is declared by more than one package used in a platform DSC, then the only
remediation is to remove use of the global [LibraryClasses] section and use a module scope <LibraryClasses>
section in every module that depends on that lib class name.

> >
> > >
> > > >   + JsonDumpString()
> > > >     func header params do not match func prototype
> > > >     Does not describe who allocates the return buffer and who
> > > >     is responsible for freeing the buffer returned.
> > > >     What do Flags do?  What is the difference between this
> > > >     function and JsonToText()?
> > > In JsonToText, it only converts JSON array and object to text. We
> > > could just remove this for now because I don’t really remember the reason
> > to create this function, it has been a while. Seems to me it is fine to remove
> > this function.
> > >
> > > >   + JsonLoadBuffer() - Error param description missing
> > > >   + JsonArrayGetValue() does not describe the conditions NULL
> > > >     is returned.
> > > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > > >     function need to be called to free the array?
> > > All above addressed.
> > >
> > > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > > >     are asymmetric.  The Ascii one states that change will
> > > >     modify the original string.  The Unicode one says that the
> > > >     caller needs to free the returned string.  Any reason we
> > > >     can not make them symmetric?
> > > Jansson doesn't support Unicode string. The memory of the unicode
> > > string returned by JsonValueGetUnicodeString Is allocated by
> > UTF8StrToUCS2().
> > >  > Also, if Ascii one should
> > > >     not be modified, why isn’t the return type CONST?
> > > Yes. will do that.
> > >
> > > >
> > > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > >   + Change [Sources.common] to [Sources]
> > > done
> > > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > > >   + Does this lib instance really depend on MdeModulePkg?
> > > Yes, SortLib
> > > >   + Have you reviewed the module types this lib instance is
> > > >     compatible with?  Why does it need to support DXE_CORE?
> > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > >     If there are SMM use cases, then why is MM excluded?
> > > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER. These
> > are
> > > module types have potential use cases I can think of now.
> > > >
> > > > * RedfishPkg/Library/JsonLib
> > > >   + Readme.rst still has references to JanssonJsonLibMapping.h
> > > done
> > > >   + Have you reviewed the module types this lib instance is
> > > >     compatible with?  Why does it need to support DXE_CORE?
> > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > >     If there are SMM use cases, then why is MM excluded?
> > > Answered above
> > > >   + JsonLib.inf has a [BuildOptions] section that disables some warnings
> > that
> > > >     make me concerned that this library may have some issues with
> > > > 32-bit builds.
> > > >     Have you fully validated all 32-bit CPU builds and validated the
> > functionality
> > > >     of all services from the JsonLib for all ranges of input values?
> > > Yes, IA32 build is validated. But not validating on the
> > > functionalities IA32. I don't have that use case, we can get back to fix the
> > issue if any when  someone runs this on IA32.
> >
> > I did some local testing with VS2019.  I found that a much smaller set of
> > warning disables are required for IA32 and X64 and the set is different for
> > IA32 and X64.  Can you review what is needed and minimize the required set
> > of each supported arch?
> >
> >   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> > /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
> >   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090 /DHAVE_CONFIG_H=1
> > /U_WIN32 /UWIN64 /U_MSC_VER
> >
> > > >
> > > > * RedfishLibs.dsc.inc
> > > >   It is better to add [LibraryClasses] statement to this file, so it
> > > >   can be include anywhere in a DSC file.  With current implementation
> > > >   if it is not included within a [LibraryClasses] section, it will
> > > >   generate a build error.
> > > I will separate this to another set of patch. Don’t mix up with jansson edk2
> > port.
> > >
> > > >You might also consider changing the name
> > > >   of this file in case you want to add more than just lib mappings
> > > >   to this file in the future.  See UnitTestFramworkPkg for examples.
> > > >
> > > > Best regards,
> > > >
> > > > Mike
> > > >
> > > > > -----Original Message-----
> > > > > From: Abner Chang <abner.chang@hpe.com>
> > > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > > To: devel@edk2.groups.io
> > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > > <leif@nuviainc.com>; Kinney, Michael D
> > > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > > <gaoliming@byosoft.com.cn>; Nickle Wang <nickle.wang@hpe.com>;
> > > > Peter
> > > > > O'Hanley <peter.ohanley@hpe.com>
> > > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > > >
> > > > > In v8, - Assigne patch file order
> > > > >        - Add Acked-by tags
> > > > > In v7, - Remove C RTC header files to under [Include.Common.Private]
> > > > >          in RedfishPkg.dec.
> > > > >        - address comments given by Mike Kinney.
> > > > > In v6, Remove JanssonJsonMapping.h In v5, move BaseUcs2Utf8Lib to
> > > > > under RedfishPkg.
> > > > > In v4,
> > > > >        - Address review comments
> > > > >        - Seperate CRT functions to a individule library CrtLib under
> > > > >          RedfishPkg.
> > > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > > >
> > > > > In v3, Add jansson library as the required submoudle in
> > > > >        CiSettings.py for CI test.
> > > > > In v2, JsonLib is moved to under RedfishPkg.
> > > > >
> > > > > edk2 JSON library is based on jansson open source
> > > > > (https://github.com/akheron/jansson) and wrapped as an edk2 library.
> > > > > edk2 JsonLib will be used by edk2 Redfish feature drivers (not
> > > > > contributed yet) and the edk2 port of libredfish library (not
> > > > > contributed yet) based on DMTF GitHub
> > > > > (https://github.com/DMTF/libredfish).
> > > > >
> > > > > Jansson is licensed under the MIT license(refer to ReadMe.rst under
> > edk2).
> > > > > It is used in production and its API is stable. In UEFI/EDKII
> > > > > environment, Redfish project consumes jansson to achieve JSON
> > > > operations.
> > > > >
> > > > > * Jansson version on edk2: 2.13.1
> > > > >
> > > > > * EDKII jansson library wrapper:
> > > > >    - JsonLib.h:
> > > > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > > > >      jannson funcitons accordingly.
> > > > >
> > > > >    - JanssonJsonLibMapping.h:
> > > > >      This is the wrapper file to map funcitons and definitions used in
> > > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > > >      modifications on native jannson applications to be built under
> > > > >      edk2 environment.
> > > > >
> > > > > *Known issue:
> > > > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > > > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > > > >   The PR is submitted to jansson open source community.
> > > > >   https://github.com/akheron/jansson/pull/558
> > > > >
> > > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > > >
> > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > > Cc: Andrew Fish <afish@apple.com>
> > > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > > >
> > > > > Abner Chang (6):
> > > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > > >   edk2: jansson submodule for edk2 JSON library
> > > > >   RedfishPkg/CrtLib: C runtime library
> > > > >   RedfishPkg/library: EDK2 port of jansson library
> > > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > > >   .pytool: Add required submodule for JsonLib
> > > > >
> > > > >  .gitmodules                                   |    3 +
> > > > >  .pytool/CISettings.py                         |    2 +
> > > > >  ReadMe.rst                                    |    1 +
> > > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
> > > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > > >  RedfishPkg/Library/JsonLib/load.c             | 1111 +++++++++++++++++
> > > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > > >  33 files changed, 4614 insertions(+)  create mode 100644
> > > > > RedfishPkg/Include/Crt/assert.h  create mode
> > > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > > RedfishPkg/Include/Crt/sys/types.h
> > > > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create mode
> > > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > > >  create mode 100644
> > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > > >  create mode 100644
> > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > > > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > > >  create mode 100644 RedfishPkg/Library/JsonLib/jansson_config.h
> > > > >  create mode 100644
> > > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > > >
> > > > > --
> > > > > 2.17.1
> > >
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-23  6:10         ` Michael D Kinney
@ 2020-12-23  7:53           ` Abner Chang
  2020-12-23  9:02             ` Abner Chang
  0 siblings, 1 reply; 19+ messages in thread
From: Abner Chang @ 2020-12-23  7:53 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)



> -----Original Message-----
> From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> Sent: Wednesday, December 23, 2020 2:10 PM
> To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> Hi Abner,
> 
> Response below.
> 
> Mike
> 
> 
> > -----Original Message-----
> > From: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>
> > Sent: Tuesday, December 22, 2020 8:40 PM
> > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > devel@edk2.groups.io
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> >
> >
> > > -----Original Message-----
> > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > Sent: Wednesday, December 23, 2020 2:14 AM
> > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > > Hi Abner,
> > >
> > > A few comments below.
> > >
> > > Best regards,
> > >
> > > Mike
> > >
> > > > -----Original Message-----
> > > > From: Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>
> > > > Sent: Monday, December 21, 2020 12:17 AM
> > > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > > devel@edk2.groups.io
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > <leif@nuviainc.com>; Liming Gao <gaoliming@byosoft.com.cn>; Wang,
> > > > Nickle (HPS SW) <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > <peter.ohanley@hpe.com>
> > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > > Mike, response in below. Also v9 is sent.
> > > >
> > > > Thanks for review this in detail.
> > > > Abner
> > > >
> > > > > -----Original Message-----
> > > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > > Sent: Monday, December 21, 2020 3:43 AM
> > > > > To: Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>;
> > > > > devel@edk2.groups.io; Kinney, Michael D
> > > > > <michael.d.kinney@intel.com>
> > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > Laszlo
> > > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
> > > > > Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > <peter.ohanley@hpe.com>
> > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > >
> > > > > Hi Abner,
> > > > >
> > > > > The include path in the [Include.Common.Private] section should
> > > > > not be in the same file path as the [Include] section.  This
> > > > > allows private include files to be accessed.
> > > > >
> > > > > Instead, you should create a new top level package directory
> > > > > called PrivateInclude and put all non-public include content in
> > > > > that directory.  The UnitTestFrameworkPkg is a good reference
> > > > > that demonstrates this design pattern.
> > > > Yes, this looks better. All Crt header files and CrtLib.h will be
> > > > moved to
> > > under PrivateInclude.
> > > > >
> > > > > The library class name CrtLib is very generic and the library
> > > > > class is in the public includes so it is exported as a public
> > > > > interface from the
> > > RedfishPkg.
> > > > > This CrtLib implementation appears to be tuned to support the
> > > > > dependencies for the jansson submodule.  I recommend changing
> > > > > the library class name and the library instance name so it is
> > > > > clear that this CrtLib is only for jansson.
> > > > > Perhaps 'JanssonCrtLib'.
> > > > The CrtLib is not used by jannson lib, libredfish as well
> > > > (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a
> > > > good
> > > naming, will keep that as it.
> > > >
> > > > >Also, does this library class (CrtLib.h) need to be  exported
> > > > >from RedfishPkg as a public interface?
> > > > No, it will be moved to under PrivateInclude.
> > > >
> > > > If CrtLib.h is defined as a private library and CrtLib.h is in
> > > > PrivateInclude which is not exposed to other packages, then why do
> > > > we
> > > care about the naming of CrtLib is too generic? Which is the private
> > > library under RedfishPkg.
> > > > Move those header files to under PrivateInclude seems clear to
> > > > people that CrtLib is only for RedfishPkg. I think we don’t have
> > > > to change the
> > > naming in this case.
> > >
> > > In general I agree, but there is one place where the lib mapping has
> > > wider scope, and that is in a platform DSC file.  The lib class name
> > > CrtLib has to be listed in the DSC file.  If more than one package
> > > defines a library class called CrtLib, then the last mapping used
> > > will be used for all modules if it is listed in the [LibraryClasses]
> > > section of the DSC file.  The only was to handle this type of name
> > > collision is to use a module scoped library mapping in the
> > > <LibraryClasses> section of each individual module that uses a
> > > CrtLib.  I am only trying to avoid the potential for future name collisions
> for a library class/instance that is specific to the JSON use case.
> > >
> > > We recognize that several modules in edk2 have this type of gasket
> > > between an EDK II env and a standard C lib.  We may find a we to
> > > implement a more generic gasket and retire the use of the
> > > implementation specific ones.  This is another reason to use an
> > > implementation specific name in this use case and be able to introduce a
> more generic name in the future.
> > >
> > > Another comment below to see if there is a way to avoid introducing
> > > a CrtLib class.
> > >
> > > >
> > > > >
> > > > > * RedfishPkg/Include/Library/CrtLib.h
> > > > >   + Remove reference to MDE_CPU_IA64.  This has been retired
> > > > > from the
> > > > > edk2 repo.
> > > > Ok.
> > > > >   + I do see one remaining reference to this in the CryptoPkg
> > > > > that need to
> > > be
> > > > >     removed.
> > > > >
> > > > > * RedfishPkg/Include/Library/JsonLib.h
> > > > >   + Some of the function descriptions are very brief and I can not tell
> > > > >     how to use the service from the description and more importantly, I
> > > > >     would not know how to write a unit test to verify the
> > > > > expected
> > > behavior.
> > > > >     Since these are a set of public APIs from this package that you
> > > > >     expect modules/libs from outside of RedfishPkg to use, then all of
> > > > >     these public APIs must be fully documented.
> > > > Most of the API in JsonLib are wrappers of native jansson APIs. We
> > > > can mention the URL to jansson API reference document in file header.
> > > > INVALID URI REMOVED
> > > 3A__jansson.readthedo
> > > >
> > >
> cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> > > SN6FZBN4
> > > > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> > > uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > > >
> zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > > > I will review all function header again,  please check v9 patch later.
> > > >
> > > > >   + Are there any of these APIs that are not really needed by
> modules/libs
> > > > >     outside the RedfishPkg?  It would be better to remove APIs that are
> > > > >     not needed outside RedfishPkg from this public include file.
> > > > >   + A couple examples that stood out are:
> > > > >     JsonDecreaseReference()
> > > > >     JsonIncreaseReference()
> > > > >     JsonObjectIterator()
> > > > >     JsonObjectIteratorValue()
> > > > >     JsonObjectIteratorNext()
> > > > The native jansson APIs of all above wrappers are used in libredfish.
> > > > So that is the potential use case for other JSON applications.
> > >
> > > Can you provide a pointer to an example of this use case?
> > >
> > > I am trying to make sure we are doing the right design of RedfishPkg
> > > with respect to CrtLib for this use case.  Are these are JSON apps
> > > that do not use JsonLib, but are expected to build in an EDK II
> > > build environment?  Would these JSON apps require more standard C
> > > lib services than the CrtLib used to build JsonLib?  Where would those
> additional C lib services come from?
> > >
> > > There is a standard C lib in edk2-libc.  Would that be required to
> > > build the JSON apps.
> > >
> > > In other uses of submodules with C lib dependencies, a new CrtLib
> > > like lib class was not added and instead the support was added
> > > directly to the EDK II wrapper APIs. Some examples are:
> > >   * MdeModulePkg\Library\BrotliCustomDecompressLib
> > >   * MdeModulePkg\Universal\RegularExpressionDxe
> > >
> > > If there are use cases where the CrtLib will be added to an INF
> > > outside the RedfishPkg, then I still think the name needs to be
> > > changed to be specific to the JSON use case.
> > CrtLib should not be added to INF outside RedfishPkg, but it will be added
> to platform DSC file.
> > >
> > > If the use of CrtLib is only within the RedfishPkg, then the Library
> > > Class can be declared in a [LibraryClasses.Common.Private] section
> > > of the DEC file.  See UnitTestFrameworkPkg for examples
> > Because CrtLib, JsonLib and other RedfishPkg modules will be included in
> other package dsc file (e.g. EmulatorPkg).
> > What if in EmulatorPkg one CrtLib libraryclass maps to the private one
> > under RedfishPkg, but another with the same name is the public library
> provided by other package (e.g. MdeModulePkg) and used by modules
> other than RedfishPkg?
> > Is edk2 build tool that smart to link the private CrtLib for
> > RedfishPkg modules and all other non RedfishPkg modules are linked with
> the public one?
> >
> > Abner
> >
> 
> No.  Not that smart.
> 
> There are global lib class -> lib instance mapping in [LibraryClasses] sections of
> DSC files.  If the same lib class is listed more than once, then the last mapping
> wins.
> 
> If a module scoped <LibraryClasses> section is used, then then last mapping
> in the scope of that module wins.
> 
> If the same lib class name is declared by more than one package used in a
> platform DSC, then the only remediation is to remove use of the global
> [LibraryClasses] section and use a module scope <LibraryClasses> section in
> every module that depends on that lib class name.
Ok, I will rename it to RedfishCrtLib.

Abner
> 
> > >
> > > >
> > > > >   + JsonDumpString()
> > > > >     func header params do not match func prototype
> > > > >     Does not describe who allocates the return buffer and who
> > > > >     is responsible for freeing the buffer returned.
> > > > >     What do Flags do?  What is the difference between this
> > > > >     function and JsonToText()?
> > > > In JsonToText, it only converts JSON array and object to text. We
> > > > could just remove this for now because I don’t really remember the
> > > > reason
> > > to create this function, it has been a while. Seems to me it is fine
> > > to remove this function.
> > > >
> > > > >   + JsonLoadBuffer() - Error param description missing
> > > > >   + JsonArrayGetValue() does not describe the conditions NULL
> > > > >     is returned.
> > > > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > > > >     function need to be called to free the array?
> > > > All above addressed.
> > > >
> > > > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > > > >     are asymmetric.  The Ascii one states that change will
> > > > >     modify the original string.  The Unicode one says that the
> > > > >     caller needs to free the returned string.  Any reason we
> > > > >     can not make them symmetric?
> > > > Jansson doesn't support Unicode string. The memory of the unicode
> > > > string returned by JsonValueGetUnicodeString Is allocated by
> > > UTF8StrToUCS2().
> > > >  > Also, if Ascii one should
> > > > >     not be modified, why isn’t the return type CONST?
> > > > Yes. will do that.
> > > >
> > > > >
> > > > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > >   + Change [Sources.common] to [Sources]
> > > > done
> > > > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > >   + Does this lib instance really depend on MdeModulePkg?
> > > > Yes, SortLib
> > > > >   + Have you reviewed the module types this lib instance is
> > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > > >     If there are SMM use cases, then why is MM excluded?
> > > > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER.
> These
> > > are
> > > > module types have potential use cases I can think of now.
> > > > >
> > > > > * RedfishPkg/Library/JsonLib
> > > > >   + Readme.rst still has references to JanssonJsonLibMapping.h
> > > > done
> > > > >   + Have you reviewed the module types this lib instance is
> > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > > >     If there are SMM use cases, then why is MM excluded?
> > > > Answered above
> > > > >   + JsonLib.inf has a [BuildOptions] section that disables some
> > > > > warnings
> > > that
> > > > >     make me concerned that this library may have some issues
> > > > > with 32-bit builds.
> > > > >     Have you fully validated all 32-bit CPU builds and validated
> > > > > the
> > > functionality
> > > > >     of all services from the JsonLib for all ranges of input values?
> > > > Yes, IA32 build is validated. But not validating on the
> > > > functionalities IA32. I don't have that use case, we can get back
> > > > to fix the
> > > issue if any when  someone runs this on IA32.
> > >
> > > I did some local testing with VS2019.  I found that a much smaller
> > > set of warning disables are required for IA32 and X64 and the set is
> > > different for
> > > IA32 and X64.  Can you review what is needed and minimize the
> > > required set of each supported arch?
> > >
> > >   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> > > /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
> > >   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090 /DHAVE_CONFIG_H=1
> > > /U_WIN32 /UWIN64 /U_MSC_VER
> > >
> > > > >
> > > > > * RedfishLibs.dsc.inc
> > > > >   It is better to add [LibraryClasses] statement to this file, so it
> > > > >   can be include anywhere in a DSC file.  With current implementation
> > > > >   if it is not included within a [LibraryClasses] section, it will
> > > > >   generate a build error.
> > > > I will separate this to another set of patch. Don’t mix up with
> > > > jansson edk2
> > > port.
> > > >
> > > > >You might also consider changing the name
> > > > >   of this file in case you want to add more than just lib mappings
> > > > >   to this file in the future.  See UnitTestFramworkPkg for examples.
> > > > >
> > > > > Best regards,
> > > > >
> > > > > Mike
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Abner Chang <abner.chang@hpe.com>
> > > > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > > > To: devel@edk2.groups.io
> > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > > > <leif@nuviainc.com>; Kinney, Michael D
> > > > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > > > <gaoliming@byosoft.com.cn>; Nickle Wang
> <nickle.wang@hpe.com>;
> > > > > Peter
> > > > > > O'Hanley <peter.ohanley@hpe.com>
> > > > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > > > >
> > > > > > In v8, - Assigne patch file order
> > > > > >        - Add Acked-by tags
> > > > > > In v7, - Remove C RTC header files to under
> [Include.Common.Private]
> > > > > >          in RedfishPkg.dec.
> > > > > >        - address comments given by Mike Kinney.
> > > > > > In v6, Remove JanssonJsonMapping.h In v5, move BaseUcs2Utf8Lib
> > > > > > to under RedfishPkg.
> > > > > > In v4,
> > > > > >        - Address review comments
> > > > > >        - Seperate CRT functions to a individule library CrtLib under
> > > > > >          RedfishPkg.
> > > > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > > > >
> > > > > > In v3, Add jansson library as the required submoudle in
> > > > > >        CiSettings.py for CI test.
> > > > > > In v2, JsonLib is moved to under RedfishPkg.
> > > > > >
> > > > > > edk2 JSON library is based on jansson open source
> > > > > > (https://github.com/akheron/jansson) and wrapped as an edk2
> library.
> > > > > > edk2 JsonLib will be used by edk2 Redfish feature drivers (not
> > > > > > contributed yet) and the edk2 port of libredfish library (not
> > > > > > contributed yet) based on DMTF GitHub
> > > > > > (https://github.com/DMTF/libredfish).
> > > > > >
> > > > > > Jansson is licensed under the MIT license(refer to ReadMe.rst
> > > > > > under
> > > edk2).
> > > > > > It is used in production and its API is stable. In UEFI/EDKII
> > > > > > environment, Redfish project consumes jansson to achieve JSON
> > > > > operations.
> > > > > >
> > > > > > * Jansson version on edk2: 2.13.1
> > > > > >
> > > > > > * EDKII jansson library wrapper:
> > > > > >    - JsonLib.h:
> > > > > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > > > > >      jannson funcitons accordingly.
> > > > > >
> > > > > >    - JanssonJsonLibMapping.h:
> > > > > >      This is the wrapper file to map funcitons and definitions used in
> > > > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > > > >      modifications on native jannson applications to be built under
> > > > > >      edk2 environment.
> > > > > >
> > > > > > *Known issue:
> > > > > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > > > > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > > > > >   The PR is submitted to jansson open source community.
> > > > > >   https://github.com/akheron/jansson/pull/558
> > > > > >
> > > > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > > > >
> > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > > > Cc: Andrew Fish <afish@apple.com>
> > > > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > > > >
> > > > > > Abner Chang (6):
> > > > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > > > >   edk2: jansson submodule for edk2 JSON library
> > > > > >   RedfishPkg/CrtLib: C runtime library
> > > > > >   RedfishPkg/library: EDK2 port of jansson library
> > > > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > > > >   .pytool: Add required submodule for JsonLib
> > > > > >
> > > > > >  .gitmodules                                   |    3 +
> > > > > >  .pytool/CISettings.py                         |    2 +
> > > > > >  ReadMe.rst                                    |    1 +
> > > > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > > > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > > > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > > > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964 ++++++++++++++
> > > > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > > > >  RedfishPkg/Library/JsonLib/load.c             | 1111
> +++++++++++++++++
> > > > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > > > >  33 files changed, 4614 insertions(+)  create mode 100644
> > > > > > RedfishPkg/Include/Crt/assert.h  create mode
> > > > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > > > RedfishPkg/Include/Crt/sys/types.h
> > > > > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create mode
> > > > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > > > >  create mode 100644
> > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > > > >  create mode 100644
> > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > > > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > > > >  create mode 100644
> > > > > > RedfishPkg/Library/JsonLib/jansson_config.h
> > > > > >  create mode 100644
> > > > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > > > >
> > > > > > --
> > > > > > 2.17.1
> > > >
> >


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v8 0/6] jansson edk2 port
  2020-12-23  7:53           ` Abner Chang
@ 2020-12-23  9:02             ` Abner Chang
  2020-12-24  6:49               ` [edk2-devel] " Michael D Kinney
  0 siblings, 1 reply; 19+ messages in thread
From: Abner Chang @ 2020-12-23  9:02 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)

Hi Mike, v10 patch set sent.
BTW, why don’t you put those private libraries in UniTestFrameworkPkg to under /PrivateLibrary which is similar to /PrivateInclude?

Abner

> -----Original Message-----
> From: Chang, Abner (HPS SW/FW Technologist)
> Sent: Wednesday, December 23, 2020 3:54 PM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [PATCH v8 0/6] jansson edk2 port
> 
> 
> 
> > -----Original Message-----
> > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > Sent: Wednesday, December 23, 2020 2:10 PM
> > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> > Hi Abner,
> >
> > Response below.
> >
> > Mike
> >
> >
> > > -----Original Message-----
> > > From: Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>
> > > Sent: Tuesday, December 22, 2020 8:40 PM
> > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > devel@edk2.groups.io
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > Sent: Wednesday, December 23, 2020 2:14 AM
> > > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > > devel@edk2.groups.io; Kinney, Michael D
> > > > <michael.d.kinney@intel.com>
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > Laszlo
> > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
> > > > Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > <peter.ohanley@hpe.com>
> > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > > Hi Abner,
> > > >
> > > > A few comments below.
> > > >
> > > > Best regards,
> > > >
> > > > Mike
> > > >
> > > > > -----Original Message-----
> > > > > From: Chang, Abner (HPS SW/FW Technologist)
> > <abner.chang@hpe.com>
> > > > > Sent: Monday, December 21, 2020 12:17 AM
> > > > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > > > devel@edk2.groups.io
> > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > > <leif@nuviainc.com>; Liming Gao <gaoliming@byosoft.com.cn>;
> > > > > Wang, Nickle (HPS SW) <nickle.wang@hpe.com>; O'Hanley, Peter
> > > > > (EXL)
> > > > <peter.ohanley@hpe.com>
> > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > >
> > > > > Mike, response in below. Also v9 is sent.
> > > > >
> > > > > Thanks for review this in detail.
> > > > > Abner
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > > > Sent: Monday, December 21, 2020 3:43 AM
> > > > > > To: Chang, Abner (HPS SW/FW Technologist)
> > <abner.chang@hpe.com>;
> > > > > > devel@edk2.groups.io; Kinney, Michael D
> > > > > > <michael.d.kinney@intel.com>
> > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > Laszlo
> > > > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
> > > > > > Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > > <peter.ohanley@hpe.com>
> > > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > > >
> > > > > > Hi Abner,
> > > > > >
> > > > > > The include path in the [Include.Common.Private] section
> > > > > > should not be in the same file path as the [Include] section.
> > > > > > This allows private include files to be accessed.
> > > > > >
> > > > > > Instead, you should create a new top level package directory
> > > > > > called PrivateInclude and put all non-public include content
> > > > > > in that directory.  The UnitTestFrameworkPkg is a good
> > > > > > reference that demonstrates this design pattern.
> > > > > Yes, this looks better. All Crt header files and CrtLib.h will
> > > > > be moved to
> > > > under PrivateInclude.
> > > > > >
> > > > > > The library class name CrtLib is very generic and the library
> > > > > > class is in the public includes so it is exported as a public
> > > > > > interface from the
> > > > RedfishPkg.
> > > > > > This CrtLib implementation appears to be tuned to support the
> > > > > > dependencies for the jansson submodule.  I recommend changing
> > > > > > the library class name and the library instance name so it is
> > > > > > clear that this CrtLib is only for jansson.
> > > > > > Perhaps 'JanssonCrtLib'.
> > > > > The CrtLib is not used by jannson lib, libredfish as well
> > > > > (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a
> > > > > good
> > > > naming, will keep that as it.
> > > > >
> > > > > >Also, does this library class (CrtLib.h) need to be  exported
> > > > > >from RedfishPkg as a public interface?
> > > > > No, it will be moved to under PrivateInclude.
> > > > >
> > > > > If CrtLib.h is defined as a private library and CrtLib.h is in
> > > > > PrivateInclude which is not exposed to other packages, then why
> > > > > do we
> > > > care about the naming of CrtLib is too generic? Which is the
> > > > private library under RedfishPkg.
> > > > > Move those header files to under PrivateInclude seems clear to
> > > > > people that CrtLib is only for RedfishPkg. I think we don’t have
> > > > > to change the
> > > > naming in this case.
> > > >
> > > > In general I agree, but there is one place where the lib mapping
> > > > has wider scope, and that is in a platform DSC file.  The lib
> > > > class name CrtLib has to be listed in the DSC file.  If more than
> > > > one package defines a library class called CrtLib, then the last
> > > > mapping used will be used for all modules if it is listed in the
> > > > [LibraryClasses] section of the DSC file.  The only was to handle
> > > > this type of name collision is to use a module scoped library
> > > > mapping in the <LibraryClasses> section of each individual module
> > > > that uses a CrtLib.  I am only trying to avoid the potential for
> > > > future name collisions
> > for a library class/instance that is specific to the JSON use case.
> > > >
> > > > We recognize that several modules in edk2 have this type of gasket
> > > > between an EDK II env and a standard C lib.  We may find a we to
> > > > implement a more generic gasket and retire the use of the
> > > > implementation specific ones.  This is another reason to use an
> > > > implementation specific name in this use case and be able to
> > > > introduce a
> > more generic name in the future.
> > > >
> > > > Another comment below to see if there is a way to avoid
> > > > introducing a CrtLib class.
> > > >
> > > > >
> > > > > >
> > > > > > * RedfishPkg/Include/Library/CrtLib.h
> > > > > >   + Remove reference to MDE_CPU_IA64.  This has been retired
> > > > > > from the
> > > > > > edk2 repo.
> > > > > Ok.
> > > > > >   + I do see one remaining reference to this in the CryptoPkg
> > > > > > that need to
> > > > be
> > > > > >     removed.
> > > > > >
> > > > > > * RedfishPkg/Include/Library/JsonLib.h
> > > > > >   + Some of the function descriptions are very brief and I can not tell
> > > > > >     how to use the service from the description and more importantly,
> I
> > > > > >     would not know how to write a unit test to verify the
> > > > > > expected
> > > > behavior.
> > > > > >     Since these are a set of public APIs from this package that you
> > > > > >     expect modules/libs from outside of RedfishPkg to use, then all of
> > > > > >     these public APIs must be fully documented.
> > > > > Most of the API in JsonLib are wrappers of native jansson APIs.
> > > > > We can mention the URL to jansson API reference document in file
> header.
> > > > > INVALID URI REMOVED
> > > > 3A__jansson.readthedo
> > > > >
> > > >
> >
> cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> > > > SN6FZBN4
> > > > > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> > > > uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > > > >
> > zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > > > > I will review all function header again,  please check v9 patch later.
> > > > >
> > > > > >   + Are there any of these APIs that are not really needed by
> > modules/libs
> > > > > >     outside the RedfishPkg?  It would be better to remove APIs that
> are
> > > > > >     not needed outside RedfishPkg from this public include file.
> > > > > >   + A couple examples that stood out are:
> > > > > >     JsonDecreaseReference()
> > > > > >     JsonIncreaseReference()
> > > > > >     JsonObjectIterator()
> > > > > >     JsonObjectIteratorValue()
> > > > > >     JsonObjectIteratorNext()
> > > > > The native jansson APIs of all above wrappers are used in libredfish.
> > > > > So that is the potential use case for other JSON applications.
> > > >
> > > > Can you provide a pointer to an example of this use case?
> > > >
> > > > I am trying to make sure we are doing the right design of
> > > > RedfishPkg with respect to CrtLib for this use case.  Are these
> > > > are JSON apps that do not use JsonLib, but are expected to build
> > > > in an EDK II build environment?  Would these JSON apps require
> > > > more standard C lib services than the CrtLib used to build
> > > > JsonLib?  Where would those
> > additional C lib services come from?
> > > >
> > > > There is a standard C lib in edk2-libc.  Would that be required to
> > > > build the JSON apps.
> > > >
> > > > In other uses of submodules with C lib dependencies, a new CrtLib
> > > > like lib class was not added and instead the support was added
> > > > directly to the EDK II wrapper APIs. Some examples are:
> > > >   * MdeModulePkg\Library\BrotliCustomDecompressLib
> > > >   * MdeModulePkg\Universal\RegularExpressionDxe
> > > >
> > > > If there are use cases where the CrtLib will be added to an INF
> > > > outside the RedfishPkg, then I still think the name needs to be
> > > > changed to be specific to the JSON use case.
> > > CrtLib should not be added to INF outside RedfishPkg, but it will be
> > > added
> > to platform DSC file.
> > > >
> > > > If the use of CrtLib is only within the RedfishPkg, then the
> > > > Library Class can be declared in a [LibraryClasses.Common.Private]
> > > > section of the DEC file.  See UnitTestFrameworkPkg for examples
> > > Because CrtLib, JsonLib and other RedfishPkg modules will be
> > > included in
> > other package dsc file (e.g. EmulatorPkg).
> > > What if in EmulatorPkg one CrtLib libraryclass maps to the private
> > > one under RedfishPkg, but another with the same name is the public
> > > library
> > provided by other package (e.g. MdeModulePkg) and used by modules
> > other than RedfishPkg?
> > > Is edk2 build tool that smart to link the private CrtLib for
> > > RedfishPkg modules and all other non RedfishPkg modules are linked
> > > with
> > the public one?
> > >
> > > Abner
> > >
> >
> > No.  Not that smart.
> >
> > There are global lib class -> lib instance mapping in [LibraryClasses]
> > sections of DSC files.  If the same lib class is listed more than
> > once, then the last mapping wins.
> >
> > If a module scoped <LibraryClasses> section is used, then then last
> > mapping in the scope of that module wins.
> >
> > If the same lib class name is declared by more than one package used
> > in a platform DSC, then the only remediation is to remove use of the
> > global [LibraryClasses] section and use a module scope
> > <LibraryClasses> section in every module that depends on that lib class
> name.
> Ok, I will rename it to RedfishCrtLib.
> 
> Abner
> >
> > > >
> > > > >
> > > > > >   + JsonDumpString()
> > > > > >     func header params do not match func prototype
> > > > > >     Does not describe who allocates the return buffer and who
> > > > > >     is responsible for freeing the buffer returned.
> > > > > >     What do Flags do?  What is the difference between this
> > > > > >     function and JsonToText()?
> > > > > In JsonToText, it only converts JSON array and object to text.
> > > > > We could just remove this for now because I don’t really
> > > > > remember the reason
> > > > to create this function, it has been a while. Seems to me it is
> > > > fine to remove this function.
> > > > >
> > > > > >   + JsonLoadBuffer() - Error param description missing
> > > > > >   + JsonArrayGetValue() does not describe the conditions NULL
> > > > > >     is returned.
> > > > > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > > > > >     function need to be called to free the array?
> > > > > All above addressed.
> > > > >
> > > > > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > > > > >     are asymmetric.  The Ascii one states that change will
> > > > > >     modify the original string.  The Unicode one says that the
> > > > > >     caller needs to free the returned string.  Any reason we
> > > > > >     can not make them symmetric?
> > > > > Jansson doesn't support Unicode string. The memory of the
> > > > > unicode string returned by JsonValueGetUnicodeString Is
> > > > > allocated by
> > > > UTF8StrToUCS2().
> > > > >  > Also, if Ascii one should
> > > > > >     not be modified, why isn’t the return type CONST?
> > > > > Yes. will do that.
> > > > >
> > > > > >
> > > > > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > > >   + Change [Sources.common] to [Sources]
> > > > > done
> > > > > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > > >   + Does this lib instance really depend on MdeModulePkg?
> > > > > Yes, SortLib
> > > > > >   + Have you reviewed the module types this lib instance is
> > > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > > > >     If there are SMM use cases, then why is MM excluded?
> > > > > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER.
> > These
> > > > are
> > > > > module types have potential use cases I can think of now.
> > > > > >
> > > > > > * RedfishPkg/Library/JsonLib
> > > > > >   + Readme.rst still has references to JanssonJsonLibMapping.h
> > > > > done
> > > > > >   + Have you reviewed the module types this lib instance is
> > > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > > > >     If there are SMM use cases, then why is MM excluded?
> > > > > Answered above
> > > > > >   + JsonLib.inf has a [BuildOptions] section that disables
> > > > > > some warnings
> > > > that
> > > > > >     make me concerned that this library may have some issues
> > > > > > with 32-bit builds.
> > > > > >     Have you fully validated all 32-bit CPU builds and
> > > > > > validated the
> > > > functionality
> > > > > >     of all services from the JsonLib for all ranges of input values?
> > > > > Yes, IA32 build is validated. But not validating on the
> > > > > functionalities IA32. I don't have that use case, we can get
> > > > > back to fix the
> > > > issue if any when  someone runs this on IA32.
> > > >
> > > > I did some local testing with VS2019.  I found that a much smaller
> > > > set of warning disables are required for IA32 and X64 and the set
> > > > is different for
> > > > IA32 and X64.  Can you review what is needed and minimize the
> > > > required set of each supported arch?
> > > >
> > > >   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> > > > /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
> > > >   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090
> /DHAVE_CONFIG_H=1
> > > > /U_WIN32 /UWIN64 /U_MSC_VER
> > > >
> > > > > >
> > > > > > * RedfishLibs.dsc.inc
> > > > > >   It is better to add [LibraryClasses] statement to this file, so it
> > > > > >   can be include anywhere in a DSC file.  With current
> implementation
> > > > > >   if it is not included within a [LibraryClasses] section, it will
> > > > > >   generate a build error.
> > > > > I will separate this to another set of patch. Don’t mix up with
> > > > > jansson edk2
> > > > port.
> > > > >
> > > > > >You might also consider changing the name
> > > > > >   of this file in case you want to add more than just lib mappings
> > > > > >   to this file in the future.  See UnitTestFramworkPkg for examples.
> > > > > >
> > > > > > Best regards,
> > > > > >
> > > > > > Mike
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Abner Chang <abner.chang@hpe.com>
> > > > > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > > > > To: devel@edk2.groups.io
> > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish
> > > > > > > <afish@apple.com>; Laszlo Ersek <lersek@redhat.com>; Leif
> > > > > > > Lindholm <leif@nuviainc.com>; Kinney, Michael D
> > > > > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > > > > <gaoliming@byosoft.com.cn>; Nickle Wang
> > <nickle.wang@hpe.com>;
> > > > > > Peter
> > > > > > > O'Hanley <peter.ohanley@hpe.com>
> > > > > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > > > > >
> > > > > > > In v8, - Assigne patch file order
> > > > > > >        - Add Acked-by tags
> > > > > > > In v7, - Remove C RTC header files to under
> > [Include.Common.Private]
> > > > > > >          in RedfishPkg.dec.
> > > > > > >        - address comments given by Mike Kinney.
> > > > > > > In v6, Remove JanssonJsonMapping.h In v5, move
> > > > > > > BaseUcs2Utf8Lib to under RedfishPkg.
> > > > > > > In v4,
> > > > > > >        - Address review comments
> > > > > > >        - Seperate CRT functions to a individule library CrtLib under
> > > > > > >          RedfishPkg.
> > > > > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > > > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > > > > >
> > > > > > > In v3, Add jansson library as the required submoudle in
> > > > > > >        CiSettings.py for CI test.
> > > > > > > In v2, JsonLib is moved to under RedfishPkg.
> > > > > > >
> > > > > > > edk2 JSON library is based on jansson open source
> > > > > > > (https://github.com/akheron/jansson) and wrapped as an edk2
> > library.
> > > > > > > edk2 JsonLib will be used by edk2 Redfish feature drivers
> > > > > > > (not contributed yet) and the edk2 port of libredfish
> > > > > > > library (not contributed yet) based on DMTF GitHub
> > > > > > > (https://github.com/DMTF/libredfish).
> > > > > > >
> > > > > > > Jansson is licensed under the MIT license(refer to
> > > > > > > ReadMe.rst under
> > > > edk2).
> > > > > > > It is used in production and its API is stable. In
> > > > > > > UEFI/EDKII environment, Redfish project consumes jansson to
> > > > > > > achieve JSON
> > > > > > operations.
> > > > > > >
> > > > > > > * Jansson version on edk2: 2.13.1
> > > > > > >
> > > > > > > * EDKII jansson library wrapper:
> > > > > > >    - JsonLib.h:
> > > > > > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > > > > > >      jannson funcitons accordingly.
> > > > > > >
> > > > > > >    - JanssonJsonLibMapping.h:
> > > > > > >      This is the wrapper file to map funcitons and definitions used in
> > > > > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > > > > >      modifications on native jannson applications to be built under
> > > > > > >      edk2 environment.
> > > > > > >
> > > > > > > *Known issue:
> > > > > > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > > > > > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > > > > > >   The PR is submitted to jansson open source community.
> > > > > > >   https://github.com/akheron/jansson/pull/558
> > > > > > >
> > > > > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > > > > >
> > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > > > > Cc: Andrew Fish <afish@apple.com>
> > > > > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > > > > >
> > > > > > > Abner Chang (6):
> > > > > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > > > > >   edk2: jansson submodule for edk2 JSON library
> > > > > > >   RedfishPkg/CrtLib: C runtime library
> > > > > > >   RedfishPkg/library: EDK2 port of jansson library
> > > > > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > > > > >   .pytool: Add required submodule for JsonLib
> > > > > > >
> > > > > > >  .gitmodules                                   |    3 +
> > > > > > >  .pytool/CISettings.py                         |    2 +
> > > > > > >  ReadMe.rst                                    |    1 +
> > > > > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > > > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > > > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > > > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > > > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > > > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > > > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > > > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > > > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > > > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > > > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > > > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > > > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > > > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > > > > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > > > > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > > > > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > > > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > > > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > > > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964
> ++++++++++++++
> > > > > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > > > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > > > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > > > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > > > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > > > > >  RedfishPkg/Library/JsonLib/load.c             | 1111
> > +++++++++++++++++
> > > > > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > > > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > > > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > > > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > > > > >  33 files changed, 4614 insertions(+)  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/assert.h  create mode
> > > > > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > > > > RedfishPkg/Include/Crt/sys/types.h
> > > > > > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create
> > > > > > > mode
> > > > > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > > > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > > > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > > > > >  create mode 100644
> > > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > > > > >  create mode 100644
> > > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > > > > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > > > > >  create mode 100644
> > > > > > > RedfishPkg/Library/JsonLib/jansson_config.h
> > > > > > >  create mode 100644
> > > > > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > > > > >
> > > > > > > --
> > > > > > > 2.17.1
> > > > >
> > >


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [edk2-devel] [PATCH v8 0/6] jansson edk2 port
  2020-12-23  9:02             ` Abner Chang
@ 2020-12-24  6:49               ` Michael D Kinney
  2020-12-24 12:34                 ` Abner Chang
  0 siblings, 1 reply; 19+ messages in thread
From: Michael D Kinney @ 2020-12-24  6:49 UTC (permalink / raw)
  To: devel@edk2.groups.io, abner.chang@hpe.com, Kinney, Michael D
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner Chang
> Sent: Wednesday, December 23, 2020 1:02 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle
> (HPS SW) <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: Re: [edk2-devel] [PATCH v8 0/6] jansson edk2 port
> 
> Hi Mike, v10 patch set sent.
> BTW, why don’t you put those private libraries in UniTestFrameworkPkg to under /PrivateLibrary which is similar to
> /PrivateInclude?

That is a good question.  We had not considered that before because it does not change
the visibility of the library instance (we have to support listing these in platform 
DSC files).  Using PrivateInclude actually prevents a module/lib from other packages
from using those include files because the include paths passed into the compiler
do not contain private include paths.

From a self-documenting perspective using a PrivateLibrary directory name would
make it obvious that the library is not intended to be used by any components 
from other packages.

Mike

> 
> Abner
> 
> > -----Original Message-----
> > From: Chang, Abner (HPS SW/FW Technologist)
> > Sent: Wednesday, December 23, 2020 3:54 PM
> > To: Kinney, Michael D <michael.d.kinney@intel.com>; devel@edk2.groups.io
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> > <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> >
> >
> >
> > > -----Original Message-----
> > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > Sent: Wednesday, December 23, 2020 2:10 PM
> > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > > Hi Abner,
> > >
> > > Response below.
> > >
> > > Mike
> > >
> > >
> > > > -----Original Message-----
> > > > From: Chang, Abner (HPS SW/FW Technologist)
> > <abner.chang@hpe.com>
> > > > Sent: Tuesday, December 22, 2020 8:40 PM
> > > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > > devel@edk2.groups.io
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > Laszlo
> > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > <peter.ohanley@hpe.com>
> > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > > Sent: Wednesday, December 23, 2020 2:14 AM
> > > > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > > > devel@edk2.groups.io; Kinney, Michael D
> > > > > <michael.d.kinney@intel.com>
> > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > Laszlo
> > > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
> > > > > Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > <peter.ohanley@hpe.com>
> > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > >
> > > > > Hi Abner,
> > > > >
> > > > > A few comments below.
> > > > >
> > > > > Best regards,
> > > > >
> > > > > Mike
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Chang, Abner (HPS SW/FW Technologist)
> > > <abner.chang@hpe.com>
> > > > > > Sent: Monday, December 21, 2020 12:17 AM
> > > > > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > > > > devel@edk2.groups.io
> > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > > > <leif@nuviainc.com>; Liming Gao <gaoliming@byosoft.com.cn>;
> > > > > > Wang, Nickle (HPS SW) <nickle.wang@hpe.com>; O'Hanley, Peter
> > > > > > (EXL)
> > > > > <peter.ohanley@hpe.com>
> > > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > > >
> > > > > > Mike, response in below. Also v9 is sent.
> > > > > >
> > > > > > Thanks for review this in detail.
> > > > > > Abner
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > > > > Sent: Monday, December 21, 2020 3:43 AM
> > > > > > > To: Chang, Abner (HPS SW/FW Technologist)
> > > <abner.chang@hpe.com>;
> > > > > > > devel@edk2.groups.io; Kinney, Michael D
> > > > > > > <michael.d.kinney@intel.com>
> > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > > Laszlo
> > > > > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
> > > > > > > Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > > > <peter.ohanley@hpe.com>
> > > > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > > > >
> > > > > > > Hi Abner,
> > > > > > >
> > > > > > > The include path in the [Include.Common.Private] section
> > > > > > > should not be in the same file path as the [Include] section.
> > > > > > > This allows private include files to be accessed.
> > > > > > >
> > > > > > > Instead, you should create a new top level package directory
> > > > > > > called PrivateInclude and put all non-public include content
> > > > > > > in that directory.  The UnitTestFrameworkPkg is a good
> > > > > > > reference that demonstrates this design pattern.
> > > > > > Yes, this looks better. All Crt header files and CrtLib.h will
> > > > > > be moved to
> > > > > under PrivateInclude.
> > > > > > >
> > > > > > > The library class name CrtLib is very generic and the library
> > > > > > > class is in the public includes so it is exported as a public
> > > > > > > interface from the
> > > > > RedfishPkg.
> > > > > > > This CrtLib implementation appears to be tuned to support the
> > > > > > > dependencies for the jansson submodule.  I recommend changing
> > > > > > > the library class name and the library instance name so it is
> > > > > > > clear that this CrtLib is only for jansson.
> > > > > > > Perhaps 'JanssonCrtLib'.
> > > > > > The CrtLib is not used by jannson lib, libredfish as well
> > > > > > (https://github.com/DMTF/libredfish). So JanssonCrtLib is not a
> > > > > > good
> > > > > naming, will keep that as it.
> > > > > >
> > > > > > >Also, does this library class (CrtLib.h) need to be  exported
> > > > > > >from RedfishPkg as a public interface?
> > > > > > No, it will be moved to under PrivateInclude.
> > > > > >
> > > > > > If CrtLib.h is defined as a private library and CrtLib.h is in
> > > > > > PrivateInclude which is not exposed to other packages, then why
> > > > > > do we
> > > > > care about the naming of CrtLib is too generic? Which is the
> > > > > private library under RedfishPkg.
> > > > > > Move those header files to under PrivateInclude seems clear to
> > > > > > people that CrtLib is only for RedfishPkg. I think we don’t have
> > > > > > to change the
> > > > > naming in this case.
> > > > >
> > > > > In general I agree, but there is one place where the lib mapping
> > > > > has wider scope, and that is in a platform DSC file.  The lib
> > > > > class name CrtLib has to be listed in the DSC file.  If more than
> > > > > one package defines a library class called CrtLib, then the last
> > > > > mapping used will be used for all modules if it is listed in the
> > > > > [LibraryClasses] section of the DSC file.  The only was to handle
> > > > > this type of name collision is to use a module scoped library
> > > > > mapping in the <LibraryClasses> section of each individual module
> > > > > that uses a CrtLib.  I am only trying to avoid the potential for
> > > > > future name collisions
> > > for a library class/instance that is specific to the JSON use case.
> > > > >
> > > > > We recognize that several modules in edk2 have this type of gasket
> > > > > between an EDK II env and a standard C lib.  We may find a we to
> > > > > implement a more generic gasket and retire the use of the
> > > > > implementation specific ones.  This is another reason to use an
> > > > > implementation specific name in this use case and be able to
> > > > > introduce a
> > > more generic name in the future.
> > > > >
> > > > > Another comment below to see if there is a way to avoid
> > > > > introducing a CrtLib class.
> > > > >
> > > > > >
> > > > > > >
> > > > > > > * RedfishPkg/Include/Library/CrtLib.h
> > > > > > >   + Remove reference to MDE_CPU_IA64.  This has been retired
> > > > > > > from the
> > > > > > > edk2 repo.
> > > > > > Ok.
> > > > > > >   + I do see one remaining reference to this in the CryptoPkg
> > > > > > > that need to
> > > > > be
> > > > > > >     removed.
> > > > > > >
> > > > > > > * RedfishPkg/Include/Library/JsonLib.h
> > > > > > >   + Some of the function descriptions are very brief and I can not tell
> > > > > > >     how to use the service from the description and more importantly,
> > I
> > > > > > >     would not know how to write a unit test to verify the
> > > > > > > expected
> > > > > behavior.
> > > > > > >     Since these are a set of public APIs from this package that you
> > > > > > >     expect modules/libs from outside of RedfishPkg to use, then all of
> > > > > > >     these public APIs must be fully documented.
> > > > > > Most of the API in JsonLib are wrappers of native jansson APIs.
> > > > > > We can mention the URL to jansson API reference document in file
> > header.
> > > > > > INVALID URI REMOVED
> > > > > 3A__jansson.readthedo
> > > > > >
> > > > >
> > >
> > cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> > > > > SN6FZBN4
> > > > > > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> > > > > uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > > > > >
> > > zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > > > > > I will review all function header again,  please check v9 patch later.
> > > > > >
> > > > > > >   + Are there any of these APIs that are not really needed by
> > > modules/libs
> > > > > > >     outside the RedfishPkg?  It would be better to remove APIs that
> > are
> > > > > > >     not needed outside RedfishPkg from this public include file.
> > > > > > >   + A couple examples that stood out are:
> > > > > > >     JsonDecreaseReference()
> > > > > > >     JsonIncreaseReference()
> > > > > > >     JsonObjectIterator()
> > > > > > >     JsonObjectIteratorValue()
> > > > > > >     JsonObjectIteratorNext()
> > > > > > The native jansson APIs of all above wrappers are used in libredfish.
> > > > > > So that is the potential use case for other JSON applications.
> > > > >
> > > > > Can you provide a pointer to an example of this use case?
> > > > >
> > > > > I am trying to make sure we are doing the right design of
> > > > > RedfishPkg with respect to CrtLib for this use case.  Are these
> > > > > are JSON apps that do not use JsonLib, but are expected to build
> > > > > in an EDK II build environment?  Would these JSON apps require
> > > > > more standard C lib services than the CrtLib used to build
> > > > > JsonLib?  Where would those
> > > additional C lib services come from?
> > > > >
> > > > > There is a standard C lib in edk2-libc.  Would that be required to
> > > > > build the JSON apps.
> > > > >
> > > > > In other uses of submodules with C lib dependencies, a new CrtLib
> > > > > like lib class was not added and instead the support was added
> > > > > directly to the EDK II wrapper APIs. Some examples are:
> > > > >   * MdeModulePkg\Library\BrotliCustomDecompressLib
> > > > >   * MdeModulePkg\Universal\RegularExpressionDxe
> > > > >
> > > > > If there are use cases where the CrtLib will be added to an INF
> > > > > outside the RedfishPkg, then I still think the name needs to be
> > > > > changed to be specific to the JSON use case.
> > > > CrtLib should not be added to INF outside RedfishPkg, but it will be
> > > > added
> > > to platform DSC file.
> > > > >
> > > > > If the use of CrtLib is only within the RedfishPkg, then the
> > > > > Library Class can be declared in a [LibraryClasses.Common.Private]
> > > > > section of the DEC file.  See UnitTestFrameworkPkg for examples
> > > > Because CrtLib, JsonLib and other RedfishPkg modules will be
> > > > included in
> > > other package dsc file (e.g. EmulatorPkg).
> > > > What if in EmulatorPkg one CrtLib libraryclass maps to the private
> > > > one under RedfishPkg, but another with the same name is the public
> > > > library
> > > provided by other package (e.g. MdeModulePkg) and used by modules
> > > other than RedfishPkg?
> > > > Is edk2 build tool that smart to link the private CrtLib for
> > > > RedfishPkg modules and all other non RedfishPkg modules are linked
> > > > with
> > > the public one?
> > > >
> > > > Abner
> > > >
> > >
> > > No.  Not that smart.
> > >
> > > There are global lib class -> lib instance mapping in [LibraryClasses]
> > > sections of DSC files.  If the same lib class is listed more than
> > > once, then the last mapping wins.
> > >
> > > If a module scoped <LibraryClasses> section is used, then then last
> > > mapping in the scope of that module wins.
> > >
> > > If the same lib class name is declared by more than one package used
> > > in a platform DSC, then the only remediation is to remove use of the
> > > global [LibraryClasses] section and use a module scope
> > > <LibraryClasses> section in every module that depends on that lib class
> > name.
> > Ok, I will rename it to RedfishCrtLib.
> >
> > Abner
> > >
> > > > >
> > > > > >
> > > > > > >   + JsonDumpString()
> > > > > > >     func header params do not match func prototype
> > > > > > >     Does not describe who allocates the return buffer and who
> > > > > > >     is responsible for freeing the buffer returned.
> > > > > > >     What do Flags do?  What is the difference between this
> > > > > > >     function and JsonToText()?
> > > > > > In JsonToText, it only converts JSON array and object to text.
> > > > > > We could just remove this for now because I don’t really
> > > > > > remember the reason
> > > > > to create this function, it has been a while. Seems to me it is
> > > > > fine to remove this function.
> > > > > >
> > > > > > >   + JsonLoadBuffer() - Error param description missing
> > > > > > >   + JsonArrayGetValue() does not describe the conditions NULL
> > > > > > >     is returned.
> > > > > > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > > > > > >     function need to be called to free the array?
> > > > > > All above addressed.
> > > > > >
> > > > > > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > > > > > >     are asymmetric.  The Ascii one states that change will
> > > > > > >     modify the original string.  The Unicode one says that the
> > > > > > >     caller needs to free the returned string.  Any reason we
> > > > > > >     can not make them symmetric?
> > > > > > Jansson doesn't support Unicode string. The memory of the
> > > > > > unicode string returned by JsonValueGetUnicodeString Is
> > > > > > allocated by
> > > > > UTF8StrToUCS2().
> > > > > >  > Also, if Ascii one should
> > > > > > >     not be modified, why isn’t the return type CONST?
> > > > > > Yes. will do that.
> > > > > >
> > > > > > >
> > > > > > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > > > >   + Change [Sources.common] to [Sources]
> > > > > > done
> > > > > > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > > > >   + Does this lib instance really depend on MdeModulePkg?
> > > > > > Yes, SortLib
> > > > > > >   + Have you reviewed the module types this lib instance is
> > > > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > > > > >     If there are SMM use cases, then why is MM excluded?
> > > > > > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER.
> > > These
> > > > > are
> > > > > > module types have potential use cases I can think of now.
> > > > > > >
> > > > > > > * RedfishPkg/Library/JsonLib
> > > > > > >   + Readme.rst still has references to JanssonJsonLibMapping.h
> > > > > > done
> > > > > > >   + Have you reviewed the module types this lib instance is
> > > > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM drivers?
> > > > > > >     If there are SMM use cases, then why is MM excluded?
> > > > > > Answered above
> > > > > > >   + JsonLib.inf has a [BuildOptions] section that disables
> > > > > > > some warnings
> > > > > that
> > > > > > >     make me concerned that this library may have some issues
> > > > > > > with 32-bit builds.
> > > > > > >     Have you fully validated all 32-bit CPU builds and
> > > > > > > validated the
> > > > > functionality
> > > > > > >     of all services from the JsonLib for all ranges of input values?
> > > > > > Yes, IA32 build is validated. But not validating on the
> > > > > > functionalities IA32. I don't have that use case, we can get
> > > > > > back to fix the
> > > > > issue if any when  someone runs this on IA32.
> > > > >
> > > > > I did some local testing with VS2019.  I found that a much smaller
> > > > > set of warning disables are required for IA32 and X64 and the set
> > > > > is different for
> > > > > IA32 and X64.  Can you review what is needed and minimize the
> > > > > required set of each supported arch?
> > > > >
> > > > >   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> > > > > /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
> > > > >   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090
> > /DHAVE_CONFIG_H=1
> > > > > /U_WIN32 /UWIN64 /U_MSC_VER
> > > > >
> > > > > > >
> > > > > > > * RedfishLibs.dsc.inc
> > > > > > >   It is better to add [LibraryClasses] statement to this file, so it
> > > > > > >   can be include anywhere in a DSC file.  With current
> > implementation
> > > > > > >   if it is not included within a [LibraryClasses] section, it will
> > > > > > >   generate a build error.
> > > > > > I will separate this to another set of patch. Don’t mix up with
> > > > > > jansson edk2
> > > > > port.
> > > > > >
> > > > > > >You might also consider changing the name
> > > > > > >   of this file in case you want to add more than just lib mappings
> > > > > > >   to this file in the future.  See UnitTestFramworkPkg for examples.
> > > > > > >
> > > > > > > Best regards,
> > > > > > >
> > > > > > > Mike
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Abner Chang <abner.chang@hpe.com>
> > > > > > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > > > > > To: devel@edk2.groups.io
> > > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish
> > > > > > > > <afish@apple.com>; Laszlo Ersek <lersek@redhat.com>; Leif
> > > > > > > > Lindholm <leif@nuviainc.com>; Kinney, Michael D
> > > > > > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > > > > > <gaoliming@byosoft.com.cn>; Nickle Wang
> > > <nickle.wang@hpe.com>;
> > > > > > > Peter
> > > > > > > > O'Hanley <peter.ohanley@hpe.com>
> > > > > > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > > > > > >
> > > > > > > > In v8, - Assigne patch file order
> > > > > > > >        - Add Acked-by tags
> > > > > > > > In v7, - Remove C RTC header files to under
> > > [Include.Common.Private]
> > > > > > > >          in RedfishPkg.dec.
> > > > > > > >        - address comments given by Mike Kinney.
> > > > > > > > In v6, Remove JanssonJsonMapping.h In v5, move
> > > > > > > > BaseUcs2Utf8Lib to under RedfishPkg.
> > > > > > > > In v4,
> > > > > > > >        - Address review comments
> > > > > > > >        - Seperate CRT functions to a individule library CrtLib under
> > > > > > > >          RedfishPkg.
> > > > > > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > > > > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > > > > > >
> > > > > > > > In v3, Add jansson library as the required submoudle in
> > > > > > > >        CiSettings.py for CI test.
> > > > > > > > In v2, JsonLib is moved to under RedfishPkg.
> > > > > > > >
> > > > > > > > edk2 JSON library is based on jansson open source
> > > > > > > > (https://github.com/akheron/jansson) and wrapped as an edk2
> > > library.
> > > > > > > > edk2 JsonLib will be used by edk2 Redfish feature drivers
> > > > > > > > (not contributed yet) and the edk2 port of libredfish
> > > > > > > > library (not contributed yet) based on DMTF GitHub
> > > > > > > > (https://github.com/DMTF/libredfish).
> > > > > > > >
> > > > > > > > Jansson is licensed under the MIT license(refer to
> > > > > > > > ReadMe.rst under
> > > > > edk2).
> > > > > > > > It is used in production and its API is stable. In
> > > > > > > > UEFI/EDKII environment, Redfish project consumes jansson to
> > > > > > > > achieve JSON
> > > > > > > operations.
> > > > > > > >
> > > > > > > > * Jansson version on edk2: 2.13.1
> > > > > > > >
> > > > > > > > * EDKII jansson library wrapper:
> > > > > > > >    - JsonLib.h:
> > > > > > > >      This is the denifitions of EDKII JSON APIs which are mapped to
> > > > > > > >      jannson funcitons accordingly.
> > > > > > > >
> > > > > > > >    - JanssonJsonLibMapping.h:
> > > > > > > >      This is the wrapper file to map funcitons and definitions used in
> > > > > > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > > > > > >      modifications on native jannson applications to be built under
> > > > > > > >      edk2 environment.
> > > > > > > >
> > > > > > > > *Known issue:
> > > > > > > >   Build fail with jansson/src/load.c, overrride and add code in load.c
> > > > > > > >   to conditionally use stdin according to HAVE_UNISTD_H macro.
> > > > > > > >   The PR is submitted to jansson open source community.
> > > > > > > >   https://github.com/akheron/jansson/pull/558
> > > > > > > >
> > > > > > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > > > > > >
> > > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > > > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > > > > > Cc: Andrew Fish <afish@apple.com>
> > > > > > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > > > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > > > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > > > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > > > > > >
> > > > > > > > Abner Chang (6):
> > > > > > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > > > > > >   edk2: jansson submodule for edk2 JSON library
> > > > > > > >   RedfishPkg/CrtLib: C runtime library
> > > > > > > >   RedfishPkg/library: EDK2 port of jansson library
> > > > > > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > > > > > >   .pytool: Add required submodule for JsonLib
> > > > > > > >
> > > > > > > >  .gitmodules                                   |    3 +
> > > > > > > >  .pytool/CISettings.py                         |    2 +
> > > > > > > >  ReadMe.rst                                    |    1 +
> > > > > > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > > > > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > > > > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > > > > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > > > > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > > > > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > > > > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > > > > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > > > > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > > > > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > > > > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > > > > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > > > > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > > > > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > > > > > >  RedfishPkg/Include/Library/JsonLib.h          |  763 +++++++++++
> > > > > > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421 +++++++
> > > > > > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > > > > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > > > > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > > > > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964
> > ++++++++++++++
> > > > > > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > > > > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > > > > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > > > > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > > > > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > > > > > >  RedfishPkg/Library/JsonLib/load.c             | 1111
> > > +++++++++++++++++
> > > > > > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > > > > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > > > > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > > > > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > > > > > >  33 files changed, 4614 insertions(+)  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/assert.h  create mode
> > > > > > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/limits.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > > > > > RedfishPkg/Include/Crt/sys/types.h
> > > > > > > >  create mode 100644 RedfishPkg/Include/Crt/time.h  create
> > > > > > > > mode
> > > > > > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > > > > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > > > > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > > > > > >  create mode 100644
> > > > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > > > > > >  create mode 100644
> > > > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.inf
> > > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/Readme.rst
> > > > > > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > > > > > >  create mode 100644
> > > > > > > > RedfishPkg/Library/JsonLib/jansson_config.h
> > > > > > > >  create mode 100644
> > > > > > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > > > > > >
> > > > > > > > --
> > > > > > > > 2.17.1
> > > > > >
> > > >
> 
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [edk2-devel] [PATCH v8 0/6] jansson edk2 port
  2020-12-24  6:49               ` [edk2-devel] " Michael D Kinney
@ 2020-12-24 12:34                 ` Abner Chang
  0 siblings, 0 replies; 19+ messages in thread
From: Abner Chang @ 2020-12-24 12:34 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Sean Brogan, Bret Barkelew, Andrew Fish, Laszlo Ersek,
	Leif Lindholm, Liming Gao, Wang, Nickle (HPS SW),
	O'Hanley, Peter (EXL)



> -----Original Message-----
> From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> Sent: Thursday, December 24, 2020 2:50 PM
> To: devel@edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang@hpe.com>; Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> <nickle.wang@hpe.com>; O'Hanley, Peter (EXL) <peter.ohanley@hpe.com>
> Subject: RE: [edk2-devel] [PATCH v8 0/6] jansson edk2 port
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abner
> > Chang
> > Sent: Wednesday, December 23, 2020 1:02 AM
> > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > devel@edk2.groups.io
> > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>; Laszlo
> > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > Subject: Re: [edk2-devel] [PATCH v8 0/6] jansson edk2 port
> >
> > Hi Mike, v10 patch set sent.
> > BTW, why don’t you put those private libraries in UniTestFrameworkPkg
> > to under /PrivateLibrary which is similar to /PrivateInclude?
> 
> That is a good question.  We had not considered that before because it does
> not change the visibility of the library instance (we have to support listing
> these in platform DSC files).  Using PrivateInclude actually prevents a
> module/lib from other packages from using those include files because the
> include paths passed into the compiler do not contain private include paths.
> 
> From a self-documenting perspective using a PrivateLibrary directory name
> would make it obvious that the library is not intended to be used by any
> components from other packages.
> 
> Mike
Yes, that is what my thought. I will have /PrivateLibrary for RedfishCrtLib.

Thanks
Abner
> 
> >
> > Abner
> >
> > > -----Original Message-----
> > > From: Chang, Abner (HPS SW/FW Technologist)
> > > Sent: Wednesday, December 23, 2020 3:54 PM
> > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > devel@edk2.groups.io
> > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> Laszlo
> > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>; Liming
> > > Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> <peter.ohanley@hpe.com>
> > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > Sent: Wednesday, December 23, 2020 2:10 PM
> > > > To: Chang, Abner (HPS SW/FW Technologist) <abner.chang@hpe.com>;
> > > > devel@edk2.groups.io; Kinney, Michael D
> > > > <michael.d.kinney@intel.com>
> > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > Laszlo Ersek <lersek@redhat.com>; Leif Lindholm
> > > > <leif@nuviainc.com>; Liming Gao <gaoliming@byosoft.com.cn>; Wang,
> > > > Nickle (HPS SW) <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > <peter.ohanley@hpe.com>
> > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > >
> > > > Hi Abner,
> > > >
> > > > Response below.
> > > >
> > > > Mike
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Chang, Abner (HPS SW/FW Technologist)
> > > <abner.chang@hpe.com>
> > > > > Sent: Tuesday, December 22, 2020 8:40 PM
> > > > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > > > devel@edk2.groups.io
> > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > Laszlo
> > > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
> > > > > Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > > <peter.ohanley@hpe.com>
> > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > >
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
> > > > > > Sent: Wednesday, December 23, 2020 2:14 AM
> > > > > > To: Chang, Abner (HPS SW/FW Technologist)
> > > > > > <abner.chang@hpe.com>; devel@edk2.groups.io; Kinney, Michael
> D
> > > > > > <michael.d.kinney@intel.com>
> > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish <afish@apple.com>;
> > > > Laszlo
> > > > > > Ersek <lersek@redhat.com>; Leif Lindholm <leif@nuviainc.com>;
> > > > > > Liming Gao <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > > <peter.ohanley@hpe.com>
> > > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > > >
> > > > > > Hi Abner,
> > > > > >
> > > > > > A few comments below.
> > > > > >
> > > > > > Best regards,
> > > > > >
> > > > > > Mike
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Chang, Abner (HPS SW/FW Technologist)
> > > > <abner.chang@hpe.com>
> > > > > > > Sent: Monday, December 21, 2020 12:17 AM
> > > > > > > To: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > > > > > devel@edk2.groups.io
> > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish
> > > > > > > <afish@apple.com>; Laszlo Ersek <lersek@redhat.com>; Leif
> > > > > > > Lindholm <leif@nuviainc.com>; Liming Gao
> > > > > > > <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > > > <nickle.wang@hpe.com>; O'Hanley, Peter
> > > > > > > (EXL)
> > > > > > <peter.ohanley@hpe.com>
> > > > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > > > >
> > > > > > > Mike, response in below. Also v9 is sent.
> > > > > > >
> > > > > > > Thanks for review this in detail.
> > > > > > > Abner
> > > > > > >
> > > > > > > > -----Original Message-----
> > > > > > > > From: Kinney, Michael D
> > > > > > > > [mailto:michael.d.kinney@intel.com]
> > > > > > > > Sent: Monday, December 21, 2020 3:43 AM
> > > > > > > > To: Chang, Abner (HPS SW/FW Technologist)
> > > > <abner.chang@hpe.com>;
> > > > > > > > devel@edk2.groups.io; Kinney, Michael D
> > > > > > > > <michael.d.kinney@intel.com>
> > > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret Barkelew
> > > > > > > > <Bret.Barkelew@microsoft.com>; Andrew Fish
> > > > > > > > <afish@apple.com>;
> > > > > > Laszlo
> > > > > > > > Ersek <lersek@redhat.com>; Leif Lindholm
> > > > > > > > <leif@nuviainc.com>; Liming Gao
> > > > > > > > <gaoliming@byosoft.com.cn>; Wang, Nickle (HPS SW)
> > > > > > > > <nickle.wang@hpe.com>; O'Hanley, Peter (EXL)
> > > > > > <peter.ohanley@hpe.com>
> > > > > > > > Subject: RE: [PATCH v8 0/6] jansson edk2 port
> > > > > > > >
> > > > > > > > Hi Abner,
> > > > > > > >
> > > > > > > > The include path in the [Include.Common.Private] section
> > > > > > > > should not be in the same file path as the [Include] section.
> > > > > > > > This allows private include files to be accessed.
> > > > > > > >
> > > > > > > > Instead, you should create a new top level package
> > > > > > > > directory called PrivateInclude and put all non-public
> > > > > > > > include content in that directory.  The
> > > > > > > > UnitTestFrameworkPkg is a good reference that demonstrates
> this design pattern.
> > > > > > > Yes, this looks better. All Crt header files and CrtLib.h
> > > > > > > will be moved to
> > > > > > under PrivateInclude.
> > > > > > > >
> > > > > > > > The library class name CrtLib is very generic and the
> > > > > > > > library class is in the public includes so it is exported
> > > > > > > > as a public interface from the
> > > > > > RedfishPkg.
> > > > > > > > This CrtLib implementation appears to be tuned to support
> > > > > > > > the dependencies for the jansson submodule.  I recommend
> > > > > > > > changing the library class name and the library instance
> > > > > > > > name so it is clear that this CrtLib is only for jansson.
> > > > > > > > Perhaps 'JanssonCrtLib'.
> > > > > > > The CrtLib is not used by jannson lib, libredfish as well
> > > > > > > (https://github.com/DMTF/libredfish). So JanssonCrtLib is
> > > > > > > not a good
> > > > > > naming, will keep that as it.
> > > > > > >
> > > > > > > >Also, does this library class (CrtLib.h) need to be
> > > > > > > >exported from RedfishPkg as a public interface?
> > > > > > > No, it will be moved to under PrivateInclude.
> > > > > > >
> > > > > > > If CrtLib.h is defined as a private library and CrtLib.h is
> > > > > > > in PrivateInclude which is not exposed to other packages,
> > > > > > > then why do we
> > > > > > care about the naming of CrtLib is too generic? Which is the
> > > > > > private library under RedfishPkg.
> > > > > > > Move those header files to under PrivateInclude seems clear
> > > > > > > to people that CrtLib is only for RedfishPkg. I think we
> > > > > > > don’t have to change the
> > > > > > naming in this case.
> > > > > >
> > > > > > In general I agree, but there is one place where the lib
> > > > > > mapping has wider scope, and that is in a platform DSC file.
> > > > > > The lib class name CrtLib has to be listed in the DSC file.
> > > > > > If more than one package defines a library class called
> > > > > > CrtLib, then the last mapping used will be used for all
> > > > > > modules if it is listed in the [LibraryClasses] section of the
> > > > > > DSC file.  The only was to handle this type of name collision
> > > > > > is to use a module scoped library mapping in the
> > > > > > <LibraryClasses> section of each individual module that uses a
> > > > > > CrtLib.  I am only trying to avoid the potential for future
> > > > > > name collisions
> > > > for a library class/instance that is specific to the JSON use case.
> > > > > >
> > > > > > We recognize that several modules in edk2 have this type of
> > > > > > gasket between an EDK II env and a standard C lib.  We may
> > > > > > find a we to implement a more generic gasket and retire the
> > > > > > use of the implementation specific ones.  This is another
> > > > > > reason to use an implementation specific name in this use case
> > > > > > and be able to introduce a
> > > > more generic name in the future.
> > > > > >
> > > > > > Another comment below to see if there is a way to avoid
> > > > > > introducing a CrtLib class.
> > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > * RedfishPkg/Include/Library/CrtLib.h
> > > > > > > >   + Remove reference to MDE_CPU_IA64.  This has been
> > > > > > > > retired from the
> > > > > > > > edk2 repo.
> > > > > > > Ok.
> > > > > > > >   + I do see one remaining reference to this in the
> > > > > > > > CryptoPkg that need to
> > > > > > be
> > > > > > > >     removed.
> > > > > > > >
> > > > > > > > * RedfishPkg/Include/Library/JsonLib.h
> > > > > > > >   + Some of the function descriptions are very brief and I can not
> tell
> > > > > > > >     how to use the service from the description and more
> > > > > > > > importantly,
> > > I
> > > > > > > >     would not know how to write a unit test to verify the
> > > > > > > > expected
> > > > > > behavior.
> > > > > > > >     Since these are a set of public APIs from this package that you
> > > > > > > >     expect modules/libs from outside of RedfishPkg to use, then
> all of
> > > > > > > >     these public APIs must be fully documented.
> > > > > > > Most of the API in JsonLib are wrappers of native jansson APIs.
> > > > > > > We can mention the URL to jansson API reference document in
> > > > > > > file
> > > header.
> > > > > > > INVALID URI REMOVED
> > > > > > 3A__jansson.readthedo
> > > > > > >
> > > > > >
> > > >
> > >
> cs.io_en_2.13_index.html&d=DwIGaQ&c=C5b8zRQO1miGmBeVZ2LFWg&r=_
> > > > > > SN6FZBN4
> > > > > > > Vgi4Ulkskz6qU3NYRO03nHp9P7Z5q59A3E&m=vd-
> > > > > > uPz864czoYA5C7YaPgqXfdPjv4c5kB
> > > > > > >
> > > >
> zTwV60NvNQ&s=acVzN3x4yND0jkg44bJ48ZkyPyugjwsYvUGdD4nJL74&e=
> > > > > > > I will review all function header again,  please check v9 patch later.
> > > > > > >
> > > > > > > >   + Are there any of these APIs that are not really needed
> > > > > > > > by
> > > > modules/libs
> > > > > > > >     outside the RedfishPkg?  It would be better to remove
> > > > > > > > APIs that
> > > are
> > > > > > > >     not needed outside RedfishPkg from this public include file.
> > > > > > > >   + A couple examples that stood out are:
> > > > > > > >     JsonDecreaseReference()
> > > > > > > >     JsonIncreaseReference()
> > > > > > > >     JsonObjectIterator()
> > > > > > > >     JsonObjectIteratorValue()
> > > > > > > >     JsonObjectIteratorNext()
> > > > > > > The native jansson APIs of all above wrappers are used in
> libredfish.
> > > > > > > So that is the potential use case for other JSON applications.
> > > > > >
> > > > > > Can you provide a pointer to an example of this use case?
> > > > > >
> > > > > > I am trying to make sure we are doing the right design of
> > > > > > RedfishPkg with respect to CrtLib for this use case.  Are
> > > > > > these are JSON apps that do not use JsonLib, but are expected
> > > > > > to build in an EDK II build environment?  Would these JSON
> > > > > > apps require more standard C lib services than the CrtLib used
> > > > > > to build JsonLib?  Where would those
> > > > additional C lib services come from?
> > > > > >
> > > > > > There is a standard C lib in edk2-libc.  Would that be
> > > > > > required to build the JSON apps.
> > > > > >
> > > > > > In other uses of submodules with C lib dependencies, a new
> > > > > > CrtLib like lib class was not added and instead the support
> > > > > > was added directly to the EDK II wrapper APIs. Some examples are:
> > > > > >   * MdeModulePkg\Library\BrotliCustomDecompressLib
> > > > > >   * MdeModulePkg\Universal\RegularExpressionDxe
> > > > > >
> > > > > > If there are use cases where the CrtLib will be added to an
> > > > > > INF outside the RedfishPkg, then I still think the name needs
> > > > > > to be changed to be specific to the JSON use case.
> > > > > CrtLib should not be added to INF outside RedfishPkg, but it
> > > > > will be added
> > > > to platform DSC file.
> > > > > >
> > > > > > If the use of CrtLib is only within the RedfishPkg, then the
> > > > > > Library Class can be declared in a
> > > > > > [LibraryClasses.Common.Private] section of the DEC file.  See
> > > > > > UnitTestFrameworkPkg for examples
> > > > > Because CrtLib, JsonLib and other RedfishPkg modules will be
> > > > > included in
> > > > other package dsc file (e.g. EmulatorPkg).
> > > > > What if in EmulatorPkg one CrtLib libraryclass maps to the
> > > > > private one under RedfishPkg, but another with the same name is
> > > > > the public library
> > > > provided by other package (e.g. MdeModulePkg) and used by modules
> > > > other than RedfishPkg?
> > > > > Is edk2 build tool that smart to link the private CrtLib for
> > > > > RedfishPkg modules and all other non RedfishPkg modules are
> > > > > linked with
> > > > the public one?
> > > > >
> > > > > Abner
> > > > >
> > > >
> > > > No.  Not that smart.
> > > >
> > > > There are global lib class -> lib instance mapping in
> > > > [LibraryClasses] sections of DSC files.  If the same lib class is
> > > > listed more than once, then the last mapping wins.
> > > >
> > > > If a module scoped <LibraryClasses> section is used, then then
> > > > last mapping in the scope of that module wins.
> > > >
> > > > If the same lib class name is declared by more than one package
> > > > used in a platform DSC, then the only remediation is to remove use
> > > > of the global [LibraryClasses] section and use a module scope
> > > > <LibraryClasses> section in every module that depends on that lib
> > > > class
> > > name.
> > > Ok, I will rename it to RedfishCrtLib.
> > >
> > > Abner
> > > >
> > > > > >
> > > > > > >
> > > > > > > >   + JsonDumpString()
> > > > > > > >     func header params do not match func prototype
> > > > > > > >     Does not describe who allocates the return buffer and who
> > > > > > > >     is responsible for freeing the buffer returned.
> > > > > > > >     What do Flags do?  What is the difference between this
> > > > > > > >     function and JsonToText()?
> > > > > > > In JsonToText, it only converts JSON array and object to text.
> > > > > > > We could just remove this for now because I don’t really
> > > > > > > remember the reason
> > > > > > to create this function, it has been a while. Seems to me it
> > > > > > is fine to remove this function.
> > > > > > >
> > > > > > > >   + JsonLoadBuffer() - Error param description missing
> > > > > > > >   + JsonArrayGetValue() does not describe the conditions NULL
> > > > > > > >     is returned.
> > > > > > > >   + JsonObjectGetKeys().  Return type is CHAR8**.  What
> > > > > > > >     function need to be called to free the array?
> > > > > > > All above addressed.
> > > > > > >
> > > > > > > >   + JsonValueGetAsciiString() and JsonValueGetUnicodeString()
> > > > > > > >     are asymmetric.  The Ascii one states that change will
> > > > > > > >     modify the original string.  The Unicode one says that the
> > > > > > > >     caller needs to free the returned string.  Any reason we
> > > > > > > >     can not make them symmetric?
> > > > > > > Jansson doesn't support Unicode string. The memory of the
> > > > > > > unicode string returned by JsonValueGetUnicodeString Is
> > > > > > > allocated by
> > > > > > UTF8StrToUCS2().
> > > > > > >  > Also, if Ascii one should
> > > > > > > >     not be modified, why isn’t the return type CONST?
> > > > > > > Yes. will do that.
> > > > > > >
> > > > > > > >
> > > > > > > > * RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > > > > >   + Change [Sources.common] to [Sources]
> > > > > > > done
> > > > > > > > * RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > > > > >   + Does this lib instance really depend on MdeModulePkg?
> > > > > > > Yes, SortLib
> > > > > > > >   + Have you reviewed the module types this lib instance is
> > > > > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM
> drivers?
> > > > > > > >     If there are SMM use cases, then why is MM excluded?
> > > > > > > Will just keep DXE_DRVER, UEFI_APPLICATION and UEFI_DRIVER.
> > > > These
> > > > > > are
> > > > > > > module types have potential use cases I can think of now.
> > > > > > > >
> > > > > > > > * RedfishPkg/Library/JsonLib
> > > > > > > >   + Readme.rst still has references to
> > > > > > > > JanssonJsonLibMapping.h
> > > > > > > done
> > > > > > > >   + Have you reviewed the module types this lib instance is
> > > > > > > >     compatible with?  Why does it need to support DXE_CORE?
> > > > > > > >     Are their JsonLib use cases for DXE_RUNTIME and SMM
> drivers?
> > > > > > > >     If there are SMM use cases, then why is MM excluded?
> > > > > > > Answered above
> > > > > > > >   + JsonLib.inf has a [BuildOptions] section that disables
> > > > > > > > some warnings
> > > > > > that
> > > > > > > >     make me concerned that this library may have some
> > > > > > > > issues with 32-bit builds.
> > > > > > > >     Have you fully validated all 32-bit CPU builds and
> > > > > > > > validated the
> > > > > > functionality
> > > > > > > >     of all services from the JsonLib for all ranges of input values?
> > > > > > > Yes, IA32 build is validated. But not validating on the
> > > > > > > functionalities IA32. I don't have that use case, we can get
> > > > > > > back to fix the
> > > > > > issue if any when  someone runs this on IA32.
> > > > > >
> > > > > > I did some local testing with VS2019.  I found that a much
> > > > > > smaller set of warning disables are required for IA32 and X64
> > > > > > and the set is different for
> > > > > > IA32 and X64.  Can you review what is needed and minimize the
> > > > > > required set of each supported arch?
> > > > > >
> > > > > >   MSFT:*_*_X64_CC_FLAGS = /wd4244 /wd4090 /wd4334
> > > > > > /DHAVE_CONFIG_H=1 /U_WIN32 /UWIN64 /U_MSC_VER
> > > > > >   MSFT:*_*_IA32_CC_FLAGS = /wd4244 /wd4090
> > > /DHAVE_CONFIG_H=1
> > > > > > /U_WIN32 /UWIN64 /U_MSC_VER
> > > > > >
> > > > > > > >
> > > > > > > > * RedfishLibs.dsc.inc
> > > > > > > >   It is better to add [LibraryClasses] statement to this file, so it
> > > > > > > >   can be include anywhere in a DSC file.  With current
> > > implementation
> > > > > > > >   if it is not included within a [LibraryClasses] section, it will
> > > > > > > >   generate a build error.
> > > > > > > I will separate this to another set of patch. Don’t mix up
> > > > > > > with jansson edk2
> > > > > > port.
> > > > > > >
> > > > > > > >You might also consider changing the name
> > > > > > > >   of this file in case you want to add more than just lib mappings
> > > > > > > >   to this file in the future.  See UnitTestFramworkPkg for
> examples.
> > > > > > > >
> > > > > > > > Best regards,
> > > > > > > >
> > > > > > > > Mike
> > > > > > > >
> > > > > > > > > -----Original Message-----
> > > > > > > > > From: Abner Chang <abner.chang@hpe.com>
> > > > > > > > > Sent: Thursday, December 17, 2020 5:19 AM
> > > > > > > > > To: devel@edk2.groups.io
> > > > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret
> > > > > > > > > Barkelew <Bret.Barkelew@microsoft.com>; Andrew Fish
> > > > > > > > > <afish@apple.com>; Laszlo Ersek <lersek@redhat.com>;
> > > > > > > > > Leif Lindholm <leif@nuviainc.com>; Kinney, Michael D
> > > > > > > > > <michael.d.kinney@intel.com>; Liming Gao
> > > > > > > > > <gaoliming@byosoft.com.cn>; Nickle Wang
> > > > <nickle.wang@hpe.com>;
> > > > > > > > Peter
> > > > > > > > > O'Hanley <peter.ohanley@hpe.com>
> > > > > > > > > Subject: [PATCH v8 0/6] jansson edk2 port
> > > > > > > > >
> > > > > > > > > In v8, - Assigne patch file order
> > > > > > > > >        - Add Acked-by tags In v7, - Remove C RTC header
> > > > > > > > > files to under
> > > > [Include.Common.Private]
> > > > > > > > >          in RedfishPkg.dec.
> > > > > > > > >        - address comments given by Mike Kinney.
> > > > > > > > > In v6, Remove JanssonJsonMapping.h In v5, move
> > > > > > > > > BaseUcs2Utf8Lib to under RedfishPkg.
> > > > > > > > > In v4,
> > > > > > > > >        - Address review comments
> > > > > > > > >        - Seperate CRT functions to a individule library CrtLib under
> > > > > > > > >          RedfishPkg.
> > > > > > > > >        - Seperate UCS2-UTF8 functions to a individule library
> > > > > > > > >          BaseUcs2Utf8Lib under MdeModulePkg.
> > > > > > > > >
> > > > > > > > > In v3, Add jansson library as the required submoudle in
> > > > > > > > >        CiSettings.py for CI test.
> > > > > > > > > In v2, JsonLib is moved to under RedfishPkg.
> > > > > > > > >
> > > > > > > > > edk2 JSON library is based on jansson open source
> > > > > > > > > (https://github.com/akheron/jansson) and wrapped as an
> > > > > > > > > edk2
> > > > library.
> > > > > > > > > edk2 JsonLib will be used by edk2 Redfish feature
> > > > > > > > > drivers (not contributed yet) and the edk2 port of
> > > > > > > > > libredfish library (not contributed yet) based on DMTF
> > > > > > > > > GitHub (https://github.com/DMTF/libredfish).
> > > > > > > > >
> > > > > > > > > Jansson is licensed under the MIT license(refer to
> > > > > > > > > ReadMe.rst under
> > > > > > edk2).
> > > > > > > > > It is used in production and its API is stable. In
> > > > > > > > > UEFI/EDKII environment, Redfish project consumes jansson
> > > > > > > > > to achieve JSON
> > > > > > > > operations.
> > > > > > > > >
> > > > > > > > > * Jansson version on edk2: 2.13.1
> > > > > > > > >
> > > > > > > > > * EDKII jansson library wrapper:
> > > > > > > > >    - JsonLib.h:
> > > > > > > > >      This is the denifitions of EDKII JSON APIs which are mapped
> to
> > > > > > > > >      jannson funcitons accordingly.
> > > > > > > > >
> > > > > > > > >    - JanssonJsonLibMapping.h:
> > > > > > > > >      This is the wrapper file to map funcitons and definitions
> used in
> > > > > > > > >      native jannson applications to edk2 JsonLib. This avoids the
> > > > > > > > >      modifications on native jannson applications to be built
> under
> > > > > > > > >      edk2 environment.
> > > > > > > > >
> > > > > > > > > *Known issue:
> > > > > > > > >   Build fail with jansson/src/load.c, overrride and add code in
> load.c
> > > > > > > > >   to conditionally use stdin according to HAVE_UNISTD_H
> macro.
> > > > > > > > >   The PR is submitted to jansson open source community.
> > > > > > > > >   https://github.com/akheron/jansson/pull/558
> > > > > > > > >
> > > > > > > > > Signed-off-by: Abner Chang <abner.chang@hpe.com>
> > > > > > > > >
> > > > > > > > > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > > > > > > > > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > > > > > > > > Cc: Andrew Fish <afish@apple.com>
> > > > > > > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > > > > > > Cc: Leif Lindholm <leif@nuviainc.com>
> > > > > > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > > > > > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > > > > > > > > Cc: Nickle Wang <nickle.wang@hpe.com>
> > > > > > > > > Cc: Peter O'Hanley <peter.ohanley@hpe.com>
> > > > > > > > >
> > > > > > > > > Abner Chang (6):
> > > > > > > > >   RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library
> > > > > > > > >   edk2: jansson submodule for edk2 JSON library
> > > > > > > > >   RedfishPkg/CrtLib: C runtime library
> > > > > > > > >   RedfishPkg/library: EDK2 port of jansson library
> > > > > > > > >   RedfishPkg: Add EDK2 port of jansson library to build
> > > > > > > > >   .pytool: Add required submodule for JsonLib
> > > > > > > > >
> > > > > > > > >  .gitmodules                                   |    3 +
> > > > > > > > >  .pytool/CISettings.py                         |    2 +
> > > > > > > > >  ReadMe.rst                                    |    1 +
> > > > > > > > >  RedfishPkg/Include/Crt/assert.h               |   16 +
> > > > > > > > >  RedfishPkg/Include/Crt/errno.h                |   16 +
> > > > > > > > >  RedfishPkg/Include/Crt/limits.h               |   16 +
> > > > > > > > >  RedfishPkg/Include/Crt/math.h                 |   16 +
> > > > > > > > >  RedfishPkg/Include/Crt/stdarg.h               |   15 +
> > > > > > > > >  RedfishPkg/Include/Crt/stddef.h               |   16 +
> > > > > > > > >  RedfishPkg/Include/Crt/stdio.h                |   15 +
> > > > > > > > >  RedfishPkg/Include/Crt/stdlib.h               |   16 +
> > > > > > > > >  RedfishPkg/Include/Crt/string.h               |   16 +
> > > > > > > > >  RedfishPkg/Include/Crt/sys/time.h             |   15 +
> > > > > > > > >  RedfishPkg/Include/Crt/sys/types.h            |   15 +
> > > > > > > > >  RedfishPkg/Include/Crt/time.h                 |   15 +
> > > > > > > > >  RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h  |   61 +
> > > > > > > > >  RedfishPkg/Include/Library/CrtLib.h           |  191 +++
> > > > > > > > >  RedfishPkg/Include/Library/JsonLib.h          |  763
> +++++++++++
> > > > > > > > >  .../Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c |  421
> +++++++
> > > > > > > > >  .../BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf       |   31 +
> > > > > > > > >  RedfishPkg/Library/CrtLib/CrtLib.c            |  595 +++++++++
> > > > > > > > >  RedfishPkg/Library/CrtLib/CrtLib.inf          |   38 +
> > > > > > > > >  RedfishPkg/Library/JsonLib/JsonLib.c          |  964
> > > ++++++++++++++
> > > > > > > > >  RedfishPkg/Library/JsonLib/JsonLib.inf        |   89 ++
> > > > > > > > >  RedfishPkg/Library/JsonLib/Readme.rst         |   40 +
> > > > > > > > >  RedfishPkg/Library/JsonLib/jansson            |    1 +
> > > > > > > > >  RedfishPkg/Library/JsonLib/jansson_config.h   |   41 +
> > > > > > > > >  .../Library/JsonLib/jansson_private_config.h  |   19 +
> > > > > > > > >  RedfishPkg/Library/JsonLib/load.c             | 1111
> > > > +++++++++++++++++
> > > > > > > > >  RedfishPkg/RedfishLibs.dsc.inc                |    3 +
> > > > > > > > >  RedfishPkg/RedfishPkg.ci.yaml                 |   25 +
> > > > > > > > >  RedfishPkg/RedfishPkg.dec                     |   25 +
> > > > > > > > >  RedfishPkg/RedfishPkg.dsc                     |    3 +
> > > > > > > > >  33 files changed, 4614 insertions(+)  create mode
> > > > > > > > > 100644 RedfishPkg/Include/Crt/assert.h  create mode
> > > > > > > > > 100644 RedfishPkg/Include/Crt/errno.h  create mode
> > > > > > > > > 100644 RedfishPkg/Include/Crt/limits.h  create mode
> > > > > > > > > 100644 RedfishPkg/Include/Crt/math.h  create mode 100644
> > > > > > > > > RedfishPkg/Include/Crt/stdarg.h  create mode 100644
> > > > > > > > > RedfishPkg/Include/Crt/stddef.h  create mode 100644
> > > > > > > > > RedfishPkg/Include/Crt/stdio.h  create mode 100644
> > > > > > > > > RedfishPkg/Include/Crt/stdlib.h  create mode 100644
> > > > > > > > > RedfishPkg/Include/Crt/string.h  create mode 100644
> > > > > > > > > RedfishPkg/Include/Crt/sys/time.h  create mode 100644
> > > > > > > > > RedfishPkg/Include/Crt/sys/types.h
> > > > > > > > >  create mode 100644 RedfishPkg/Include/Crt/time.h
> > > > > > > > > create mode
> > > > > > > > > 100644 RedfishPkg/Include/Library/BaseUcs2Utf8Lib.h
> > > > > > > > >  create mode 100644 RedfishPkg/Include/Library/CrtLib.h
> > > > > > > > >  create mode 100644 RedfishPkg/Include/Library/JsonLib.h
> > > > > > > > >  create mode 100644
> > > > > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.c
> > > > > > > > >  create mode 100644
> > > > > > > > > RedfishPkg/Library/BaseUcs2Utf8Lib/BaseUcs2Utf8Lib.inf
> > > > > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.c
> > > > > > > > >  create mode 100644 RedfishPkg/Library/CrtLib/CrtLib.inf
> > > > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/JsonLib.c
> > > > > > > > >  create mode 100644
> > > > > > > > > RedfishPkg/Library/JsonLib/JsonLib.inf
> > > > > > > > >  create mode 100644
> > > > > > > > > RedfishPkg/Library/JsonLib/Readme.rst
> > > > > > > > >  create mode 160000 RedfishPkg/Library/JsonLib/jansson
> > > > > > > > >  create mode 100644
> > > > > > > > > RedfishPkg/Library/JsonLib/jansson_config.h
> > > > > > > > >  create mode 100644
> > > > > > > > > RedfishPkg/Library/JsonLib/jansson_private_config.h
> > > > > > > > >  create mode 100644 RedfishPkg/Library/JsonLib/load.c
> > > > > > > > >
> > > > > > > > > --
> > > > > > > > > 2.17.1
> > > > > > >
> > > > >
> >
> >
> >
> > 
> >


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2020-12-24 12:35 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-17 13:18 [PATCH v8 0/6] jansson edk2 port Abner Chang
2020-12-17 13:18 ` [PATCH v8 1/6] RedfishPkg/Ucs2Utf8lib: UCS2 to UFT8 manipulation library Abner Chang
2020-12-17 13:18 ` [PATCH v8 2/6] edk2: jansson submodule for edk2 JSON library Abner Chang
2020-12-17 13:18 ` [PATCH v8 3/6] RedfishPkg/CrtLib: C runtime library Abner Chang
2020-12-17 13:18 ` [PATCH v8 4/6] RedfishPkg/library: EDK2 port of jansson library Abner Chang
2020-12-18 11:19   ` Leif Lindholm
2020-12-17 13:18 ` [PATCH v8 5/6] RedfishPkg: Add EDK2 port of jansson library to build Abner Chang
2020-12-17 13:18 ` [PATCH v8 6/6] .pytool: Add required submodule for JsonLib Abner Chang
2020-12-20 19:42 ` [PATCH v8 0/6] jansson edk2 port Michael D Kinney
2020-12-21  8:17   ` Abner Chang
2020-12-22 18:14     ` Michael D Kinney
2020-12-23  3:42       ` Abner Chang
2020-12-23  4:28       ` Abner Chang
2020-12-23  4:39       ` Abner Chang
2020-12-23  6:10         ` Michael D Kinney
2020-12-23  7:53           ` Abner Chang
2020-12-23  9:02             ` Abner Chang
2020-12-24  6:49               ` [edk2-devel] " Michael D Kinney
2020-12-24 12:34                 ` Abner Chang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox