REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the RedfishPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Abner Chang <abner.chang@hpe.com>
		
			
				
	
	
		
			1089 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1089 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  CRT wrapper functions for system call,the string operation functions
 | 
						|
  are remodeled after edk2-libc.
 | 
						|
 | 
						|
  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/RedfishCrtLib.h>
 | 
						|
#include <Library/MemoryAllocationLib.h>
 | 
						|
#include <Library/SortLib.h>
 | 
						|
#include <Library/UefiRuntimeServicesTableLib.h>
 | 
						|
 | 
						|
int   errno            = 0;
 | 
						|
char  errnum_message[] = "We don't support to map errnum to the error message on edk2 Redfish\n";
 | 
						|
 | 
						|
// This is required to keep VC++ happy if you use floating-point
 | 
						|
int  _fltused = 1;
 | 
						|
 | 
						|
/**
 | 
						|
  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;
 | 
						|
}
 | 
						|
 | 
						|
static UINT8  BitMask[] = {
 | 
						|
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
 | 
						|
};
 | 
						|
 | 
						|
#define WHICH8(c)     ((unsigned char)(c) >> 3)
 | 
						|
#define WHICH_BIT(c)  (BitMask[((c) & 0x7)])
 | 
						|
#define BITMAP64  ((UINT64 *)bitmap)
 | 
						|
 | 
						|
static
 | 
						|
void
 | 
						|
BuildBitmap (
 | 
						|
  unsigned char  *bitmap,
 | 
						|
  const char     *s2,
 | 
						|
  int            n
 | 
						|
  )
 | 
						|
{
 | 
						|
  unsigned char  bit;
 | 
						|
  int            index;
 | 
						|
 | 
						|
  // Initialize bitmap.  Bit 0 is always 1 which corresponds to '\0'
 | 
						|
  for (BITMAP64[0] = index = 1; index < n; index++) {
 | 
						|
    BITMAP64[index] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  // Set bits in bitmap corresponding to the characters in s2
 | 
						|
  for ( ; *s2 != '\0'; s2++) {
 | 
						|
    index         = WHICH8 (*s2);
 | 
						|
    bit           = WHICH_BIT (*s2);
 | 
						|
    bitmap[index] = bitmap[index] | bit;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/** The strpbrk function locates the first occurrence in the string pointed to
 | 
						|
    by s1 of any character from the string pointed to by s2.
 | 
						|
 | 
						|
    @return   The strpbrk function returns a pointer to the character, or a
 | 
						|
              null pointer if no character from s2 occurs in s1.
 | 
						|
**/
 | 
						|
char *
 | 
						|
