[winpr,stream] Added functions to read/write utf-8

* Stream_Write_UTF16_String_From_UTF8 writes a UTF-8 string to a
      stream in UTF-16 encoding
    * Stream_Read_UTF16_String_To_UTF8 reads a UTF-16 encoded string
      from the stream and returns it in UTF-8 encoding
This commit is contained in:
Armin Novak 2022-10-27 15:37:25 +02:00 committed by akallabeth
parent 2ac2f43503
commit 2aefa9418d
2 changed files with 102 additions and 2 deletions

View File

@ -467,8 +467,48 @@ extern "C"
return TRUE;
}
WINPR_API BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t length);
WINPR_API BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t length);
WINPR_API BOOL Stream_Read_UTF16_String(wStream* s, WCHAR* dst, size_t charLength);
WINPR_API BOOL Stream_Write_UTF16_String(wStream* s, const WCHAR* src, size_t charLength);
/** \brief Reads a WCHAR string from a stream and converts it to UTF-8 and returns a newly
* allocated string
*
* \param s The stream to read data from
* \param wcharLength The number of WCHAR characters to read (NOT the size in bytes!)
* \param pUtfCharLength Ignored if \b NULL, otherwise will be set to the number of
* characters in the resulting UTF-8 string
* \return A '\0' terminated UTF-8 encoded string or NULL for any failure.
*/
WINPR_API char* Stream_Read_UTF16_String_As_UTF8(wStream* s, size_t wcharLength,
size_t* pUtfCharLength);
/** \brief Reads a WCHAR string from a stream and converts it to UTF-8 and
* writes it to the supplied buffer
*
* \param s The stream to read data from
* \param wcharLength The number of WCHAR characters to read (NOT the size in bytes!)
* \param utfBuffer A pointer to a buffer holding the result string
* \param utfBufferCharLength The size of the result buffer
* \return The char length (strlen) of the result string or -1 for failure
*/
WINPR_API SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength,
char* utfBuffer,
size_t utfBufferCharLength);
/** \brief Writes a UTF-8 string UTF16 encoded to the stream. If the UTF-8
* string is short, the remainig characters are filled up with '\0'
*
* \param s The stream to write to
* \param wcharLength the length (in WCHAR characters) to write
* \param src The source data buffer with the UTF-8 data
* \param length The length in bytes of the UTF-8 buffer
* \param fill If \b TRUE fill the unused parts of the wcharLength with 0
*
* \b return number of used characters for success, /b -1 for failure
*/
WINPR_API SSIZE_T Stream_Write_UTF16_String_From_UTF8(wStream* s, size_t wcharLength,
const char* src, size_t length,
BOOL fill);
/* StreamPool */

View File

@ -379,3 +379,63 @@ BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s
}
return TRUE;
}
SSIZE_T Stream_Write_UTF16_String_From_UTF8(wStream* s, size_t dlen, const char* src, size_t length,
BOOL fill)
{
const size_t wlen = Stream_GetRemainingCapacity(s) / sizeof(WCHAR);
union
{
WCHAR* wc;
BYTE* b;
} cnv;
cnv.b = Stream_Pointer(s);
if (length == 0)
return 0;
if (wlen < dlen)
return -1;
SSIZE_T rc = ConvertUtf8NToWChar(src, length, cnv.wc, dlen);
if (rc < 0)
return -1;
Stream_Seek(s, (size_t)rc * sizeof(WCHAR));
if (fill)
Stream_Zero(s, (dlen - (size_t)rc) * sizeof(WCHAR));
return rc;
}
char* Stream_Read_UTF16_String_As_UTF8(wStream* s, size_t dlen, size_t* psize)
{
union
{
const WCHAR* wc;
const BYTE* b;
} cnv;
cnv.b = Stream_Pointer(s);
if (dlen > SIZE_MAX / sizeof(WCHAR))
return NULL;
if (!Stream_CheckAndLogRequiredLength(STREAM_TAG, s, dlen * sizeof(WCHAR)))
return NULL;
Stream_Seek(s, dlen * sizeof(WCHAR));
return ConvertWCharNToUtf8Alloc(cnv.wc, dlen, psize);
}
SSIZE_T Stream_Read_UTF16_String_As_UTF8_Buffer(wStream* s, size_t wcharLength, char* utfBuffer,
size_t utfBufferCharLength)
{
const WCHAR* ptr = (const WCHAR*)Stream_Pointer(s);
if (wcharLength > SIZE_MAX / sizeof(WCHAR))
return -1;
if (!Stream_CheckAndLogRequiredLength(STREAM_TAG, s, wcharLength * sizeof(WCHAR)))
return -1;
Stream_Seek(s, wcharLength * sizeof(WCHAR));
return ConvertWCharNToUtf8(ptr, wcharLength, utfBuffer, utfBufferCharLength);
}