0

を呼び出す方法と同様の方法で JNI 文字列を取得できる出力ストリームが必要なため、カスタムstd::basic_streambufandを作成しました。これらのクラスは非常に単純です。std::basic_ostreamstd::ostringstream::str()

namespace myns {

class jni_utf16_streambuf : public std::basic_streambuf<char16_t>
{
    JNIEnv * d_env;
    std::vector<char16_t> d_buf;
    virtual int_type overflow(int_type);

public:
    jni_utf16_streambuf(JNIEnv *);
    jstring jstr() const;
};

typedef std::basic_ostream<char16_t, std::char_traits<char16_t>> utf16_ostream;

class jni_utf16_ostream : public utf16_ostream
{
    jni_utf16_streambuf d_buf;

public:
    jni_utf16_ostream(JNIEnv *);
    jstring jstr() const;
};

// ...

} // namespace myns

さらにoperator<<、すべて同じ名前空間で の4 つのオーバーロードを作成しました。

namespace myns {

// ...

utf16_ostream& operator<<(utf16_ostream&, jstring) throw(std::bad_cast);

utf16_ostream& operator<<(utf16_ostream&, const char *);

utf16_ostream& operator<<(utf16_ostream&, const jni_utf16_string_region&);

jni_utf16_ostream& operator<<(jni_utf16_ostream&, jstring);

// ...

} // namespace myns

の実装jni_utf16_streambuf::overflow(int_type)は簡単です。バッファ幅を 2 ​​倍にし、要求された文字を置き、ベース、プット、エンド ポインタを正しく設定するだけです。テスト済みで、動作することを確信しています。

jni_utf16_ostreamUnicode 文字を挿入しても問題なく動作します。たとえば、これは問題なく動作し、"hello, world" を含むストリームが生成されます。

myns::jni_utf16_ostream o(env);
o << u"hello, wor" << u'l' << u'd';

私の問題は、整数値を挿入しようとするとすぐに、ストリームの不良ビットが設定されることです。次に例を示します。

myns::jni_utf16_ostream o(env);
if (o.badbit()) throw "bad bit before"; // does not throw
int32_t x(5);
o << x;
if (o.badbit()) throw "bad bit after"; // throws :(

なぜこれが起こっているのか理解できません!std::basic_streambuf実装する必要がある他の方法はありますか????

4

1 に答える 1