Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

88 Zeilen
2.6 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
  41. // copied, segfaults sometimes otherwise
  42. ERL_NIF_TERM sub_bin = enif_make_sub_binary(env, bin_term, pos, size);
  43. return wrap_new(env, process_independent_env, enif_make_copy(process_independent_env, sub_bin));
  44. }
  45. char*
  46. wrap_enif_make_new_binary(ErlNifEnv* env, size_t size, ERL_NIF_TERM* termp)
  47. {
  48. ErlNifEnv* process_independent_env = enif_alloc_env();
  49. ERL_NIF_TERM bin;
  50. char* chrbuf = (char*) enif_make_new_binary(process_independent_env, size, &bin);
  51. *termp = wrap_new(env, process_independent_env, bin);
  52. return chrbuf;
  53. }
  54. int
  55. unwrap(ErlNifEnv* env, ERL_NIF_TERM wrapper_resource, ERL_NIF_TERM* bin_term_p)
  56. {
  57. jiffy_st* st = (jiffy_st*) enif_priv_data(env);
  58. Wrapper* wrapper_p = NULL;
  59. if(!enif_get_resource(env, wrapper_resource, st->res_wrapper, (void**) &wrapper_p)) {
  60. return 0;
  61. }
  62. *bin_term_p = enif_make_copy(env, wrapper_p->bin);
  63. return 1;
  64. }
  65. void
  66. wrapper_destroy(ErlNifEnv* env, void* obj)
  67. {
  68. Wrapper* wrapper_p = (Wrapper*) obj;
  69. enif_free_env(wrapper_p->env);
  70. }