【问题标题】:insert utf-8 data in openldap with c api使用 c api 在 openldap 中插入 utf-8 数据
【发布时间】: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 操作错误。

【问题讨论】:

    标签: c++ utf-8 openldap


    【解决方案1】:

    事实证明,我的代码并没有错。我的修改试图将全名存储在“displayName”字段以及“gecos”中。但显然“gecos”无法处理 utf8 数据。

    我们实际上不再使用 gecos。该值仅存在于我们多年前使用的某些软件中,因此我将其从目录中删除。

    很难找到的是,即使将日志级别设置为“解析”,该错误仍然没有出现在日志中。

    因为 libldap 很难破解,所以我将包含一个指向我正在处理的项目的完整代码的链接。它可以作为其他程序员的起点。 (我发现的教程中的大部分代码都已过时。)

    https://github.com/yvanvds/yATools/tree/master/libadmintools/ldap

    【讨论】:

      猜你喜欢
      • 2019-10-18
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      • 2015-08-09
      • 1970-01-01
      • 2013-05-05
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多