を呼び出す方法と同様の方法で JNI 文字列を取得できる出力ストリームが必要なため、カスタムstd::basic_streambuf
andを作成しました。これらのクラスは非常に単純です。std::basic_ostream
std::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_ostream
Unicode 文字を挿入しても問題なく動作します。たとえば、これは問題なく動作し、"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
実装する必要がある他の方法はありますか????