【发布时间】:2015-05-07 20:36:28
【问题描述】:
在 openldap 数据库中插入 utf-8 数据的正确方法是什么?我在 std::wstring 中有 utf-8 编码的数据:
std::wstring converted = boost::locale::conv::to_utf<wchar_t>(line, "Latin1");
当字符串需要添加到 ldapMod 结构时,我使用这个函数:
std::string str8(const std::wstring& s) {
return boost::locale::conv::utf_to_utf<char>(s);
}
从 wstring 转换为 string。这在我的函数中用于创建 LDAPMod:
LDAPMod ** y::ldap::server::createMods(dataset& values) {
LDAPMod ** mods = new LDAPMod*[values.elms() + 1];
mods[values.elms()] = NULL;
for(int i = 0; i < values.elms(); i++) {
mods[i] = new LDAPMod;
data & d = values.get(i);
switch (d.getType()) {
case NEW: mods[i]->mod_op = 0; break;
case ADD: mods[i]->mod_op = LDAP_MOD_ADD; break;
case MODIFY: mods[i]->mod_op = LDAP_MOD_REPLACE; break;
case DELETE: mods[i]->mod_op = LDAP_MOD_DELETE; break;
default: assert(false);
}
std::string type = str8(d.getValue(L"type"));
mods[i]->mod_type = new char[type.size() + 1];
std::copy(type.begin(), type.end(), mods[i]->mod_type);
mods[i]->mod_type[type.size()] = '\0';
mods[i]->mod_vals.modv_strvals = new char*[d.elms(L"values") + 1];
for(int j = 0; j < d.elms(L"values"); j++) {
std::string value = str8(d.getValue(L"values", j));
mods[i]->mod_vals.modv_strvals[j] = new char[value.size() + 1];
std::copy(value.begin(), value.end(), mods[i]->mod_vals.modv_strvals[j]);
mods[i]->mod_vals.modv_strvals[j][value.size()] = '\0';
}
mods[i]->mod_vals.modv_strvals[d.elms(L"values")] = NULL;
}
return mods;
}
生成的 LDAPMod 被传递给 ldap_modify_ext_s 并且只要我只使用 ASCII 字符就可以工作。但是,如果字符串中存在其他字符,则会出现 ldap 操作错误。
我也用 ldap 库 (ldap_x_wcs_to_utf8s) 提供的函数试过这个,但结果和 boost 转换一样。
不是转换本身有问题,因为如果我将修改转换回 std::wstring 并在我的程序输出中显示它,编码仍然是正确的。
AFAIK openldap 长期以来一直支持 utf-8,所以我想知道在此之前是否还有其他事情必须完成?
我查看了 openldap 客户端/工具示例,但该库提供的 utf-8 函数从未在其中使用过。
更新: 我注意到我可以使用 Apache Directory Studio 将像 é 这样的 utf-8 字符插入 ldap。我可以在我的 c++ 程序中从 ldap 检索这些值。但是,如果我再次插入相同的字符,而不对该字符串进行任何更改,我会再次收到 ldap 操作错误。
【问题讨论】: