迭代ldap搜索结果集

时间:2014-08-07 07:44:20

标签: c ldap openldap

我正在使用libldap从OpenLDAP服务器获取信息。到目前为止,代码工作正常,但我对如何设计结果集的处理有点不确定。让我们说搜索返回2个属性,这些属性都是多值的,并且可以有很多值(例如memberOf属性)。

现在我使代码尽可能紧凑:

for (ldap_result = ldap_first_message(ldap_handle, ldap_result); ldap_result != NULL; ldap_result = ldap_next_message(ldap_handle, ldap_result)) {
    switch (msgtype = ldap_msgtype(ldap_result)) {
        case LDAP_RES_SEARCH_ENTRY:
            {
                /* iterate over all requested attributes */
                for (attr = ldap_first_attribute(ldap_handle, ldap_result, &ber); attr != NULL; attr = ldap_next_attribute(ldap_handle, ldap_result, ber)) {
                    /* iterate over attribute values */
                    if ((bvals = ldap_get_values_len(ldap_handle, ldap_result, attr)) != NULL) {
                        int i;
                        for (i = 0; bvals[i] != '\0'; i++) {
                            char *value = bvals[i]->bv_val;
                            ber_len_t len = bvals[i]->bv_len;

                            // if attribute == x
                            if (strcmp(attr, "x")) == 0) {
                                // do_x();
                                // do_y();

                            // if attribute == y
                            } else if (strcmp(attr, "y") == 0) {
                                // do_sth_different();
                            }
                            /* free values structure after each iteration */
                            ldap_value_free_len(bvals);
                        }
                    }
                }
                /* free attributes structure */
                ber_free(ber, 0);
                break;
            }
        default:
            {
            // whatever
            break;
            }
    }
}

那么这里发生了什么?我得到第一个属性,例如100个值。对于每个值,如果其属性为a或b,我会进行字符串比较。在现代硬件和较少的价值观上,它不会成为一个问题,但可能会有更多价值。代码紧凑但效率可能更好。

让我们看看我们如何能让它与众不同:

for (ldap_result = ldap_first_message(ldap_handle, ldap_result); ldap_result != NULL; ldap_result = ldap_next_message(ldap_handle, ldap_result)) {
    switch (msgtype = ldap_msgtype(ldap_result)) {
        case LDAP_RES_SEARCH_ENTRY:
            {
                /* iterate over all requested attributes */
                for (attr = ldap_first_attribute(ldap_handle, ldap_result, &ber); attr != NULL; attr = ldap_next_attribute(ldap_handle, ldap_result, ber)) {
                    // if attribute == x
                    if (strcmp(attr, "x")) == 0) {
                        /* iterate over attribute values */
                        if ((bvals = ldap_get_values_len(ldap_handle, ldap_result, attr)) != NULL) {
                            int i;
                            for (i = 0; bvals[i] != '\0'; i++) {
                                /* iterate over attribute values */
                                char *value = bvals[i]->bv_val;
                                ber_len_t len = bvals[i]->bv_len;

                                // do_x();
                                // do_y();
                                /* free values structure after each iteration */
                                ldap_value_free_len(bvals);
                            }
                            /* free attributes structure */
                            ber_free(ber, 0);
                        }
                    // if attribute == y
                    } else if (strcmp(attr, "y") == 0) {
                        /* iterate over attribute values */
                        if ((bvals = ldap_get_values_len(ldap_handle, ldap_result, attr)) != NULL) {
                            int i;
                            for (i = 0; bvals[i] != '\0'; i++) {
                                /* iterate over attribute values */
                                char *value = bvals[i]->bv_val;
                                ber_len_t len = bvals[i]->bv_len;

                                // do_sth_different();
                                /* free values structure after each iteration */
                                ldap_value_free_len(bvals);
                            }
                            /* free attributes structure */
                            ber_free(ber, 0);
                        }
                    }
                }   
            }
        default:
            {
            // whatever
            break;
            }
    }
}

现在只有一个字符串比较,如果它的属性为a或b。不幸的是,这两个属性都有很多代码重复。

任何解决方案更适合的建议还是可能还有一个我尚未见过的建议?

1 个答案:

答案 0 :(得分:1)

在第一个示例中,保存attr是x还是y的值,以便计算一次而不会出现代码重复问题

 for (attr = ldap_first_attribute(ldap_handle, ldap_result, &ber); attr != NULL; attr = ldap_next_attribute(ldap_handle, ldap_result, ber)) {
                /* iterate over attribute values */
      bool isX = strcmp(attr, "x")) == 0;
      bool isY =  strcmp(attr, "y")) == 0;

      ....

      // if attribute == x
      if (isX) {
          // do_x();
          // do_y();

       // if attribute == y
      } else if (isY) {
           // do_sth_different();
       }