namespace.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #include "uthash.h"
  2. #include "namespace.h"
  3. typedef struct namespace_t {
  4. ns_pfx pfx; // Namespace prefix.
  5. char * ns; // Fully qualified NS.
  6. UT_hash_handle hh; // UTHash handle.
  7. } Namespace;
  8. typedef struct namespace_index_t {
  9. Namespace * ns; // Pointer to a NS struct.
  10. UT_hash_handle hh; // UTHash handle.
  11. } NSIndex;
  12. typedef struct ns_map_t {
  13. Namespace * pn; // Prefix to namespace.
  14. NSIndex * np; // Namespace to prefix.
  15. } NSMap;
  16. NSMap *
  17. LSUP_nsmap_new (void)
  18. {
  19. NSMap *map;
  20. CALLOC_GUARD (map, NULL);
  21. return map;
  22. }
  23. void
  24. LSUP_nsmap_free (NSMap *map)
  25. {
  26. if (UNLIKELY (!map)) return;
  27. Namespace *entry, *tmp;
  28. HASH_ITER (hh, map->pn, entry, tmp) {
  29. HASH_DEL (map->pn, entry);
  30. free (entry->ns);
  31. free (entry);
  32. }
  33. NSIndex *idx_entry, *idx_tmp;
  34. HASH_ITER (hh, map->np, idx_entry, idx_tmp) {
  35. HASH_DEL (map->np, idx_entry);
  36. free (idx_entry);
  37. }
  38. free (map);
  39. }
  40. LSUP_rc
  41. LSUP_nsmap_add (NSMap *map, const ns_pfx pfx, const char *nsstr)
  42. {
  43. // Main entry (pn)
  44. // Delete any found record.
  45. // Main and index are deleted independently because the pair may be
  46. // different.
  47. Namespace *entry = NULL;
  48. HASH_FIND_STR (map->pn, pfx, entry);
  49. if (entry) {
  50. HASH_DEL (map->pn, entry);
  51. free (entry->ns);
  52. free (entry);
  53. }
  54. // Add.
  55. MALLOC_GUARD (entry, LSUP_MEM_ERR);
  56. //entry = malloc (sizeof (*entry));
  57. //if (UNLIKELY (!entry)) return LSUP_MEM_ERR;
  58. entry->ns = strdup (nsstr);
  59. strcpy (entry->pfx, pfx);
  60. HASH_ADD_STR (map->pn, pfx, entry);
  61. // Index.
  62. // Delete any found record.
  63. NSIndex *idx_entry = NULL;
  64. HASH_FIND_STR (map->np, nsstr, idx_entry);
  65. if (idx_entry) {
  66. HASH_DEL (map->np, idx_entry);
  67. free (idx_entry);
  68. }
  69. // Add.
  70. MALLOC_GUARD (idx_entry, LSUP_MEM_ERR);
  71. //idx_entry = malloc (sizeof (*idx_entry));
  72. //if (UNLIKELY (!entry)) return LSUP_MEM_ERR;
  73. idx_entry->ns = entry;
  74. HASH_ADD_KEYPTR (hh, map->np, entry->ns, strlen (nsstr), idx_entry);
  75. return LSUP_OK;
  76. }
  77. LSUP_rc
  78. LSUP_nsmap_remove (NSMap *map, const ns_pfx pfx)
  79. {
  80. Namespace *entry = NULL;
  81. NSIndex *idx_entry = NULL;
  82. HASH_FIND_STR (map->pn, pfx, entry);
  83. if (entry) {
  84. HASH_FIND_STR (map->np, entry->ns, idx_entry);
  85. if (idx_entry) {
  86. HASH_DEL (map->np, idx_entry);
  87. free (idx_entry);
  88. }
  89. HASH_DEL (map->pn, entry);
  90. free (entry->ns);
  91. free (entry);
  92. return LSUP_OK;
  93. }
  94. return LSUP_NOACTION;
  95. }
  96. const char *
  97. LSUP_nsmap_get (const NSMap *map, const ns_pfx pfx)
  98. {
  99. Namespace *entry = NULL;
  100. HASH_FIND_STR (map->pn, pfx, entry);
  101. return (entry) ? entry->ns : NULL;
  102. }
  103. LSUP_rc
  104. LSUP_nsmap_normalize_uri (
  105. const NSMap *map, const char *uri, char **pfx_uri)
  106. {
  107. *pfx_uri = NULL;
  108. NSIndex *entry;
  109. HASH_FIND_STR (map->np, uri, entry);
  110. if (entry) {
  111. *pfx_uri = malloc (
  112. strlen (entry->ns->pfx)
  113. + strlen (uri) - strlen (entry->ns->ns)
  114. + 2); // one for terminating \x00, one for the colon.
  115. if (UNLIKELY (! (*pfx_uri))) return LSUP_MEM_ERR;
  116. sprintf (
  117. *pfx_uri, "%s:%s",
  118. entry->ns->pfx, uri + strlen (entry->ns->ns));
  119. return LSUP_OK;
  120. } else return LSUP_NORESULT;
  121. }
  122. LSUP_rc
  123. LSUP_nsmap_denormalize_uri (
  124. const NSMap *map, const char *pfx_uri, char **uri)
  125. {
  126. *uri = NULL;
  127. size_t pfx_len = strcspn (pfx_uri, ":");
  128. if (pfx_len >= PFX_LEN) pfx_len = PFX_LEN - 1;
  129. ns_pfx pfx;
  130. strncpy (pfx, pfx_uri, pfx_len);
  131. pfx[pfx_len] = 0;
  132. Namespace *entry;
  133. HASH_FIND_STR (map->pn, pfx, entry);
  134. if (entry)
  135. *uri = malloc (strlen (entry->ns) + strlen (pfx_uri) - pfx_len - 1);
  136. else *uri = strdup (pfx_uri);
  137. return LSUP_OK;
  138. }