fs/io/BufferedOutputStream: add wchar_t overloads

This commit is contained in:
Max Kellermann 2016-09-04 12:05:37 +02:00
parent c39c259078
commit b630afdeda
2 changed files with 69 additions and 0 deletions

View File

@ -25,6 +25,11 @@
#include <string.h>
#include <stdio.h>
#ifdef _UNICODE
#include "system/Error.hxx"
#include <windows.h>
#endif
bool
BufferedOutputStream::AppendToBuffer(const void *data, size_t size) noexcept
{
@ -103,6 +108,52 @@ BufferedOutputStream::Format(const char *fmt, ...)
buffer.Append(size);
}
#ifdef _UNICODE
void
BufferedOutputStream::Write(const wchar_t *p)
{
WriteWideToUTF8(p, wcslen(p));
}
void
BufferedOutputStream::WriteWideToUTF8(const wchar_t *src, size_t src_length)
{
if (src_length == 0)
return;
auto r = buffer.Write();
if (r.IsEmpty()) {
Flush();
r = buffer.Write();
}
int length = WideCharToMultiByte(CP_UTF8, 0, src, src_length,
r.data, r.size, nullptr, nullptr);
if (length <= 0) {
const auto error = GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER)
throw MakeLastError(error, "UTF-8 conversion failed");
/* how much buffer do we need? */
length = WideCharToMultiByte(CP_UTF8, 0, src, src_length,
nullptr, 0, nullptr, nullptr);
if (length <= 0)
throw MakeLastError(error, "UTF-8 conversion failed");
/* grow the buffer and try again */
length = WideCharToMultiByte(CP_UTF8, 0, src, src_length,
buffer.Write(length), length,
nullptr, nullptr);
if (length <= 0)
throw MakeLastError(error, "UTF-8 conversion failed");
}
buffer.Append(length);
}
#endif
void
BufferedOutputStream::Flush()
{

View File

@ -26,11 +26,17 @@
#include <stddef.h>
#ifdef _UNICODE
#include <wchar.h>
#endif
class OutputStream;
/**
* An #OutputStream wrapper that buffers its output to reduce the
* number of OutputStream::Write() calls.
*
* All wchar_t based strings are converted to UTF-8.
*/
class BufferedOutputStream {
OutputStream &os;
@ -52,6 +58,14 @@ public:
gcc_printf(2,3)
void Format(const char *fmt, ...);
#ifdef _UNICODE
void Write(const wchar_t &ch) {
WriteWideToUTF8(&ch, 1);
}
void Write(const wchar_t *p);
#endif
/**
* Write buffer contents to the #OutputStream.
*/
@ -59,6 +73,10 @@ public:
private:
bool AppendToBuffer(const void *data, size_t size) noexcept;
#ifdef _UNICODE
void WriteWideToUTF8(const wchar_t *p, size_t length);
#endif
};
#endif