xrp_ns.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright (c) 2016 - 2018 Cadence Design Systems Inc.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sublicense, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included
  13. * in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <inttypes.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include "xrp_debug.h"
  27. #include "xrp_ns.h"
  28. static int compare_cmd_ns(const void *nsid, struct xrp_cmd_ns *cmd_ns)
  29. {
  30. return memcmp(nsid, cmd_ns->id, sizeof(cmd_ns->id));
  31. }
  32. int xrp_cmd_ns_match(const void *nsid, struct xrp_cmd_ns *cmd_ns)
  33. {
  34. return cmd_ns && compare_cmd_ns(nsid, cmd_ns) == 0;
  35. }
  36. #ifdef DEBUG
  37. static void dump_nsid(const void *p)
  38. {
  39. const uint8_t *id = p;
  40. printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  41. id[0], id[1], id[2], id[3],
  42. id[4], id[5],
  43. id[6], id[7],
  44. id[8], id[9],
  45. id[10], id[11], id[12], id[13], id[14], id[15]);
  46. }
  47. static void dump_cmd_ns(const struct xrp_cmd_ns *cmd_ns)
  48. {
  49. if (cmd_ns) {
  50. dump_nsid(cmd_ns->id);
  51. printf(" -> %p(%p)", cmd_ns->handler, cmd_ns->handler_context);
  52. } else {
  53. printf("NULL");
  54. }
  55. }
  56. static void dump_cmd_ns_map(const struct xrp_cmd_ns_map *ns_map)
  57. {
  58. size_t i;
  59. printf("n_cmd_ns: %zu, size_cmd_ns: %zu\n",
  60. ns_map->n_cmd_ns, ns_map->size_cmd_ns);
  61. for (i = 0; i < ns_map->n_cmd_ns; ++i) {
  62. printf(" ");
  63. dump_cmd_ns(ns_map->cmd_ns + i);
  64. printf("\n");
  65. }
  66. }
  67. #else
  68. static void dump_nsid(const void *p)
  69. {
  70. (void)p;
  71. }
  72. static void dump_cmd_ns(const struct xrp_cmd_ns *cmd_ns)
  73. {
  74. (void)cmd_ns;
  75. }
  76. static void dump_cmd_ns_map(const struct xrp_cmd_ns_map *ns_map)
  77. {
  78. (void)ns_map;
  79. }
  80. #endif
  81. static int cmd_ns_present(struct xrp_cmd_ns_map *ns_map,
  82. struct xrp_cmd_ns *cmd_ns)
  83. {
  84. return cmd_ns >= ns_map->cmd_ns &&
  85. cmd_ns < ns_map->cmd_ns + ns_map->n_cmd_ns;
  86. }
  87. struct xrp_cmd_ns *xrp_find_cmd_ns(struct xrp_cmd_ns_map *ns_map,
  88. const void *id)
  89. {
  90. size_t a = 0;
  91. size_t b = ns_map->n_cmd_ns;
  92. struct xrp_cmd_ns *p;
  93. pr_debug("%s: ", __func__);
  94. dump_nsid(id);
  95. pr_debug("\n");
  96. while (b - a > 1) {
  97. size_t c = (a + b) / 2;
  98. pr_debug("a: %zu, b:%zu, c: %zu\n", a, b, c);
  99. p = ns_map->cmd_ns + c;
  100. if (compare_cmd_ns(id, p) < 0)
  101. b = c;
  102. else
  103. a = c;
  104. pr_debug("...a: %zu, b:%zu\n", a, b);
  105. }
  106. p = ns_map->cmd_ns + a;
  107. if (a < b && compare_cmd_ns(id, p) > 0)
  108. ++p;
  109. if (cmd_ns_present(ns_map, p)) {
  110. pr_debug("%s: found: ", __func__);
  111. dump_cmd_ns(p);
  112. pr_debug("\n");
  113. } else {
  114. pr_debug("%s: not found\n", __func__);
  115. }
  116. return p;
  117. }
  118. static struct xrp_cmd_ns *insert_cmd_ns(struct xrp_cmd_ns_map *ns_map,
  119. struct xrp_cmd_ns *cmd_ns)
  120. {
  121. size_t i = cmd_ns - ns_map->cmd_ns;
  122. if (ns_map->n_cmd_ns == ns_map->size_cmd_ns) {
  123. size_t new_size = (ns_map->size_cmd_ns + 1) * 2;
  124. void *new_cmd_ns = realloc(ns_map->cmd_ns,
  125. new_size * sizeof(*ns_map->cmd_ns));
  126. if (!new_cmd_ns)
  127. return NULL;
  128. ns_map->cmd_ns = new_cmd_ns;
  129. ns_map->size_cmd_ns = new_size;
  130. cmd_ns = ns_map->cmd_ns + i;
  131. }
  132. memmove(cmd_ns + 1, cmd_ns,
  133. sizeof(*cmd_ns) * (ns_map->n_cmd_ns - i));
  134. ++ns_map->n_cmd_ns;
  135. return cmd_ns;
  136. }
  137. static void remove_cmd_ns(struct xrp_cmd_ns_map *ns_map,
  138. struct xrp_cmd_ns *cmd_ns)
  139. {
  140. size_t i = cmd_ns - ns_map->cmd_ns;
  141. memmove(cmd_ns, cmd_ns + 1,
  142. sizeof(*cmd_ns) * (ns_map->n_cmd_ns - i - 1));
  143. --ns_map->n_cmd_ns;
  144. }
  145. int xrp_register_namespace(struct xrp_cmd_ns_map *ns_map,
  146. const void *nsid,
  147. xrp_command_handler *handler,
  148. void *handler_context)
  149. {
  150. struct xrp_cmd_ns *cmd_ns = xrp_find_cmd_ns(ns_map, nsid);
  151. if (cmd_ns_present(ns_map, cmd_ns) && xrp_cmd_ns_match(nsid, cmd_ns)) {
  152. return 0;
  153. } else {
  154. cmd_ns = insert_cmd_ns(ns_map, cmd_ns);
  155. if (cmd_ns) {
  156. memcpy(cmd_ns->id, nsid, sizeof(cmd_ns->id));
  157. cmd_ns->handler = handler;
  158. cmd_ns->handler_context = handler_context;
  159. dump_cmd_ns_map(ns_map);
  160. return 1;
  161. } else {
  162. return 0;
  163. }
  164. }
  165. }
  166. int xrp_unregister_namespace(struct xrp_cmd_ns_map *ns_map,
  167. const void *nsid)
  168. {
  169. struct xrp_cmd_ns *cmd_ns = xrp_find_cmd_ns(ns_map, nsid);
  170. if (cmd_ns_present(ns_map, cmd_ns) && xrp_cmd_ns_match(nsid, cmd_ns)) {
  171. remove_cmd_ns(ns_map, cmd_ns);
  172. dump_cmd_ns_map(ns_map);
  173. return 1;
  174. } else {
  175. return 0;
  176. }
  177. }