strpbrk (
 | 
						|
  const char  *s1,
 | 
						|
  const char  *s2
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8  bitmap[(((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
 | 
						|
  UINT8  bit;
 | 
						|
  int    index;
 | 
						|
 | 
						|
  BuildBitmap (bitmap, s2, sizeof (bitmap) / sizeof (UINT64));
 | 
						|
 | 
						|
  for ( ; *s1 != '\0'; ++s1) {
 | 
						|
    index = WHICH8 (*s1);
 | 
						|
    bit   = WHICH_BIT (*s1);
 | 
						|
    if ((bitmap[index] & bit) != 0) {
 | 
						|
      return (char *)s1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/** The strerror function maps the number in errnum to a message string.
 | 
						|
    Typically, the values for errnum come from errno, but strerror shall map
 | 
						|
    any value of type int to a message.
 | 
						|
 | 
						|
    The implementation shall behave as if no library function calls the
 | 
						|
    strerror function.
 | 
						|
 | 
						|
    @return   The strerror function returns a pointer to the string, the
 | 
						|
              contents of which are locale specific.  The array pointed to
 | 
						|
              shall not be modified by the program, but may be overwritten by
 | 
						|
              a subsequent call to the strerror function.
 | 
						|
**/
 | 
						|
char *
 | 
						|
strerror (
 | 
						|
  int  errnum
 | 
						|
  )
 | 
						|
{
 | 
						|
  return errnum_message;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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 EOF;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Open stream file, we don't support file operastion on edk2 JSON library.
 | 
						|
 | 
						|
  @return 0 Unsupported
 | 
						|
 | 
						|
**/
 | 
						|
FILE *
 | 
						|
fopen (
 | 
						|
  const char  *filename,
 | 
						|
  const char  *mode
 | 
						|
  )
 | 
						|
{
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Read stream from file, we don't support file operastion on edk2 JSON library.
 | 
						|
 | 
						|
  @return 0 Unsupported
 | 
						|
 | 
						|
**/
 | 
						|
size_t
 | 
						|
fread (
 | 
						|
  void    *ptr,
 | 
						|
  size_t  size,
 | 
						|
  size_t  count,
 | 
						|
  FILE    *stream
 | 
						|
  )
 | 
						|
{
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Write stream from file, we don't support file operastion on edk2 JSON library.
 | 
						|
 | 
						|
  @return 0 Unsupported
 | 
						|
 | 
						|
**/
 | 
						|
size_t
 | 
						|
fwrite (
 | 
						|
  const void  *ptr,
 | 
						|
  size_t      size,
 | 
						|
  size_t      count,
 | 
						|
  FILE        *stream
 | 
						|
  )
 | 
						|
{
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Close file, we don't support file operastion on edk2 JSON library.
 | 
						|
 | 
						|
  @return 0 Unsupported
 | 
						|
 | 
						|
**/
 | 
						|
int
 | 
						|
fclose (
 | 
						|
  FILE  *stream
 | 
						|
  )
 | 
						|
{
 | 
						|
  return EOF;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Write the formatted string to file, we don't support file operastion on edk2 JSON library.
 | 
						|
 | 
						|
  @return 0 Unsupported
 | 
						|
 | 
						|
**/
 | 
						|
int
 | 
						|
fprintf (
 | 
						|
  FILE        *stream,
 | 
						|
  const char  *format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function check if this is the formating string specifier.
 | 
						|
 | 
						|
  @param[in]      FormatString     A Null-terminated ASCII format string.
 | 
						|
  @param[in,out]  CurrentPosition  The starting position at the given string to check for
 | 
						|
                                   "[flags][width][.precision][length]s" string specifier.
 | 
						|
  @param[in]      StrLength        Maximum string length.
 | 
						|
 | 
						|
  @return BOOLEAN   TRUE means this is the formating string specifier. CurrentPosition is
 | 
						|
                    returned at the position of "s".
 | 
						|
                    FALSE means this is not the formating string specifier.. CurrentPosition is
 | 
						|
                    returned at the position of failed character.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
CheckFormatingString (
 | 
						|
  IN     CONST CHAR8  *FormatString,
 | 
						|
  IN OUT UINTN        *CurrentPosition,
 | 
						|
  IN     UINTN        StrLength
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR8  FormatStringParamater;
 | 
						|
 | 
						|
  while (*(FormatString + *CurrentPosition) != 's') {
 | 
						|
    //
 | 
						|
    // Loop until reach character 's' if the formating string is
 | 
						|
    // compliant with "[flags][width][.precision][length]" format for
 | 
						|
    // the string specifier.
 | 
						|
    //
 | 
						|
    FormatStringParamater = *(FormatString + *CurrentPosition);
 | 
						|
    if ((FormatStringParamater != '-') &&
 | 
						|
        (FormatStringParamater != '+') &&
 | 
						|
        (FormatStringParamater != '*') &&
 | 
						|
        (FormatStringParamater != '.') &&
 | 
						|
        !(((UINTN)FormatStringParamater >= (UINTN)'0') && ((UINTN)FormatStringParamater <= (UINTN)'9'))
 | 
						|
        )
 | 
						|
    {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    (*CurrentPosition)++;
 | 
						|
    if (*CurrentPosition >= StrLength) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This function clones *FormatString however replaces "%s" with "%a" in the
 | 
						|
  returned string.
 | 
						|
 | 
						|
  @param[in] A Null-terminated ASCII format string.
 | 
						|
 | 
						|
  @return The new format string. Caller has to free the memory of this string
 | 
						|
          using FreePool().
 | 
						|
 | 
						|
**/
 | 
						|
CHAR8 *
 | 
						|
ReplaceUnicodeToAsciiStrFormat (
 | 
						|
  IN CONST CHAR8  *FormatString
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN    FormatStrSize;
 | 
						|
  UINTN    FormatStrIndex;
 | 
						|
  UINTN    FormatStrSpecifier;
 | 
						|
  BOOLEAN  PercentageMark;
 | 
						|
  CHAR8    *TempFormatBuffer;
 | 
						|
  BOOLEAN  IsFormatString;
 | 
						|
 | 
						|
  //
 | 
						|
  // Error checking.
 | 
						|
  //
 | 
						|
  if (FormatString == NULL) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  FormatStrSize = AsciiStrSize (FormatString);
 | 
						|
  if (FormatStrSize == 0) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  TempFormatBuffer = AllocatePool (FormatStrSize); // Allocate memory for the
 | 
						|
                                                   // new string.
 | 
						|
  if (TempFormatBuffer == NULL) {
 | 
						|
    return NULL;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Clone *FormatString but replace "%s" wih "%a".
 | 
						|
  // "%%" is not considered as the format tag.
 | 
						|
  //
 | 
						|
  PercentageMark = FALSE;
 | 
						|
  FormatStrIndex = 0;
 | 
						|
  while (FormatStrIndex < FormatStrSize) {
 | 
						|
    if (PercentageMark == TRUE) {
 | 
						|
      //
 | 
						|
      // Previous character is "%".
 | 
						|
      //
 | 
						|
      PercentageMark = FALSE;
 | 
						|
      if (*(FormatString + FormatStrIndex) != '%') {
 | 
						|
        // Check if this is double "%".
 | 
						|
        FormatStrSpecifier = FormatStrIndex;
 | 
						|
        //
 | 
						|
        // Check if this is the formating string specifier.
 | 
						|
        //
 | 
						|
        IsFormatString = CheckFormatingString (FormatString, &FormatStrSpecifier, FormatStrSize);
 | 
						|
        if ((FormatStrSpecifier - FormatStrIndex) != 0) {
 | 
						|
          CopyMem (
 | 
						|
            (VOID *)(TempFormatBuffer + FormatStrIndex),
 | 
						|
            (VOID *)(FormatString + FormatStrIndex),
 | 
						|
            FormatStrSpecifier - FormatStrIndex
 | 
						|
            );
 | 
						|
        }
 | 
						|
 | 
						|
        FormatStrIndex = FormatStrSpecifier;
 | 
						|
        if (IsFormatString == TRUE) {
 | 
						|
          //
 | 
						|
          // Replace 's' with 'a' which is printed in ASCII
 | 
						|
          // format on edk2 environment.
 | 
						|
          //
 | 
						|
          *(TempFormatBuffer + FormatStrSpecifier) = 'a';
 | 
						|
          FormatStrIndex++;
 | 
						|
        }
 | 
						|
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      goto ContinueCheck;
 | 
						|
    }
 | 
						|
 | 
						|
    if (*(FormatString + FormatStrIndex) == '%') {
 | 
						|
      //
 | 
						|
      // This character is "%", set the flag.
 | 
						|
      //
 | 
						|
      PercentageMark = TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
ContinueCheck:
 | 
						|
    //
 | 
						|
    // Clone character to the new string and advance FormatStrIndex
 | 
						|
    // to process next character.
 | 
						|
    //
 | 
						|
    *(TempFormatBuffer + FormatStrIndex) = *(FormatString + FormatStrIndex);
 | 
						|
    FormatStrIndex++;
 | 
						|
  }
 | 
						|
 | 
						|
  return TempFormatBuffer;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This is the Redfish version of CRT vsnprintf function, this function replaces "%s" to
 | 
						|
  "%a" before invoking AsciiVSPrint(). That is because "%s" is unicode base on edk2
 | 
						|
  environment however "%s" is ascii code base on vsnprintf().
 | 
						|
  See definitions of AsciiVSPrint() for the details.
 | 
						|
 | 
						|
  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
 | 
						|
                          ASCII string.
 | 
						|
  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
 | 
						|
  @param  FormatString    A Null-terminated ASCII format string.
 | 
						|
  @param  Marker          VA_LIST marker for the variable argument list.
 | 
						|
 | 
						|
  @return The number of ASCII characters in the produced output buffer not including the
 | 
						|
          Null-terminator.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
RedfishAsciiVSPrint (
 | 
						|
  OUT CHAR8        *StartOfBuffer,
 | 
						|
  IN  UINTN        BufferSize,
 | 
						|
  IN  CONST CHAR8  *FormatString,
 | 
						|
  IN  VA_LIST      Marker
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR8  *TempFormatBuffer;
 | 
						|
  UINTN  LenStrProduced;
 | 
						|
 | 
						|
  //
 | 
						|
  // Looking for "%s" in the format string and replace it
 | 
						|
  // with "%a" for printing ASCII code characters on edk2
 | 
						|
  // environment.
 | 
						|
  //
 | 
						|
  TempFormatBuffer = ReplaceUnicodeToAsciiStrFormat (FormatString);
 | 
						|
  if (TempFormatBuffer == NULL) {
 | 
						|
    return 0;
 | 
						|
  }
 | 
						|
 | 
						|
  LenStrProduced = AsciiVSPrint (StartOfBuffer, BufferSize, (CONST CHAR8 *)TempFormatBuffer, Marker);
 | 
						|
  FreePool (TempFormatBuffer);
 | 
						|
  return LenStrProduced;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  This is the Redfish version of CRT snprintf function, this function replaces "%s" to
 | 
						|
  "%a" before invoking AsciiSPrint(). That is because "%s" is unicode base on edk2
 | 
						|
  environment however "%s" is ascii code base on snprintf().
 | 
						|
  See definitions of AsciiSPrint() for the details.
 | 
						|
 | 
						|
  @param  StartOfBuffer   A pointer to the output buffer for the produced Null-terminated
 | 
						|
                          ASCII string.
 | 
						|
  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
 | 
						|
  @param  FormatString    A Null-terminated ASCII format string.
 | 
						|
  @param  ...             Variable argument list whose contents are accessed based on the
 | 
						|
                          format string specified by FormatString.
 | 
						|
 | 
						|
  @return The number of ASCII characters in the produced output buffer not including the
 | 
						|
          Null-terminator.
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
RedfishAsciiSPrint (
 | 
						|
  OUT CHAR8        *StartOfBuffer,
 | 
						|
  IN  UINTN        BufferSize,
 | 
						|
  IN  CONST CHAR8  *FormatString,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  VA_LIST  Marker;
 | 
						|
  UINTN    LenStrProduced;
 | 
						|
 | 
						|
  VA_START (Marker, FormatString);
 | 
						|
  LenStrProduced = RedfishAsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
 | 
						|
  return LenStrProduced;
 | 
						|
}
 |