1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26#ifndef WIN32
27#include <ctype.h>
28
29  #ifndef METAWARE
30    #include <wctype.h>
31  #endif
32
33#endif
34
35#ifndef METAWARE
36  #include <sys/timeb.h>
37#endif
38
39#include "KMSAgentStringUtilities.h"
40
41#ifdef WIN32
42#include <stdlib.h>
43#include <time.h>
44#define gmtime_r(clock,result) ( *(result) = *gmtime(clock), result )
45#endif
46
47// Find header in KMSAgentStringUtilities.h
48int64 UTF8ToInt64( const char* i_sNumber )
49{
50    FATAL_ASSERT( i_sNumber );
51
52#ifdef WIN32
53    return _atoi64( i_sNumber );
54#else
55    return atoll( i_sNumber );
56#endif
57}
58
59void Int64ToUTF8(char* const o_psUTF8,
60                 int64 i_iNumber,
61                 int i_bPad,
62                 int i_bHex )
63{
64    //string sFormat;
65    char sFormat[10];
66
67    if ( i_bPad && i_bHex )
68    {
69#ifdef WIN32
70        strcpy(sFormat,"%016I64X");
71#else
72        strcpy(sFormat,"%016llX");
73#endif
74    }
75    else if ( i_bPad && !i_bHex )
76    {
77#ifdef WIN32
78        strcpy(sFormat, "%019I64d");
79#else
80        strcpy(sFormat, "%019lld");
81#endif
82    }
83    else if ( !i_bPad && i_bHex )
84    {
85#ifdef WIN32
86        strcpy(sFormat, "%I64X");
87#else
88        strcpy(sFormat, "%llX");
89#endif
90    }
91    else //( !i_bPad && !i_bHex )
92    {
93#ifdef WIN32
94        strcpy(sFormat, "%I64d");
95#else
96        strcpy(sFormat, "%lld");
97#endif
98    }
99
100#ifndef METAWARE
101    int iReturn = sprintf( o_psUTF8, sFormat, i_iNumber);
102
103    //int iReturn = K_snprintf(o_psUTF8, iBufferSize, sFormat, i_iNumber);
104#else
105    int iReturn = sprintf( o_psUTF8, sFormat, i_iNumber);
106#endif
107    if ( iReturn < 0 )
108    {
109        // Our buffer wasn't big enough. Shouldn't happen.
110        FATAL_ASSERT(0);
111    }
112
113    return;
114
115}
116
117// Find header in KMSAgentStringUtilities.h
118int ConvertUTF8HexStringToBinary(
119            const char* i_sHexString,
120            unsigned char* o_pBinaryBuffer)
121{
122    int iHexLen = i_sHexString ? strlen(i_sHexString) : 0;
123    FATAL_ASSERT( (iHexLen % 2) == 0 ); // to be valid, the hex string must have an even number of characters
124
125    if ( !o_pBinaryBuffer )
126    {
127       return ( iHexLen / 2 );
128    }
129
130    if ( iHexLen <= 0 )
131    {
132        return 0;
133    }
134
135    int iDigitValue = 0;
136
137    for ( int i = 0; i < iHexLen; i++)
138    {
139        if (i_sHexString[i] >= '0' && i_sHexString[i] <= '9')
140        {
141            iDigitValue = i_sHexString[i] - '0';
142        }
143        else if (i_sHexString[i] >= 'A' && i_sHexString[i] <= 'F')
144        {
145            iDigitValue = i_sHexString[i] - 'A' + 10;
146        }
147        else if (i_sHexString[i] >= 'a' && i_sHexString[i] <= 'f')
148        {
149            iDigitValue = i_sHexString[i] - 'a' + 10;
150        }
151        else
152        {
153            iDigitValue = 0;
154        }
155
156        if (i % 2 == 0)
157        {
158            o_pBinaryBuffer[i/2] = (char)(iDigitValue << 4);
159        }
160        else
161        {
162            o_pBinaryBuffer[i/2] |= (char)iDigitValue;
163        }
164    }
165
166    return ( iHexLen / 2 );
167}
168
169// Find header in KMSAgentStringUtilities.h
170void ConvertBinaryToUTF8HexString(
171                             char* const                o_sHexString,
172                             const unsigned char* const i_pBinaryBuffer,
173                             int                        i_iBinaryBufferSize )
174{
175    const char HEXCHARS[] = "0123456789ABCDEF";
176
177    FATAL_ASSERT( o_sHexString );
178
179    if ( (i_pBinaryBuffer == 0) || (i_iBinaryBufferSize == 0) )
180    {
181        strcpy(o_sHexString, "");
182        return;
183    }
184
185    FATAL_ASSERT( i_pBinaryBuffer );
186
187    for ( int i = 0; i < (2 * i_iBinaryBufferSize); i++ )
188    {
189        unsigned char ucFourBits = i_pBinaryBuffer[i / 2];
190        if ( (i % 2) == 0 ) // high four bits of the current byte
191            ucFourBits = (ucFourBits >> 4) & 0xF; // shift down and blank out upper bits
192        else                // low four bits of the current byte
193            ucFourBits = ucFourBits & 0xF; // blank out upper bits
194
195        o_sHexString[i] = HEXCHARS[ucFourBits];
196    }
197
198    o_sHexString[i_iBinaryBufferSize * 2] = '\0';
199
200    return;
201}
202
203
204// Find header in StringUtilities.h
205void GetCurrentDateTimeISO8601UTC(char* const o_psDateTimeISO8601UTC,
206                                  int i_iLength)
207{
208
209#ifndef METAWARE
210    timeb stTime;
211    ftime(&stTime);
212
213    FATAL_ASSERT( o_psDateTimeISO8601UTC );
214
215    struct tm* pstTime = gmtime( &(stTime.time) );
216
217    K_snprintf(
218        o_psDateTimeISO8601UTC,
219        i_iLength,
220        "%04d-%02d-%02d %02d:%02d:%02d.%03dZ",
221        pstTime->tm_year+1900,
222        pstTime->tm_mon+1,
223        pstTime->tm_mday,
224        pstTime->tm_hour,
225        pstTime->tm_min,
226        pstTime->tm_sec,
227        stTime.millitm);
228
229#else
230    // no time functions for the metaware environment
231    strcpy( o_psDateTimeISO8601UTC, "" );
232#endif
233    return;
234}
235
236