Last active
February 16, 2021 00:29
-
-
Save GuilhermeRossato/eac78d8c7d6eee0eadb61e871ee080b3 to your computer and use it in GitHub Desktop.
Pure C way to convert wchar array to char array (C99)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> // snprintf | |
#include <windows.h> // wchar | |
// Convert a WIDE CHAR ARRAY (wchar *) into a CHAR ARRAY (char *) in a memory safe way. | |
// Handles unicode characters by writing \uXXXX exactly like C compilers and JSON parsers. | |
int convert_wchar_array_to_char_array(const WCHAR * input, char * output, size_t output_buffer_size) { | |
if (input == NULL || output == NULL || sizeof(WCHAR) != 2) { | |
return 0; | |
} | |
if (output_buffer_size <= 0) { | |
return 1; | |
} | |
unsigned char * input_raw = (unsigned char *) input; | |
size_t input_index; | |
size_t output_index = 0; | |
for (input_index = 0; input_index >= 0 && input_index < output_buffer_size; input_index++) { | |
if (input_raw[input_index * 2] == '\0' && (input_raw[input_index * 2 + 1] == '\0' || input_raw[input_index * 2 + 1] == 0)) { | |
if (output_index < output_buffer_size) { | |
output[output_index++] = '\0'; | |
} else { | |
output[output_buffer_size - 1] = '\0'; | |
} | |
return 1; | |
} | |
if (input_raw[input_index * 2] < 128 && (input_raw[input_index * 2 + 1] == '\0' || input_raw[input_index * 2 + 1] == 0)) { | |
// Simple ASCII character | |
if (output_index < output_buffer_size) { | |
output[output_index++] = (char) input_raw[input_index * 2]; | |
continue; | |
} else { | |
output[output_buffer_size - 1] = '\0'; | |
return 1; | |
} | |
} | |
// Unicode character | |
if (output_index + 7 >= output_buffer_size) { | |
// Not enough space in buffer | |
output[output_buffer_size - 1] = '\0'; | |
return 1; | |
} | |
// output[output_index++] = '?'; | |
output_index += snprintf( | |
&output[output_index], | |
output_buffer_size - 1 - output_index, | |
"\\u%02x%02x", | |
(unsigned char) input_raw[input_index * 2], | |
(unsigned char) input_raw[input_index * 2 + 1] | |
); | |
} | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment