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