解码base64时在GtkTextView中出现UTF-8错误

4

我已经试了几天了,只是想将一个Base64字符串解码并添加到Gtk::TextView中。以下是代码:

txtbuffer_ = Gtk::TextBuffer::create();
txtview_.set_buffer(txtbuffer_);
const Glib::ustring str = Glib::Base64::decode("YmJi3A==");
txtbuffer_->set_text(str);

当我运行程序时,出现了以下错误:
Gtk-CRITICAL **: gtk_text_buffer_emit_insert: assertion 'g_utf8_validate (text, len, NULL)' failed

这个错误只会在使用Unicode字符时出现。当文本为ASCII时,一切都运行良好。 我尝试了三个不同的base64解码器,使用了std::string和Glib::ustring与所有不同的解码器进行了尝试。我还尝试使用函数Glib::locale_to_utf8(),但是这给我带来了错误terminate called after throwing an instance of 'Glib::ConvertError'。同时我也使用了Glib::convert,但是出现了相同的错误。 我知道Gtk::TextView可以显示Unicode,因为如果我将文本设置为含有Unicode的字符串,它就能够正确地显示该文本。我读到Gtk::TextView以UTF-8格式显示文本,所以我认为我的问题在于解码后的字符串没有编码成UTF-8,但我并不确定。因此我的问题是如何让Gtk::TextView显示解码后的base64? 补充说明:我正在使用Gtkmm的3.8版本 已测试使用3.12版本,出现相同错误信息 最小程序如下: //test.h
#ifndef TEST_H_
#define TEST_H_

#include <gtkmm.h>

class MainWindow : public Gtk::Window
{
public:
    MainWindow();
    virtual ~MainWindow();

protected:
    Gtk::Box box_main;
    Gtk::TextView txtview_;
    Glib::RefPtr<Gtk::TextBuffer> txtbuffer_;
};

#endif /* TEST_H_ */

//test.cpp

#include "test.h"

MainWindow::MainWindow()
{   
    Gtk::Window::add(box_main);

    box_main.pack_start(txtview_);

    txtbuffer_ = Gtk::TextBuffer::create();
    txtview_.set_buffer(txtbuffer_);
    const Glib::ustring str = Glib::Base64::decode("YmJi3A==");
    txtbuffer_->set_text(str);

    Gtk::Window::show_all_children();
}

MainWindow::~MainWindow()
{

}

//main.cpp

#include "test.h"

int main(int argc, char* argv[])
{
    Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "test.program");

    MainWindow mw;

    return app->run(mw);
}

你能否提供一个最小可编译示例给我看看?这让我感到有些可疑,我想要仔细研究一下... - drahnr
2个回答

2

无法正常工作的原因是我编码的字符串不是UTF-8格式。感谢:https://mail.gnome.org/archives/gtk-list/2014-April/msg00016.html。我发现编码格式是ISO-8859-1。因此有两种解决方法,第一种是先将字符串编码为utf8:

const Glib::ustring str2 = Glib::Base64::encode("bbbÜ");

或者您需要找出字符串的原始编码方式,对我来说,这种方法有效:
Glib::convert(base64_str, "UTF-8", "ISO-8859-1");

1

来自文档:

请注意,返回的二进制数据不一定以零结尾,因此不应将其用作字符字符串。

这意味着utf8验证将超出边界读取,很可能会获得一系列无法成为有效utf8字符的字节序列。


但是即使这样也没有解决问题。似乎长度多了一个,最后一个值是垃圾数据。

因此,您可以使用以下方法(我建议使用)

std::string stdstr = Glib::Base64::decode (x);
const Glib::ustring str(stdstr.c_str(), stdstr.length()-1);

或者

gsize len = 0;
const gchar *ret = (gchar*)g_base64_decode (x, &len);

len --;
const Glib::ustring str(ret, len);
g_free (ret);

所以我猜这是gtk+(gtkmm封装的)中的一个bug。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接