1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** USBX Component */
16 /** */
17 /** Pictbridge Application */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28 #include "ux_pictbridge.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _ux_pictbridge_hexa_to_decimal_string PORTABLE C */
36 /* 6.1.11 */
37 /* AUTHOR */
38 /* */
39 /* Chaoqiong Xiao, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This function translates an hexa value into a decimal string. */
44 /* */
45 /* Note: */
46 /* Number of max_digit_string_size must be large enough to fit digits */
47 /* converted. */
48 /* The space of the decimal_string buffer must be equal to or larger */
49 /* than max_digit_string_size to accept converted characters. */
50 /* When leading zeros are off, the converted string ends before */
51 /* reaching buffer end and zeros are padded. */
52 /* */
53 /* INPUT */
54 /* */
55 /* hexa_value Value to be translated */
56 /* decimal_string Where to store the element */
57 /* leading_zero_flag If leading zeroes are OK */
58 /* max_digit_string_size Max number of digits (<=8) */
59 /* */
60 /* OUTPUT */
61 /* */
62 /* Completion Status */
63 /* */
64 /* CALLS */
65 /* */
66 /* */
67 /* CALLED BY */
68 /* */
69 /* _ux_pictbridge_object_parse */
70 /* */
71 /* RELEASE HISTORY */
72 /* */
73 /* DATE NAME DESCRIPTION */
74 /* */
75 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
76 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
77 /* verified memset and memcpy */
78 /* cases, */
79 /* resulting in version 6.1 */
80 /* 04-25-2022 Yajun Xia Modified comment(s), */
81 /* fixed maximum decimal */
82 /* calculation issue, */
83 /* resulting in version 6.1.11 */
84 /* */
85 /**************************************************************************/
_ux_pictbridge_hexa_to_decimal_string(ULONG hexa_value,UCHAR * decimal_string,ULONG leading_zero_flag,ULONG max_digit_string_size)86 UINT _ux_pictbridge_hexa_to_decimal_string(ULONG hexa_value, UCHAR *decimal_string,
87 ULONG leading_zero_flag, ULONG max_digit_string_size)
88 {
89
90 ULONG decimal_string_shift;
91 ULONG decimal_value;
92 ULONG leading_flag;
93 ULONG decimal_max[8] = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999};
94
95 /* Set the value of the shift decimal.*/
96 switch(max_digit_string_size)
97 {
98 case 1 :
99 decimal_string_shift = 1;
100 break;
101 case 2 :
102 decimal_string_shift = 10;
103 break;
104 case 3 :
105 decimal_string_shift = 100;
106 break;
107 case 4 :
108 decimal_string_shift = 1000;
109 break;
110 case 5 :
111 decimal_string_shift = 10000;
112 break;
113 case 6 :
114 decimal_string_shift = 100000;
115 break;
116 case 7 :
117 decimal_string_shift = 1000000;
118 break;
119 case 8 :
120 decimal_string_shift = 10000000;
121 break;
122 default :
123 return(UX_ERROR);
124 }
125
126 /* If value exceeds, do not proceed. */
127 if (hexa_value > decimal_max[max_digit_string_size - 1])
128 return(UX_ERROR);
129
130 /* Set the leading zero flag. */
131 if (leading_zero_flag == UX_PICTBRIDGE_LEADING_ZERO_ON)
132 leading_flag = UX_FALSE;
133 else
134 leading_flag = UX_TRUE;
135
136 /* Reset the decimal_string buffer. */
137 _ux_utility_memory_set(decimal_string, 0, max_digit_string_size); /* Use case of memset is verified. */
138
139 /* We parse the hexa value and build the decimal string one byte at a type. */
140 while(decimal_string_shift)
141 {
142 /* Divide the hexa value by the shift and decode the leading digital. */
143 decimal_value = hexa_value / decimal_string_shift;
144
145 /* If the result is non zero, we can insert that decimal in the string.
146 There is a special case if the value is the last decimal or if the leading flag is off. */
147 if (decimal_value != 0 || decimal_string_shift == 1 || leading_flag == UX_FALSE)
148 {
149 /* Insert the value. */
150 *decimal_string++ = (UCHAR)(decimal_value + '0');
151
152 /* Reset the leading flag. */
153 leading_flag = UX_FALSE;
154 }
155
156 /* Reduce the shift value to the next decimal. */
157 decimal_string_shift = decimal_string_shift / 10;
158
159 }
160
161 /* Operation was successful. */
162 return(UX_SUCCESS);
163 }
164
165