|
Packit Service |
20376f |
/*
|
|
Packit Service |
20376f |
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
Packit Service |
20376f |
* a Linking Exception. For full terms see the included COPYING file.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#include "common.h"
|
|
Packit Service |
20376f |
#include "utf-conv.h"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
GIT_INLINE(void) git__set_errno(void)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
Packit Service |
20376f |
errno = ENAMETOOLONG;
|
|
Packit Service |
20376f |
else
|
|
Packit Service |
20376f |
errno = EINVAL;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Converts a UTF-8 string to wide characters.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* @param dest The buffer to receive the wide string.
|
|
Packit Service |
20376f |
* @param dest_size The size of the buffer, in characters.
|
|
Packit Service |
20376f |
* @param src The UTF-8 string to convert.
|
|
Packit Service |
20376f |
* @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
int git__utf8_to_16(wchar_t *dest, size_t dest_size, const char *src)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
int len;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
|
|
Packit Service |
20376f |
* turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
|
|
Packit Service |
20376f |
* length. MultiByteToWideChar never returns int's minvalue, so underflow is not possible */
|
|
Packit Service |
20376f |
if ((len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, dest, (int)dest_size) - 1) < 0)
|
|
Packit Service |
20376f |
git__set_errno();
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return len;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Converts a wide string to UTF-8.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* @param dest The buffer to receive the UTF-8 string.
|
|
Packit Service |
20376f |
* @param dest_size The size of the buffer, in bytes.
|
|
Packit Service |
20376f |
* @param src The wide string to convert.
|
|
Packit Service |
20376f |
* @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
int git__utf16_to_8(char *dest, size_t dest_size, const wchar_t *src)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
int len;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* Length of -1 indicates NULL termination of the input string. Subtract 1 from the result to
|
|
Packit Service |
20376f |
* turn 0 into -1 (an error code) and to not count the NULL terminator as part of the string's
|
|
Packit Service |
20376f |
* length. WideCharToMultiByte never returns int's minvalue, so underflow is not possible */
|
|
Packit Service |
20376f |
if ((len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, dest, (int)dest_size, NULL, NULL) - 1) < 0)
|
|
Packit Service |
20376f |
git__set_errno();
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
return len;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Converts a UTF-8 string to wide characters.
|
|
Packit Service |
20376f |
* Memory is allocated to hold the converted string.
|
|
Packit Service |
20376f |
* The caller is responsible for freeing the string with git__free.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* @param dest Receives a pointer to the wide string.
|
|
Packit Service |
20376f |
* @param src The UTF-8 string to convert.
|
|
Packit Service |
20376f |
* @return The length of the wide string, in characters (not counting the NULL terminator), or < 0 for failure
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
int git__utf8_to_16_alloc(wchar_t **dest, const char *src)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
int utf16_size;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
*dest = NULL;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* Length of -1 indicates NULL termination of the input string */
|
|
Packit Service |
20376f |
utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, NULL, 0);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!utf16_size) {
|
|
Packit Service |
20376f |
git__set_errno();
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!(*dest = git__mallocarray(utf16_size, sizeof(wchar_t)))) {
|
|
Packit Service |
20376f |
errno = ENOMEM;
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
utf16_size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, src, -1, *dest, utf16_size);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!utf16_size) {
|
|
Packit Service |
20376f |
git__set_errno();
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git__free(*dest);
|
|
Packit Service |
20376f |
*dest = NULL;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
|
|
Packit Service |
20376f |
* terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
|
|
Packit Service |
20376f |
* so underflow is not possible */
|
|
Packit Service |
20376f |
return utf16_size - 1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Converts a wide string to UTF-8.
|
|
Packit Service |
20376f |
* Memory is allocated to hold the converted string.
|
|
Packit Service |
20376f |
* The caller is responsible for freeing the string with git__free.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* @param dest Receives a pointer to the UTF-8 string.
|
|
Packit Service |
20376f |
* @param src The wide string to convert.
|
|
Packit Service |
20376f |
* @return The length of the UTF-8 string, in bytes (not counting the NULL terminator), or < 0 for failure
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
int git__utf16_to_8_alloc(char **dest, const wchar_t *src)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
int utf8_size;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
*dest = NULL;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* Length of -1 indicates NULL termination of the input string */
|
|
Packit Service |
20376f |
utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, NULL, 0, NULL, NULL);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!utf8_size) {
|
|
Packit Service |
20376f |
git__set_errno();
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
*dest = git__malloc(utf8_size);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!*dest) {
|
|
Packit Service |
20376f |
errno = ENOMEM;
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
utf8_size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, src, -1, *dest, utf8_size, NULL, NULL);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!utf8_size) {
|
|
Packit Service |
20376f |
git__set_errno();
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git__free(*dest);
|
|
Packit Service |
20376f |
*dest = NULL;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* Subtract 1 from the result to turn 0 into -1 (an error code) and to not count the NULL
|
|
Packit Service |
20376f |
* terminator as part of the string's length. MultiByteToWideChar never returns int's minvalue,
|
|
Packit Service |
20376f |
* so underflow is not possible */
|
|
Packit Service |
20376f |
return utf8_size - 1;
|
|
Packit Service |
20376f |
}
|