c++ - 自定义流操纵器

标签 c++ stream ostream manipulators

我有一个继承自 std::ostream 的自定义流 CFileManagerOStream,它从网络流类 CTcpStream 中获取 Unicode UTF16 或 UTF32 字符串> 并将它们作为 UTF8 字符串存储在磁盘上。这些字符串可能太大(可能是多个 TB),无法在内存中转换为 UTF8,因此我认为我需要为这项工作实现一个 C++ 流操纵器。我发现的所有操纵器示例都采用整个字符串并对其进行处理,由于内存要求低,这在我的情况下不会执行。我已准备好所有 Unicode 转换代码,我要解决的问题是使用尽可能少的内存进行转换。

我希望能像这样使用操纵器;

CFileManagerOStream outFile("MultipleUtf8Strings.dat"); // Custom std::ostream
...
#ifdef _WINDOWS
CTcpStreamUtf16 largeBlobUtf16Stream;
...
outFile << ToUTF8FromUtf16 << largeBlobUtf16Stream;
#else
CTcpStreamUtf32 largeBlobUtf32Stream;
...
outFile << ToUTF8FromUtf32 << largeBlobUtf32Stream;
#endif

这可能吗,还是我的做法有误?

最佳答案

我发现使用 std::ios_base::iword 来存储请求的字符编码是手头问题的最佳解决方案:

#include <iostream>

/*!
\brief Unicode encoding
*/
enum EUnicodeEnc
{
    /** UTF-8 character encoding */
    EUnicodeEnc_UTF8 = 1,

    /** UTF-16 character encoding */
    EUnicodeEnc_UTF16 = 2,

    /** UTF-32 character encoding */
    EUnicodeEnc_UTF32 = 3
};

/** Allocate the \c std::ios_base::iword storage for use with \c SourceStreamEncoding object instances */
int SourceStreamEncoding::sourceEnc_xalloc = std::ios_base::xalloc();

/*!
\brief Stream I/O manipulator changes the source character encoding to UTF-8
*/
std::ios_base& FromUtf8(std::ios_base& os) {
    os.iword(SourceStreamEncoding::sourceEnc_xalloc) = EUnicodeEnc_UTF8;
    return os;
}

/*!
\brief Stream I/O manipulator changes the source character encoding to UTF-16
*/
std::ios_base& FromUtf16(std::ios_base& os) {
    os.iword(SourceStreamEncoding::sourceEnc_xalloc) = EUnicodeEnc_UTF16;
    return os;
}

/*!
\brief Stream I/O manipulator changes the source character encoding to UTF-32
*/
std::ios_base& FromUtf32(std::ios_base& os) {
    os.iword(SourceStreamEncoding::sourceEnc_xalloc) = EUnicodeEnc_UTF32;
    return os;
}

/*!
\brief Overrides \c std::ostream::flush()
\details Converts the buffer to the correct character encoding then flushes buffer
after writing its content to a storage device
*/
std::ostream &CFileManagerOStream::flush()
{
    switch (os.iword(SourceStreamEncoding::sourceEnc_xalloc))
    {
        case EUnicodeEnc_UTF8:
            characterEncoder.FromUTF8(...);
        break;
        case EUnicodeEnc_UTF16:
            characterEncoder.FromUTF16(...);
        break;
        case EUnicodeEnc_UTF32:
            characterEncoder.FromUTF32(...);
        break;
    }
    return (*this);
}

// Now I can do as follows:
int main()
{
    CFileManagerOStream outFile("MultipleUtf8Strings.dat"); // Custom std::ostream
    ...
#ifdef _WINDOWS
    CTcpStreamUtf16 largeBlobUtf16Stream;
    ...
    outFile << FromUtf16 << largeBlobUtf16Stream;
#else
    CTcpStreamUtf32 largeBlobUtf32Stream;
    ...
    outFile << FromUtf32 << largeBlobUtf32Stream;
#endif
}

此外,我添加了以下采用单个参数的操纵器:

class FromEnc
{
    public:
        explicit FromEnc(int i) : i_(i) {}
        int i_;
    private:
        template <class charT, class Traits>
        friend std::basic_ostream<charT, Traits>& operator<<(std::basic_ostream<charT, Traits>& os, const FromEnc& w) {
            os.iword(SourceStreamEncoding::sourceEnc_xalloc) = w.i_;
            return os;
        }
};

,所以现在我也可以这样做:

outFile << FromEnc(EUnicodeEnc_UTF16) << largeBlobUtf16Stream;

关于c++ - 自定义流操纵器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24588341/

相关文章:

c++ - 嵌套模板类方法语法

c++ - 使用递归的机器学习算法

php stream_get_contents 在流的末尾挂起

c++ - 支持 std::ostream operator << 中的 const_string

c++ - 用迭代器重载 vector 模板的ostream

c++ - 局部变量和尾调用优化

c++ - 编译boost程序的问题

java - 从Web服务响应中读取InputStream

Java StringBuffer 工作正常,reverse() 添加换行符

c++ - 使用嵌套函数时,Ostream 输出提供额外地址