RedfishCrtLib.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088
  1. /** @file
  2. CRT wrapper functions for system call,the string operation functions
  3. are remodeled after edk2-libc.
  4. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  5. (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
  6. SPDX-License-Identifier: BSD-2-Clause-Patent
  7. **/
  8. #include <Uefi.h>
  9. #include <Library/RedfishCrtLib.h>
  10. #include <Library/MemoryAllocationLib.h>
  11. #include <Library/SortLib.h>
  12. #include <Library/UefiRuntimeServicesTableLib.h>
  13. int errno = 0;
  14. char errnum_message[] = "We don't support to map errnum to the error message on edk2 Redfish\n";
  15. // This is required to keep VC++ happy if you use floating-point
  16. int _fltused = 1;
  17. /**
  18. Determine if a particular character is an alphanumeric character
  19. @return Returns 1 if c is an alphanumeric character, otherwise returns 0.
  20. **/
  21. int
  22. isalnum (
  23. int c
  24. )
  25. {
  26. //
  27. // <alnum> ::= [0-9] | [a-z] | [A-Z]
  28. //
  29. return ((('0' <= (c)) && ((c) <= '9')) ||
  30. (('a' <= (c)) && ((c) <= 'z')) ||
  31. (('A' <= (c)) && ((c) <= 'Z')));
  32. }
  33. /**
  34. Determine if a particular character is a digital character
  35. @return Returns 1 if c is an digital character, otherwise returns 0.
  36. **/
  37. int
  38. isdchar (
  39. int c
  40. )
  41. {
  42. //
  43. // [0-9] | [e +-.]
  44. //
  45. return ((('0' <= (c)) && ((c) <= '9')) ||
  46. (c == 'e') || (c == 'E') ||
  47. (c == '+') || (c == '-') ||
  48. (c == '.'));
  49. }
  50. /**
  51. Determine if a particular character is a space character
  52. @return Returns 1 if c is a space character
  53. **/
  54. int
  55. isspace (
  56. int c
  57. )
  58. {
  59. //
  60. // <space> ::= [ ]
  61. //
  62. return ((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n') || ((c) == '\v') || ((c) == '\f');
  63. }
  64. /**
  65. Allocates memory blocks
  66. */
  67. void *
  68. malloc (
  69. size_t size
  70. )
  71. {
  72. return AllocatePool ((UINTN)size);
  73. }
  74. /**
  75. De-allocates or frees a memory block
  76. */
  77. void
  78. free (
  79. void *ptr
  80. )
  81. {
  82. //
  83. // In Standard C, free() handles a null pointer argument transparently. This
  84. // is not true of FreePool() below, so protect it.
  85. //
  86. if (ptr != NULL) {
  87. FreePool (ptr);
  88. }
  89. }
  90. /**
  91. NetBSD Compatibility Function strdup creates a duplicate copy of a string.
  92. @return Returns the pointer to duplicated string.
  93. **/
  94. char *
  95. strdup (
  96. const char *str
  97. )
  98. {
  99. size_t len;
  100. char *copy;
  101. len = strlen (str) + 1;
  102. if ((copy = malloc (len)) == NULL) {
  103. return (NULL);
  104. }
  105. memcpy (copy, str, len);
  106. return (copy);
  107. }
  108. /** The toupper function converts a lowercase letter to a corresponding
  109. uppercase letter.
  110. @param[in] c The character to be converted.
  111. @return If the argument is a character for which islower is true and
  112. there are one or more corresponding characters, as specified by
  113. the current locale, for which isupper is true, the toupper
  114. function returns one of the corresponding characters (always the
  115. same one for any given locale); otherwise, the argument is
  116. returned unchanged.
  117. **/
  118. int
  119. toupper (
  120. IN int c
  121. )
  122. {
  123. if ((c >= 'a') && (c <= 'z')) {
  124. c = c - ('a' - 'A');
  125. }
  126. return c;
  127. }
  128. /**
  129. Digit to a value.
  130. @return Returns the value of digit.
  131. **/
  132. int
  133. Digit2Val (
  134. int c
  135. )
  136. {
  137. if (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) {
  138. /* If c is one of [A-Za-z]... */
  139. c = toupper (c) - 7; // Adjust so 'A' is ('9' + 1)
  140. }
  141. return c - '0'; // Value returned is between 0 and 35, inclusive.
  142. }
  143. /** The strtoll function converts the initial portion of the string pointed to
  144. by nptr to long long int representation.
  145. See the description for strtol for more information.
  146. @return The strtoll function returns the converted value, if any. If no
  147. conversion could be performed, zero is returned. If the correct
  148. value is outside the range of representable values, LLONG_MIN or
  149. LLONG_MAX is returned (according to the sign of the value, if any),
  150. and the value of the macro ERANGE is stored in errno.
  151. **/
  152. long long
  153. strtoll (
  154. const char *nptr,
  155. char **endptr,
  156. int base
  157. )
  158. {
  159. const char *pEnd;
  160. long long Result = 0;
  161. long long Previous;
  162. int temp;
  163. BOOLEAN Negative = FALSE;
  164. pEnd = nptr;
  165. if ((base < 0) || (base == 1) || (base > 36)) {
  166. if (endptr != NULL) {
  167. *endptr = NULL;
  168. }
  169. return 0;
  170. }
  171. // Skip leading spaces.
  172. while (isspace (*nptr)) {
  173. ++nptr;
  174. }
  175. // Process Subject sequence: optional sign followed by digits.
  176. if (*nptr == '+') {
  177. Negative = FALSE;
  178. ++nptr;
  179. } else if (*nptr == '-') {
  180. Negative = TRUE;
  181. ++nptr;
  182. }
  183. if (*nptr == '0') {
  184. /* Might be Octal or Hex */
  185. if (toupper (nptr[1]) == 'X') {
  186. /* Looks like Hex */
  187. if ((base == 0) || (base == 16)) {
  188. nptr += 2; /* Skip the "0X" */
  189. base = 16; /* In case base was 0 */
  190. }
  191. } else {
  192. /* Looks like Octal */
  193. if ((base == 0) || (base == 8)) {
  194. ++nptr; /* Skip the leading "0" */
  195. base = 8; /* In case base was 0 */
  196. }
  197. }
  198. }
  199. if (base == 0) {
  200. /* If still zero then must be decimal */
  201. base = 10;
  202. }
  203. if (*nptr == '0') {
  204. for ( ; *nptr == '0'; ++nptr) {
  205. /* Skip any remaining leading zeros */
  206. }
  207. pEnd = nptr;
  208. }
  209. while ( isalnum (*nptr) && ((temp = Digit2Val (*nptr)) < base)) {
  210. Previous = Result;
  211. Result = MultS64x64 (Result, base) + (long long int)temp;
  212. if ( Result <= Previous) {
  213. // Detect Overflow
  214. if (Negative) {
  215. Result = LLONG_MIN;
  216. } else {
  217. Result = LLONG_MAX;
  218. }
  219. Negative = FALSE;
  220. errno = ERANGE;
  221. break;
  222. }
  223. pEnd = ++nptr;
  224. }
  225. if (Negative) {
  226. Result = -Result;
  227. }
  228. // Save pointer to final sequence
  229. if (endptr != NULL) {
  230. *endptr = (char *)pEnd;
  231. }
  232. return Result;
  233. }
  234. /** The strtol, strtoll, strtoul, and strtoull functions convert the initial
  235. portion of the string pointed to by nptr to long int, long long int,
  236. unsigned long int, and unsigned long long int representation, respectively.
  237. First, they decompose the input string into three parts: an initial,
  238. possibly empty, sequence of white-space characters (as specified by the
  239. isspace function), a subject sequence resembling an integer represented in
  240. some radix determined by the value of base, and a final string of one or
  241. more unrecognized characters, including the terminating null character of
  242. the input string. Then, they attempt to convert the subject sequence to an
  243. integer, and return the result.
  244. If the value of base is zero, the expected form of the subject sequence is
  245. that of an integer constant, optionally preceded
  246. by a plus or minus sign, but not including an integer suffix. If the value
  247. of base is between 2 and 36 (inclusive), the expected form of the subject
  248. sequence is a sequence of letters and digits representing an integer with
  249. the radix specified by base, optionally preceded by a plus or minus sign,
  250. but not including an integer suffix. The letters from a (or A) through z
  251. (or Z) are ascribed the values 10 through 35; only letters and digits whose
  252. ascribed values are less than that of base are permitted. If the value of
  253. base is 16, the characters 0x or 0X may optionally precede the sequence of
  254. letters and digits, following the sign if present.
  255. The subject sequence is defined as the longest initial subsequence of the
  256. input string, starting with the first non-white-space character, that is of
  257. the expected form. The subject sequence contains no characters if the input
  258. string is empty or consists entirely of white space, or if the first
  259. non-white-space character is other than a sign or a permissible letter or digit.
  260. If the subject sequence has the expected form and the value of base is
  261. zero, the sequence of characters starting with the first digit is
  262. interpreted as an integer constant. If the subject sequence has the
  263. expected form and the value of base is between 2 and 36, it is used as the
  264. base for conversion, ascribing to each letter its value as given above. If
  265. the subject sequence begins with a minus sign, the value resulting from the
  266. conversion is negated (in the return type). A pointer to the final string
  267. is stored in the object pointed to by endptr, provided that endptr is
  268. not a null pointer.
  269. In other than the "C" locale, additional locale-specific subject sequence
  270. forms may be accepted.
  271. If the subject sequence is empty or does not have the expected form, no
  272. conversion is performed; the value of nptr is stored in the object pointed
  273. to by endptr, provided that endptr is not a null pointer.
  274. @return The strtol, strtoll, strtoul, and strtoull functions return the
  275. converted value, if any. If no conversion could be performed, zero
  276. is returned. If the correct value is outside the range of
  277. representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX,
  278. ULONG_MAX, or ULLONG_MAX is returned (according to the return type
  279. and sign of the value, if any), and the value of the macro ERANGE
  280. is stored in errno.
  281. **/
  282. long
  283. strtol (
  284. const char *nptr,
  285. char **endptr,
  286. int base
  287. )
  288. {
  289. const char *pEnd;
  290. long Result = 0;
  291. long Previous;
  292. int temp;
  293. BOOLEAN Negative = FALSE;
  294. pEnd = nptr;
  295. if ((base < 0) || (base == 1) || (base > 36)) {
  296. if (endptr != NULL) {
  297. *endptr = NULL;
  298. }
  299. return 0;
  300. }
  301. // Skip leading spaces.
  302. while (isspace (*nptr)) {
  303. ++nptr;
  304. }
  305. // Process Subject sequence: optional sign followed by digits.
  306. if (*nptr == '+') {
  307. Negative = FALSE;
  308. ++nptr;
  309. } else if (*nptr == '-') {
  310. Negative = TRUE;
  311. ++nptr;
  312. }
  313. if (*nptr == '0') {
  314. /* Might be Octal or Hex */
  315. if (toupper (nptr[1]) == 'X') {
  316. /* Looks like Hex */
  317. if ((base == 0) || (base == 16)) {
  318. nptr += 2; /* Skip the "0X" */
  319. base = 16; /* In case base was 0 */
  320. }
  321. } else {
  322. /* Looks like Octal */
  323. if ((base == 0) || (base == 8)) {
  324. ++nptr; /* Skip the leading "0" */
  325. base = 8; /* In case base was 0 */
  326. }
  327. }
  328. }
  329. if (base == 0) {
  330. /* If still zero then must be decimal */
  331. base = 10;
  332. }
  333. if (*nptr == '0') {
  334. for ( ; *nptr == '0'; ++nptr) {
  335. /* Skip any remaining leading zeros */
  336. }
  337. pEnd = nptr;
  338. }
  339. while ( isalnum (*nptr) && ((temp = Digit2Val (*nptr)) < base)) {
  340. Previous = Result;
  341. Result = (Result * base) + (long int)temp;
  342. if ( Result <= Previous) {
  343. // Detect Overflow
  344. if (Negative) {
  345. Result = LONG_MIN;
  346. } else {
  347. Result = LONG_MAX;
  348. }
  349. Negative = FALSE;
  350. errno = ERANGE;
  351. break;
  352. }
  353. pEnd = ++nptr;
  354. }
  355. if (Negative) {
  356. Result = -Result;
  357. }
  358. // Save pointer to final sequence
  359. if (endptr != NULL) {
  360. *endptr = (char *)pEnd;
  361. }
  362. return Result;
  363. }
  364. /** The strtoull function converts the initial portion of the string pointed to
  365. by nptr to unsigned long long int representation.
  366. See the description for strtol for more information.
  367. @return The strtoull function returns the converted value, if any. If no
  368. conversion could be performed, zero is returned. If the correct
  369. value is outside the range of representable values, ULLONG_MAX is
  370. returned and the value of the macro ERANGE is stored in errno.
  371. **/
  372. unsigned long long
  373. strtoull (
  374. const char *nptr,
  375. char **endptr,
  376. int base
  377. )
  378. {
  379. const char *pEnd;
  380. unsigned long long Result = 0;
  381. unsigned long long Previous;
  382. int temp;
  383. pEnd = nptr;
  384. if ((base < 0) || (base == 1) || (base > 36)) {
  385. if (endptr != NULL) {
  386. *endptr = NULL;
  387. }
  388. return 0;
  389. }
  390. // Skip leading spaces.
  391. while (isspace (*nptr)) {
  392. ++nptr;
  393. }
  394. // Process Subject sequence: optional + sign followed by digits.
  395. if (*nptr == '+') {
  396. ++nptr;
  397. }
  398. if (*nptr == '0') {
  399. /* Might be Octal or Hex */
  400. if (toupper (nptr[1]) == 'X') {
  401. /* Looks like Hex */
  402. if ((base == 0) || (base == 16)) {
  403. nptr += 2; /* Skip the "0X" */
  404. base = 16; /* In case base was 0 */
  405. }
  406. } else {
  407. /* Looks like Octal */
  408. if ((base == 0) || (base == 8)) {
  409. ++nptr; /* Skip the leading "0" */
  410. base = 8; /* In case base was 0 */
  411. }
  412. }
  413. }
  414. if (base == 0) {
  415. /* If still zero then must be decimal */
  416. base = 10;
  417. }
  418. if (*nptr == '0') {
  419. for ( ; *nptr == '0'; ++nptr) {
  420. /* Skip any remaining leading zeros */
  421. }
  422. pEnd = nptr;
  423. }
  424. while ( isalnum (*nptr) && ((temp = Digit2Val (*nptr)) < base)) {
  425. Previous = Result;
  426. Result = DivU64x32 (Result, base) + (unsigned long long)temp;
  427. if ( Result < Previous) {
  428. // If we overflowed
  429. Result = ULLONG_MAX;
  430. errno = ERANGE;
  431. break;
  432. }
  433. pEnd = ++nptr;
  434. }
  435. // Save pointer to final sequence
  436. if (endptr != NULL) {
  437. *endptr = (char *)pEnd;
  438. }
  439. return Result;
  440. }
  441. /**
  442. edk2 Jansson port does not support doubles, simply return 0.
  443. These conversion functions convert the initial portion of the string
  444. pointed to by nptr to double, float, and long double representation,
  445. respectively.
  446. The strtod(), strtof(), and strtold() functions return the converted
  447. value, if any.
  448. If endptr is not NULL, a pointer to the character after the last charac-
  449. ter used in the conversion is stored in the location referenced by
  450. endptr.
  451. If no conversion is performed, zero is returned and the value of nptr is
  452. stored in the location referenced by endptr.
  453. If the correct value would cause overflow, plus or minus HUGE_VAL,
  454. HUGE_VALF, or HUGE_VALL is returned (according to the sign and type of
  455. the return value), and ERANGE is stored in errno. If the correct value
  456. would cause underflow, zero is returned and ERANGE is stored in errno.
  457. @return Return 0.
  458. **/
  459. double
  460. strtod (
  461. const char *__restrict nptr,
  462. char **__restrict endptr
  463. )
  464. {
  465. DEBUG ((DEBUG_INFO, "We don't supprot double type on edk2 yet!"));
  466. ASSERT (FALSE);
  467. return (double)0;
  468. }
  469. static UINT8 BitMask[] = {
  470. 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
  471. };
  472. #define WHICH8(c) ((unsigned char)(c) >> 3)
  473. #define WHICH_BIT(c) (BitMask[((c) & 0x7)])
  474. #define BITMAP64 ((UINT64 *)bitmap)
  475. static
  476. void
  477. BuildBitmap (
  478. unsigned char *bitmap,
  479. const char *s2,
  480. int n
  481. )
  482. {
  483. unsigned char bit;
  484. int index;
  485. // Initialize bitmap. Bit 0 is always 1 which corresponds to '\0'
  486. for (BITMAP64[0] = index = 1; index < n; index++) {
  487. BITMAP64[index] = 0;
  488. }
  489. // Set bits in bitmap corresponding to the characters in s2
  490. for ( ; *s2 != '\0'; s2++) {
  491. index = WHICH8 (*s2);
  492. bit = WHICH_BIT (*s2);
  493. bitmap[index] = bitmap[index] | bit;
  494. }
  495. }
  496. /** The strpbrk function locates the first occurrence in the string pointed to
  497. by s1 of any character from the string pointed to by s2.
  498. @return The strpbrk function returns a pointer to the character, or a
  499. null pointer if no character from s2 occurs in s1.
  500. **/
  501. char *
  502. strpbrk (
  503. const char *s1,
  504. const char *s2
  505. )
  506. {
  507. UINT8 bitmap[(((UCHAR_MAX + 1) / CHAR_BIT) + (CHAR_BIT - 1)) & ~7U];
  508. UINT8 bit;
  509. int index;
  510. BuildBitmap (bitmap, s2, sizeof (bitmap) / sizeof (UINT64));
  511. for ( ; *s1 != '\0'; ++s1) {
  512. index = WHICH8 (*s1);
  513. bit = WHICH_BIT (*s1);
  514. if ((bitmap[index] & bit) != 0) {
  515. return (char *)s1;
  516. }
  517. }
  518. return NULL;
  519. }
  520. /** The strerror function maps the number in errnum to a message string.
  521. Typically, the values for errnum come from errno, but strerror shall map
  522. any value of type int to a message.
  523. The implementation shall behave as if no library function calls the
  524. strerror function.
  525. @return The strerror function returns a pointer to the string, the
  526. contents of which are locale specific. The array pointed to
  527. shall not be modified by the program, but may be overwritten by
  528. a subsequent call to the strerror function.
  529. **/
  530. char *
  531. strerror (
  532. int errnum
  533. )
  534. {
  535. return errnum_message;
  536. }
  537. /**
  538. Allocate and zero-initialize array.
  539. **/
  540. void *
  541. calloc (
  542. size_t Num,
  543. size_t Size
  544. )
  545. {
  546. void *RetVal;
  547. size_t NumSize;
  548. NumSize = Num * Size;
  549. RetVal = NULL;
  550. if (NumSize != 0) {
  551. RetVal = malloc (NumSize);
  552. if ( RetVal != NULL) {
  553. (VOID)ZeroMem (RetVal, NumSize);
  554. }
  555. }
  556. DEBUG ((DEBUG_POOL, "0x%p = calloc(%d, %d)\n", RetVal, Num, Size));
  557. return RetVal;
  558. }
  559. //
  560. // The arrays give the cumulative number of days up to the first of the
  561. // month number used as the index (1 -> 12) for regular and leap years.
  562. // The value at index 13 is for the whole year.
  563. //
  564. UINTN CumulativeDays[2][14] = {
  565. {
  566. 0,
  567. 0,
  568. 31,
  569. 31 + 28,
  570. 31 + 28 + 31,
  571. 31 + 28 + 31 + 30,
  572. 31 + 28 + 31 + 30 + 31,
  573. 31 + 28 + 31 + 30 + 31 + 30,
  574. 31 + 28 + 31 + 30 + 31 + 30 + 31,
  575. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
  576. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
  577. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
  578. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
  579. 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
  580. },
  581. {
  582. 0,
  583. 0,
  584. 31,
  585. 31 + 29,
  586. 31 + 29 + 31,
  587. 31 + 29 + 31 + 30,
  588. 31 + 29 + 31 + 30 + 31,
  589. 31 + 29 + 31 + 30 + 31 + 30,
  590. 31 + 29 + 31 + 30 + 31 + 30 + 31,
  591. 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
  592. 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
  593. 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
  594. 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
  595. 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31
  596. }
  597. };
  598. #define IsLeap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
  599. #define SECSPERMIN (60)
  600. #define SECSPERHOUR (60 * 60)
  601. #define SECSPERDAY (24 * SECSPERHOUR)
  602. /**
  603. Get the system time as seconds elapsed since midnight, January 1, 1970.
  604. **/
  605. time_t
  606. time (
  607. time_t *timer
  608. )
  609. {
  610. EFI_TIME Time;
  611. time_t CalTime;
  612. UINTN Year;
  613. //
  614. // Get the current time and date information
  615. //
  616. gRT->GetTime (&Time, NULL);
  617. //
  618. // Years Handling
  619. // UTime should now be set to 00:00:00 on Jan 1 of the current year.
  620. //
  621. for (Year = 1970, CalTime = 0; Year != Time.Year; Year++) {
  622. CalTime = CalTime + (time_t)(CumulativeDays[IsLeap (Year)][13] * SECSPERDAY);
  623. }
  624. //
  625. // Add in number of seconds for current Month, Day, Hour, Minute, Seconds, and TimeZone adjustment
  626. //
  627. CalTime = CalTime +
  628. (time_t)((Time.TimeZone != EFI_UNSPECIFIED_TIMEZONE) ? (Time.TimeZone * 60) : 0) +
  629. (time_t)(CumulativeDays[IsLeap (Time.Year)][Time.Month] * SECSPERDAY) +
  630. (time_t)(((Time.Day > 0) ? Time.Day - 1 : 0) * SECSPERDAY) +
  631. (time_t)(Time.Hour * SECSPERHOUR) +
  632. (time_t)(Time.Minute * 60) +
  633. (time_t)Time.Second;
  634. if (timer != NULL) {
  635. *timer = CalTime;
  636. }
  637. return CalTime;
  638. }
  639. /**
  640. Performs a quick sort
  641. **/
  642. void
  643. qsort (
  644. void *base,
  645. size_t num,
  646. size_t width,
  647. int ( *compare )(const void *, const void *)
  648. )
  649. {
  650. ASSERT (base != NULL);
  651. ASSERT (compare != NULL);
  652. PerformQuickSort (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare);
  653. return;
  654. }
  655. /**
  656. Get character from stream, we don't support file operastion on edk2 JSON library.
  657. @return Returns the character currently pointed by the internal file position indicator of the specified stream
  658. **/
  659. int
  660. fgetc (
  661. FILE *_File
  662. )
  663. {
  664. return EOF;
  665. }
  666. /**
  667. Open stream file, we don't support file operastion on edk2 JSON library.
  668. @return 0 Unsupported
  669. **/
  670. FILE *
  671. fopen (
  672. const char *filename,
  673. const char *mode
  674. )
  675. {
  676. return NULL;
  677. }
  678. /**
  679. Read stream from file, we don't support file operastion on edk2 JSON library.
  680. @return 0 Unsupported
  681. **/
  682. size_t
  683. fread (
  684. void *ptr,
  685. size_t size,
  686. size_t count,
  687. FILE *stream
  688. )
  689. {
  690. return 0;
  691. }
  692. /**
  693. Write stream from file, we don't support file operastion on edk2 JSON library.
  694. @return 0 Unsupported
  695. **/
  696. size_t
  697. fwrite (
  698. const void *ptr,
  699. size_t size,
  700. size_t count,
  701. FILE *stream
  702. )
  703. {
  704. return 0;
  705. }
  706. /**
  707. Close file, we don't support file operastion on edk2 JSON library.
  708. @return 0 Unsupported
  709. **/
  710. int
  711. fclose (
  712. FILE *stream
  713. )
  714. {
  715. return EOF;
  716. }
  717. /**
  718. Write the formatted string to file, we don't support file operastion on edk2 JSON library.
  719. @return 0 Unsupported
  720. **/
  721. int
  722. fprintf (
  723. FILE *stream,
  724. const char *format,
  725. ...
  726. )
  727. {
  728. return -1;
  729. }
  730. /**
  731. This function check if this is the formating string specifier.
  732. @param[in] FormatString A Null-terminated ASCII format string.
  733. @param[in,out] CurrentPosition The starting position at the given string to check for
  734. "[flags][width][.precision][length]s" string specifier.
  735. @param[in] StrLength Maximum string length.
  736. @return BOOLEAN TRUE means this is the formating string specifier. CurrentPosition is
  737. returned at the position of "s".
  738. FALSE means this is not the formating string specifier.. CurrentPosition is
  739. returned at the position of failed character.
  740. **/
  741. BOOLEAN
  742. CheckFormatingString (
  743. IN CONST CHAR8 *FormatString,
  744. IN OUT UINTN *CurrentPosition,
  745. IN UINTN StrLength
  746. )
  747. {
  748. CHAR8 FormatStringParamater;
  749. while (*(FormatString + *CurrentPosition) != 's') {
  750. //
  751. // Loop until reach character 's' if the formating string is
  752. // compliant with "[flags][width][.precision][length]" format for
  753. // the string specifier.
  754. //
  755. FormatStringParamater = *(FormatString + *CurrentPosition);
  756. if ((FormatStringParamater != '-') &&
  757. (FormatStringParamater != '+') &&
  758. (FormatStringParamater != '*') &&
  759. (FormatStringParamater != '.') &&
  760. !(((UINTN)FormatStringParamater >= (UINTN)'0') && ((UINTN)FormatStringParamater <= (UINTN)'9'))
  761. )
  762. {
  763. return FALSE;
  764. }
  765. (*CurrentPosition)++;
  766. if (*CurrentPosition >= StrLength) {
  767. return FALSE;
  768. }
  769. }
  770. return TRUE;
  771. }
  772. /**
  773. This function clones *FormatString however replaces "%s" with "%a" in the
  774. returned string.
  775. @param[in] A Null-terminated ASCII format string.
  776. @return The new format string. Caller has to free the memory of this string
  777. using FreePool().
  778. **/
  779. CHAR8 *
  780. ReplaceUnicodeToAsciiStrFormat (
  781. IN CONST CHAR8 *FormatString
  782. )
  783. {
  784. UINTN FormatStrSize;
  785. UINTN FormatStrIndex;
  786. UINTN FormatStrSpecifier;
  787. BOOLEAN PercentageMark;
  788. CHAR8 *TempFormatBuffer;
  789. BOOLEAN IsFormatString;
  790. //
  791. // Error checking.
  792. //
  793. if (FormatString == NULL) {
  794. return NULL;
  795. }
  796. FormatStrSize = AsciiStrSize (FormatString);
  797. if (FormatStrSize == 0) {
  798. return NULL;
  799. }
  800. TempFormatBuffer = AllocatePool (FormatStrSize); // Allocate memory for the
  801. // new string.
  802. if (TempFormatBuffer == NULL) {
  803. return NULL;
  804. }
  805. //
  806. // Clone *FormatString but replace "%s" wih "%a".
  807. // "%%" is not considered as the format tag.
  808. //
  809. PercentageMark = FALSE;
  810. FormatStrIndex = 0;
  811. while (FormatStrIndex < FormatStrSize) {
  812. if (PercentageMark == TRUE) {
  813. //
  814. // Previous character is "%".
  815. //
  816. PercentageMark = FALSE;
  817. if (*(FormatString + FormatStrIndex) != '%') {
  818. // Check if this is double "%".
  819. FormatStrSpecifier = FormatStrIndex;
  820. //
  821. // Check if this is the formating string specifier.
  822. //
  823. IsFormatString = CheckFormatingString (FormatString, &FormatStrSpecifier, FormatStrSize);
  824. if ((FormatStrSpecifier - FormatStrIndex) != 0) {
  825. CopyMem (
  826. (VOID *)(TempFormatBuffer + FormatStrIndex),
  827. (VOID *)(FormatString + FormatStrIndex),
  828. FormatStrSpecifier - FormatStrIndex
  829. );
  830. }
  831. FormatStrIndex = FormatStrSpecifier;
  832. if (IsFormatString == TRUE) {
  833. //
  834. // Replace 's' with 'a' which is printed in ASCII
  835. // format on edk2 environment.
  836. //
  837. *(TempFormatBuffer + FormatStrSpecifier) = 'a';
  838. FormatStrIndex++;
  839. }
  840. continue;
  841. }
  842. goto ContinueCheck;
  843. }
  844. if (*(FormatString + FormatStrIndex) == '%') {
  845. //
  846. // This character is "%", set the flag.
  847. //
  848. PercentageMark = TRUE;
  849. }
  850. ContinueCheck:
  851. //
  852. // Clone character to the new string and advance FormatStrIndex
  853. // to process next character.
  854. //
  855. *(TempFormatBuffer + FormatStrIndex) = *(FormatString + FormatStrIndex);
  856. FormatStrIndex++;
  857. }
  858. return TempFormatBuffer;
  859. }
  860. /**
  861. This is the Redfish version of CRT vsnprintf function, this function replaces "%s" to
  862. "%a" before invoking AsciiVSPrint(). That is because "%s" is unicode base on edk2
  863. environment however "%s" is ascii code base on vsnprintf().
  864. See definitions of AsciiVSPrint() for the details.
  865. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
  866. ASCII string.
  867. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
  868. @param FormatString A Null-terminated ASCII format string.
  869. @param Marker VA_LIST marker for the variable argument list.
  870. @return The number of ASCII characters in the produced output buffer not including the
  871. Null-terminator.
  872. **/
  873. UINTN
  874. EFIAPI
  875. RedfishAsciiVSPrint (
  876. OUT CHAR8 *StartOfBuffer,
  877. IN UINTN BufferSize,
  878. IN CONST CHAR8 *FormatString,
  879. IN VA_LIST Marker
  880. )
  881. {
  882. CHAR8 *TempFormatBuffer;
  883. UINTN LenStrProduced;
  884. //
  885. // Looking for "%s" in the format string and replace it
  886. // with "%a" for printing ASCII code characters on edk2
  887. // environment.
  888. //
  889. TempFormatBuffer = ReplaceUnicodeToAsciiStrFormat (FormatString);
  890. if (TempFormatBuffer == NULL) {
  891. return 0;
  892. }
  893. LenStrProduced = AsciiVSPrint (StartOfBuffer, BufferSize, (CONST CHAR8 *)TempFormatBuffer, Marker);
  894. FreePool (TempFormatBuffer);
  895. return LenStrProduced;
  896. }
  897. /**
  898. This is the Redfish version of CRT snprintf function, this function replaces "%s" to
  899. "%a" before invoking AsciiSPrint(). That is because "%s" is unicode base on edk2
  900. environment however "%s" is ascii code base on snprintf().
  901. See definitions of AsciiSPrint() for the details.
  902. @param StartOfBuffer A pointer to the output buffer for the produced Null-terminated
  903. ASCII string.
  904. @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.
  905. @param FormatString A Null-terminated ASCII format string.
  906. @param ... Variable argument list whose contents are accessed based on the
  907. format string specified by FormatString.
  908. @return The number of ASCII characters in the produced output buffer not including the
  909. Null-terminator.
  910. **/
  911. UINTN
  912. EFIAPI
  913. RedfishAsciiSPrint (
  914. OUT CHAR8 *StartOfBuffer,
  915. IN UINTN BufferSize,
  916. IN CONST CHAR8 *FormatString,
  917. ...
  918. )
  919. {
  920. VA_LIST Marker;
  921. UINTN LenStrProduced;
  922. VA_START (Marker, FormatString);
  923. LenStrProduced = RedfishAsciiVSPrint (StartOfBuffer, BufferSize, FormatString, Marker);
  924. return LenStrProduced;
  925. }