GtkTextView中UTF-8错误,解码base64。

时间:2021-01-21 18:25:32

I have been trying to figure this out for a few days now. All I am trying to do is decode a base64 string and add it to a Gtk::TextView. Below is the code:

我已经想了好几天了。我所要做的就是解码一个base64字符串并将其添加到Gtk::TextView。下面是代码:

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

When I run the program I get the error:

当我运行程序时,我得到错误:

Gtk-CRITICAL **: gtk_text_buffer_emit_insert: assertion 'g_utf8_validate (text, len, NULL)' failed

This error only occurs with Unicode characters. When the text is ASCII it all works fine. I have tried three different base64 decoders, I tried using std::string and Glib::ustring with all the different decoders. I also tried using the function Glib::locale_to_utf8(), but that gives me the error terminate called after throwing an instance of 'Glib::ConvertError'. And I tried using Glib::convert with the same error.

这个错误只发生在Unicode字符中。当文本为ASCII时,一切正常。我尝试了三种不同的base64解码器,我尝试使用std::string和Glib::ustring和所有不同的解码器。我还尝试使用函数Glib::locale_to_utf8(),但是在抛出一个“Glib:: conver恐惧”的实例之后,它给了我终止调用的错误。我尝试使用Glib::转换为相同的错误。

I know that Gtk::TextView can display Unicode because if I set the text to a string with Unicode it will display the text. I read that Gtk::TextView displays text in UTF-8, so I think my problem is that the decoded string is not coded in UTF-8, but I am not sure. So my question is how can I get Gtk::TextView to display the decoded base64?

我知道Gtk::TextView可以显示Unicode,因为如果我将文本设置为带有Unicode的字符串,它将显示文本。我读到Gtk::TextView在UTF-8中显示文本,所以我认为我的问题是,解码的字符串不是UTF-8编码的,但我不确定。所以我的问题是如何获得Gtk::TextView来显示解码的base64?

Added note: I am using version 3.8 of Gtkmm

补充说明:我正在使用Gtkmm的3.8版本。

Tested using version 3.12, same error message

测试使用版本3.12,同样的错误消息。

Minimal program:

最小的计划:

//test.h

/ / 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

/ / 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

/ / 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 个解决方案

#1


2  

The reason why it was not working was because the string that I encoded was not UTF-8. Thanks to: https://mail.gnome.org/archives/gtk-list/2014-April/msg00016.html. I found out that the encoding was ISO-8859-1. So there are 2 fixes kind of, first, first encode the string to utf8:

它不工作的原因是我编码的字符串不是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Ü");

or you have to figure out the original encoding of the string, so for me this worked:

或者你需要计算出字符串的原始编码,对我来说这是有效的

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

#2


1  

From documentation:

从文档:

Note that the returned binary data is not necessarily zero-terminated, so it should not be used as a character string.

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

That means utf8 validate will read beyond bounds with a likelyhood near 1 get a sequence of bytes which fail to be valid utf8 characters.

这意味着utf8验证将会超出范围,在接近1的情况下会得到一个字节序列,而这个序列不能是有效的utf8字符。


But even that did not fix it. It seems that the length is one too long and the last value is just garbage.

但即使这样也没有解决问题。看起来长度太长,最后一个值就是垃圾。

So you can either use (which I'd recommend)

所以你可以使用(我推荐)

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

or

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

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

So I guess this a bug in gtk+ (which gtkmm encapsulates)

我想这是gtk+中的一个bug (gtkmm封装)

#1


2  

The reason why it was not working was because the string that I encoded was not UTF-8. Thanks to: https://mail.gnome.org/archives/gtk-list/2014-April/msg00016.html. I found out that the encoding was ISO-8859-1. So there are 2 fixes kind of, first, first encode the string to utf8:

它不工作的原因是我编码的字符串不是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Ü");

or you have to figure out the original encoding of the string, so for me this worked:

或者你需要计算出字符串的原始编码,对我来说这是有效的

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

#2


1  

From documentation:

从文档:

Note that the returned binary data is not necessarily zero-terminated, so it should not be used as a character string.

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

That means utf8 validate will read beyond bounds with a likelyhood near 1 get a sequence of bytes which fail to be valid utf8 characters.

这意味着utf8验证将会超出范围,在接近1的情况下会得到一个字节序列,而这个序列不能是有效的utf8字符。


But even that did not fix it. It seems that the length is one too long and the last value is just garbage.

但即使这样也没有解决问题。看起来长度太长,最后一个值就是垃圾。

So you can either use (which I'd recommend)

所以你可以使用(我推荐)

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

or

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

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

So I guess this a bug in gtk+ (which gtkmm encapsulates)

我想这是gtk+中的一个bug (gtkmm封装)