erlang各种有用的函数包括一些有用nif封装,还有一些性能测试case。
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
2.8 KiB

  1. #include <stdint.h>
  2. #include "erl_nif.h"
  3. #ifdef _WIN32
  4. #define INLINE __inline
  5. #else
  6. #define INLINE inline
  7. #endif
  8. static ErlNifResourceType* ResType = NULL;
  9. ERL_NIF_TERM null;
  10. ERL_NIF_TERM ok;
  11. static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
  12. {
  13. ErlNifResourceFlags flags = ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER;
  14. ResType = enif_open_resource_type(env, NULL, "_nifArray_", NULL, flags, NULL);
  15. if(NULL == ResType)
  16. return -1;
  17. null = enif_make_atom(env, "null");
  18. ok = enif_make_atom(env, "ok");
  19. return 0;
  20. }
  21. static ERL_NIF_TERM new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  22. {
  23. uint32_t Size;
  24. if(!enif_get_uint(env, argv[0], &Size)) {
  25. return enif_make_badarg(env);
  26. }
  27. ErlNifBinary **ArrayPtr = (ErlNifBinary **) enif_alloc_resource(ResType, sizeof(ErlNifBinary*)*Size);
  28. int i;
  29. for(i = 0; i < Size; i++){
  30. ArrayPtr[i] = NULL;
  31. }
  32. ERL_NIF_TERM Res = enif_make_resource(env, ArrayPtr);
  33. enif_release_resource(ArrayPtr);
  34. return Res;
  35. }
  36. static ERL_NIF_TERM get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  37. {
  38. uint32_t Index;
  39. if(!enif_get_uint(env, argv[1], &Index)) {
  40. return enif_make_badarg(env);
  41. }
  42. ErlNifBinary **ArrayPtr;
  43. if (!enif_get_resource(env, argv[0], ResType, (void**)&ArrayPtr)){
  44. return enif_make_badarg(env);
  45. }
  46. if(NULL != ArrayPtr[Index]){
  47. ERL_NIF_TERM Ret;
  48. enif_binary_to_term(env, ArrayPtr[Index]->data, ArrayPtr[Index]->size, &Ret, 0);
  49. return Ret;
  50. } else{
  51. return null;
  52. }
  53. }
  54. static ERL_NIF_TERM put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  55. {
  56. uint32_t Index;
  57. if(!enif_get_uint(env, argv[1], &Index)) {
  58. return enif_make_badarg(env);
  59. }
  60. ErlNifBinary *Value = (ErlNifBinary *)malloc(sizeof(ErlNifBinary));
  61. if(!enif_term_to_binary(env, argv[2], Value))
  62. return enif_make_badarg(env);
  63. ErlNifBinary **ArrayPtr;
  64. if (!enif_get_resource(env, argv[0], ResType, (void**)&ArrayPtr)){
  65. return enif_make_badarg(env);
  66. }
  67. if(NULL == ArrayPtr[Index]){
  68. ArrayPtr[Index] = Value;
  69. return ok;
  70. } else{
  71. enif_release_binary(ArrayPtr[Index]),
  72. free(ArrayPtr[Index]);
  73. ArrayPtr[Index] = Value;
  74. return ok;
  75. }
  76. }
  77. static ERL_NIF_TERM test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
  78. {
  79. ErlNifBinary Value;
  80. if(!enif_term_to_binary(env, argv[0], &Value))
  81. return enif_make_badarg(env);
  82. // enif_fprintf(stdout, "IMY************ %T", argv[0]);
  83. ERL_NIF_TERM Ret;
  84. enif_binary_to_term(env, Value.data, Value.size, &Ret, 0);
  85. enif_release_binary(&Value);
  86. return Ret;
  87. }
  88. static ErlNifFunc nifFuns[] = {
  89. {"new", 1, new},
  90. {"get", 2, get},
  91. {"put", 3, put},
  92. {"test", 1, test},
  93. };
  94. ERL_NIF_INIT(nifArray, nifFuns, &load, NULL, NULL, NULL)