FreeRDP
Loading...
Searching...
No Matches
print.c
1
20#include <winpr/config.h>
21#include <winpr/debug.h>
22
23#include <stdio.h>
24#include <string.h>
25#include <stdarg.h>
26#include <errno.h>
27
28#include <winpr/crt.h>
29#include <winpr/print.h>
30
31#include "../log.h"
32
33#ifndef MIN
34#define MIN(a, b) (a) < (b) ? (a) : (b)
35#endif
36
37void winpr_HexDump(const char* tag, UINT32 level, const void* data, size_t length)
38{
39 wLog* log = WLog_Get(tag);
40 winpr_HexLogDump(log, level, data, length);
41}
42
43void winpr_HexLogDump(wLog* log, UINT32 level, const void* data, size_t length)
44{
45 const BYTE* p = data;
46 size_t line = 0;
47 size_t offset = 0;
48 const size_t maxlen = 20; /* 64bit SIZE_MAX as decimal */
49 /* String line length:
50 * prefix '[1234] '
51 * hexdump '01 02 03 04'
52 * separator ' '
53 * ASIC line 'ab..cd'
54 * zero terminator '\0'
55 */
56 const size_t blen = (maxlen + 3ULL) + (WINPR_HEXDUMP_LINE_LENGTH * 3ULL) + 3ULL +
57 WINPR_HEXDUMP_LINE_LENGTH + 1ULL;
58 size_t pos = 0;
59
60 char* buffer = NULL;
61
62 if (!WLog_IsLevelActive(log, level))
63 return;
64
65 if (!log)
66 return;
67
68 buffer = malloc(blen);
69
70 if (!buffer)
71 {
72 char ebuffer[256] = { 0 };
73 WLog_Print(log, WLOG_ERROR, "malloc(%" PRIuz ") failed with [%" PRIuz "] %s", blen, errno,
74 winpr_strerror(errno, ebuffer, sizeof(ebuffer)));
75 return;
76 }
77
78 while (offset < length)
79 {
80 int rc = _snprintf(&buffer[pos], blen - pos, "%04" PRIuz " ", offset);
81
82 if (rc < 0)
83 goto fail;
84
85 pos += (size_t)rc;
86 line = length - offset;
87
88 if (line > WINPR_HEXDUMP_LINE_LENGTH)
89 line = WINPR_HEXDUMP_LINE_LENGTH;
90
91 size_t i = 0;
92 for (; i < line; i++)
93 {
94 rc = _snprintf(&buffer[pos], blen - pos, "%02" PRIx8 " ", p[i]);
95
96 if (rc < 0)
97 goto fail;
98
99 pos += (size_t)rc;
100 }
101
102 for (; i < WINPR_HEXDUMP_LINE_LENGTH; i++)
103 {
104 rc = _snprintf(&buffer[pos], blen - pos, " ");
105
106 if (rc < 0)
107 goto fail;
108
109 pos += (size_t)rc;
110 }
111
112 for (size_t j = 0; j < line; j++)
113 {
114 rc = _snprintf(&buffer[pos], blen - pos, "%c",
115 (p[j] >= 0x20 && p[j] < 0x7F) ? (char)p[j] : '.');
116
117 if (rc < 0)
118 goto fail;
119
120 pos += (size_t)rc;
121 }
122
123 WLog_Print(log, level, "%s", buffer);
124 offset += line;
125 p += line;
126 pos = 0;
127 }
128
129 WLog_Print(log, level, "[length=%" PRIuz "] ", length);
130fail:
131 free(buffer);
132}
133
134void winpr_CArrayDump(const char* tag, UINT32 level, const void* data, size_t length, size_t width)
135{
136 const BYTE* p = data;
137 size_t offset = 0;
138 const size_t llen = ((length > width) ? width : length) * 4ull + 1ull;
139 size_t pos = 0;
140 char* buffer = malloc(llen);
141
142 if (!buffer)
143 {
144 char ebuffer[256] = { 0 };
145 WLog_ERR(tag, "malloc(%" PRIuz ") failed with [%d] %s", llen, errno,
146 winpr_strerror(errno, ebuffer, sizeof(ebuffer)));
147 return;
148 }
149
150 while (offset < length)
151 {
152 size_t line = length - offset;
153
154 if (line > width)
155 line = width;
156
157 pos = 0;
158
159 for (size_t i = 0; i < line; i++)
160 {
161 const int rc = _snprintf(&buffer[pos], llen - pos, "\\x%02" PRIX8 "", p[i]);
162 if (rc < 0)
163 goto fail;
164 pos += (size_t)rc;
165 }
166
167 WLog_LVL(tag, level, "%s", buffer);
168 offset += line;
169 p += line;
170 }
171
172fail:
173 free(buffer);
174}
175
176static BYTE value(char c)
177{
178 if ((c >= '0') && (c <= '9'))
179 return (c - '0') & 0xFF;
180 if ((c >= 'A') && (c <= 'F'))
181 return (10 + c - 'A') & 0xFF;
182 if ((c >= 'a') && (c <= 'f'))
183 return (10 + c - 'a') & 0xFF;
184 return 0;
185}
186
187size_t winpr_HexStringToBinBuffer(const char* str, size_t strLength, BYTE* data, size_t dataLength)
188{
189 size_t y = 0;
190 size_t maxStrLen = 0;
191 if (!str || !data || (strLength == 0) || (dataLength == 0))
192 return 0;
193
194 maxStrLen = strnlen(str, strLength);
195 for (size_t x = 0; x < maxStrLen;)
196 {
197 BYTE val = value(str[x++]);
198 if (x < maxStrLen)
199 val = (BYTE)(val << 4) | (value(str[x++]));
200 if (x < maxStrLen)
201 {
202 if (str[x] == ' ')
203 x++;
204 }
205 data[y++] = val;
206 if (y >= dataLength)
207 return y;
208 }
209 return y;
210}
211
212size_t winpr_BinToHexStringBuffer(const BYTE* data, size_t length, char* dstStr, size_t dstSize,
213 BOOL space)
214{
215 const size_t n = space ? 3 : 2;
216 const char bin2hex[] = "0123456789ABCDEF";
217 const size_t maxLength = MIN(length, dstSize / n);
218
219 if (!data || !dstStr || (length == 0) || (dstSize == 0))
220 return 0;
221
222 for (size_t i = 0; i < maxLength; i++)
223 {
224 const int ln = data[i] & 0xF;
225 const int hn = (data[i] >> 4) & 0xF;
226 char* dst = &dstStr[i * n];
227
228 dst[0] = bin2hex[hn];
229 dst[1] = bin2hex[ln];
230
231 if (space)
232 dst[2] = ' ';
233 }
234
235 if (space && (maxLength > 0))
236 {
237 dstStr[maxLength * n - 1] = '\0';
238 return maxLength * n - 1;
239 }
240 dstStr[maxLength * n] = '\0';
241 return maxLength * n;
242}
243
244char* winpr_BinToHexString(const BYTE* data, size_t length, BOOL space)
245{
246 size_t rc = 0;
247 const size_t n = space ? 3 : 2;
248 const size_t size = (length + 1ULL) * n;
249 char* p = (char*)malloc(size);
250
251 if (!p)
252 return NULL;
253
254 rc = winpr_BinToHexStringBuffer(data, length, p, size, space);
255 if (rc == 0)
256 {
257 free(p);
258 return NULL;
259 }
260
261 return p;
262}