You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
3.7 KiB

10 years ago
  1. /* -*- coding: utf-8 -*-
  2. * ----------------------------------------------------------------------
  3. * Copyright © 2010-2012, RedJack, LLC.
  4. * All rights reserved.
  5. *
  6. * Please see the LICENSE.txt file in this distribution for license
  7. * details.
  8. * ----------------------------------------------------------------------
  9. */
  10. #include <libcork/core.h>
  11. #include "ipset/bdd/nodes.h"
  12. struct ipset_assignment *
  13. ipset_assignment_new()
  14. {
  15. struct ipset_assignment *assignment = cork_new(struct ipset_assignment);
  16. cork_array_init(&assignment->values);
  17. return assignment;
  18. }
  19. void
  20. ipset_assignment_free(struct ipset_assignment *assignment)
  21. {
  22. cork_array_done(&assignment->values);
  23. free(assignment);
  24. }
  25. bool
  26. ipset_assignment_equal(const struct ipset_assignment *assignment1,
  27. const struct ipset_assignment *assignment2)
  28. {
  29. /* Identical pointers are trivially equal. */
  30. if (assignment1 == assignment2) {
  31. return true;
  32. }
  33. /* Otherwise we compare the assignments piecewise up through the end
  34. * of the smaller vector. */
  35. unsigned int size1 = cork_array_size(&assignment1->values);
  36. unsigned int size2 = cork_array_size(&assignment2->values);
  37. unsigned int smaller_size = (size1 < size2)? size1: size2;
  38. unsigned int i;
  39. for (i = 0; i < smaller_size; i++) {
  40. if (cork_array_at(&assignment1->values, i) !=
  41. cork_array_at(&assignment2->values, i)) {
  42. return false;
  43. }
  44. }
  45. /* If one of the assignment vectors is longer, any remaining
  46. * elements must be indeterminate. */
  47. if (size1 > smaller_size) {
  48. for (i = smaller_size; i < size1; i++) {
  49. if (cork_array_at(&assignment1->values, i) != IPSET_EITHER) {
  50. return false;
  51. }
  52. }
  53. }
  54. if (size2 > smaller_size) {
  55. for (i = smaller_size; i < size2; i++) {
  56. if (cork_array_at(&assignment2->values, i) != IPSET_EITHER) {
  57. return false;
  58. }
  59. }
  60. }
  61. /* If we make it through all of that, the two assignments are equal. */
  62. return true;
  63. }
  64. void
  65. ipset_assignment_cut(struct ipset_assignment *assignment,
  66. ipset_variable var)
  67. {
  68. if (var < cork_array_size(&assignment->values)) {
  69. assignment->values.size = var;
  70. }
  71. }
  72. void
  73. ipset_assignment_clear(struct ipset_assignment *assignment)
  74. {
  75. ipset_assignment_cut(assignment, 0);
  76. }
  77. enum ipset_tribool
  78. ipset_assignment_get(struct ipset_assignment *assignment, ipset_variable var)
  79. {
  80. if (var < cork_array_size(&assignment->values)) {
  81. /* If the requested variable is in the range of the values
  82. * array, return whatever is stored there. */
  83. return cork_array_at(&assignment->values, var);
  84. } else {
  85. /* Variables htat aren't in the values array are always EITHER. */
  86. return IPSET_EITHER;
  87. }
  88. }
  89. void
  90. ipset_assignment_set(struct ipset_assignment *assignment,
  91. ipset_variable var, enum ipset_tribool value)
  92. {
  93. /* Ensure that the vector is big enough to hold this variable
  94. * assignment, inserting new EITHERs if needed. */
  95. if (var >= cork_array_size(&assignment->values)) {
  96. unsigned int old_len = cork_array_size(&assignment->values);
  97. /* Expand the array. */
  98. cork_array_ensure_size(&assignment->values, var+1);
  99. assignment->values.size = var+1;
  100. /* Fill in EITHERs in the newly allocated elements. */
  101. if (var != old_len) {
  102. unsigned int i;
  103. for (i = old_len; i < var; i++) {
  104. cork_array_at(&assignment->values, i) = IPSET_EITHER;
  105. }
  106. }
  107. }
  108. /* Assign the desired value. */
  109. cork_array_at(&assignment->values, var) = value;
  110. }