選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

77 行
2.2 KiB

  1. // This file is part of Jiffy released under the MIT license.
  2. // See the LICENSE file for more information.
  3. #include "erl_nif.h"
  4. #include "jiffy.h"
  5. typedef struct {
  6. // The Wrapper is a struct intended to be used as a resource to hold a
  7. // binary that's been validated by jiffy to be a valid JSON value
  8. ErlNifEnv* env; // Process independent env to hold the wrapped binary
  9. ERL_NIF_TERM bin;
  10. } Wrapper;
  11. static ERL_NIF_TERM
  12. wrap_new(ErlNifEnv* process_env, ErlNifEnv* process_independent_env, ERL_NIF_TERM binary)
  13. {
  14. jiffy_st* st = (jiffy_st*) enif_priv_data(process_env);
  15. Wrapper* wrapper_p = enif_alloc_resource(st->res_wrapper, sizeof(Wrapper));
  16. ERL_NIF_TERM wrapper_term = enif_make_resource(process_env, wrapper_p);
  17. enif_release_resource(wrapper_p);
  18. wrapper_p->env = process_independent_env;
  19. wrapper_p->bin = binary;
  20. return wrapper_term;
  21. }
  22. ERL_NIF_TERM
  23. wrap_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  24. {
  25. if(argc != 1) {
  26. return enif_make_badarg(env);
  27. }
  28. ERL_NIF_TERM binary = argv[0];
  29. if(!enif_is_binary(env, binary)) {
  30. return enif_make_badarg(env);
  31. }
  32. ErlNifEnv* process_independent_env = enif_alloc_env();
  33. ERL_NIF_TERM bin_copy = enif_make_copy(process_independent_env, binary);
  34. return wrap_new(env, process_independent_env, bin_copy);
  35. }
  36. ERL_NIF_TERM
  37. wrap_enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, size_t pos, size_t size)
  38. {
  39. ErlNifEnv* process_independent_env = enif_alloc_env();
  40. // sub_bin must be created in the same env as the parent binary and then copied
  41. ERL_NIF_TERM sub_bin = enif_make_sub_binary(env, bin_term, pos, size);
  42. return wrap_new(env, process_independent_env, enif_make_copy(process_independent_env, sub_bin));
  43. }
  44. int
  45. unwrap(ErlNifEnv* env, ERL_NIF_TERM wrapper_resource, ERL_NIF_TERM* bin_term_p)
  46. {
  47. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  48. Wrapper* wrapper_p = NULL;
  49. if(!enif_get_resource(env, wrapper_resource, st->res_wrapper, (void**) &wrapper_p)) {
  50. return 0;
  51. }
  52. *bin_term_p = enif_make_copy(env, wrapper_p->bin);
  53. return 1;
  54. }
  55. void
  56. wrapper_destroy(ErlNifEnv* env, void* obj)
  57. {
  58. Wrapper* wrapper_p = (Wrapper*) obj;
  59. enif_free_env(wrapper_p->env);
  60. }