/* Copyright (c) 2016, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/obj.h>

#include <assert.h>
#include <string.h>

#include <openssl/evp.h>


struct wrapped_callback {
  void (*callback)(const OBJ_NAME *, void *arg);
  void *arg;
};

static void cipher_callback(const EVP_CIPHER *cipher, const char *name,
                            const char *unused, void *arg) {
  const struct wrapped_callback *wrapped = (struct wrapped_callback *)arg;
  OBJ_NAME obj_name;

  memset(&name, 0, sizeof(name));
  obj_name.type = OBJ_NAME_TYPE_CIPHER_METH;
  obj_name.name = name;

  wrapped->callback(&obj_name, wrapped->arg);
}

static void md_callback(const EVP_MD *md, const char *name, const char *unused,
                        void *arg) {
  const struct wrapped_callback *wrapped = (struct wrapped_callback*) arg;
  OBJ_NAME obj_name;

  memset(&name, 0, sizeof(name));
  obj_name.type = OBJ_NAME_TYPE_MD_METH;
  obj_name.name = name;

  wrapped->callback(&obj_name, wrapped->arg);
}

void OBJ_NAME_do_all_sorted(int type,
                            void (*callback)(const OBJ_NAME *, void *arg),
                            void *arg) {
  struct wrapped_callback wrapped;
  wrapped.callback = callback;
  wrapped.arg = arg;

  if (type == OBJ_NAME_TYPE_CIPHER_METH) {
    EVP_CIPHER_do_all_sorted(cipher_callback, &wrapped);
  } else if (type == OBJ_NAME_TYPE_MD_METH) {
    EVP_MD_do_all_sorted(md_callback, &wrapped);
  } else {
    assert(0);
  }
}

void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *, void *arg),
                     void *arg) {
  return OBJ_NAME_do_all_sorted(type, callback, arg);
}
