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

时间:2014-04-13 18:08:01

标签: c++ utf-8 gtk base64 gtkmm

我一直试图解决这个问题几天了。我想要做的就是解码一个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);
}

2 个答案:

答案 0 :(得分:2)

它无法工作的原因是因为我编码的字符串不是UTF-8。感谢:https://mail.gnome.org/archives/gtk-list/2014-April/msg00016.html。我发现编码是ISO-8859-1。所以有2种修复类型,首先,首先将字符串编码为utf8:

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

或者你必须弄清楚字符串的原始编码,所以对我来说这很有效:

Glib::convert(base64_str, "UTF-8", "ISO-8859-1");

答案 1 :(得分:1)

来自文档:

  

请注意,返回的二进制数据不一定是零终止的,   所以它不应该用作字符串。

这意味着utf8 validate将读取超出边界的可能性接近1获得一个字节序列,该字节序列无法成为有效的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封装)