util.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <assert.h>
  2. #include <errno.h>
  3. #include <stddef.h>
  4. #include <stdint.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <err.h>
  8. #include <sysexits.h>
  9. #include "util.h"
  10. void *
  11. allot(void **ptr, size_t *s, size_t n, size_t m, size_t d)
  12. {
  13. void *p;
  14. assert(ptr != NULL && s != NULL && m > 0);
  15. if (*ptr == NULL)
  16. *s = 0;
  17. assert(SIZE_MAX / m >= d && SIZE_MAX - *s >= d * m);
  18. if (*s / m <= n) {
  19. if (d == 0)
  20. return (NULL);
  21. if ((p = (*ptr == NULL ? malloc(d * m) :
  22. realloc(*ptr, *s + d * m))) == NULL)
  23. err(EX_OSERR, "allot");
  24. *ptr = p;
  25. *s += d * m;
  26. }
  27. return (((char *)*ptr) + n * m);
  28. }
  29. void
  30. memshuffle(void *p, size_t n, size_t s)
  31. {
  32. size_t i;
  33. assert(p != NULL);
  34. if (n < 2 || s == 0)
  35. return;
  36. assert(SIZE_MAX / n >= s);
  37. for (i = 0; i < n - 1; i++)
  38. memswap((char *)p + arc4random_uniform(n - i) * s,
  39. (char *)p + i * s, s);
  40. }
  41. void
  42. memswap(void *a, void *b, size_t s)
  43. {
  44. char buf[sizeof(void *) * 0x10];
  45. size_t i;
  46. assert(a != NULL && b != NULL);
  47. if (a == b)
  48. return;
  49. for (i = 0; i + sizeof(buf) <= s; i += sizeof(buf)) {
  50. (void)memcpy(buf, (char *)a + i, sizeof(buf));
  51. (void)memcpy((char *)a + i, (char *)b + i, sizeof(buf));
  52. (void)memcpy((char *)b + i, buf, sizeof(buf));
  53. }
  54. if (i < s) {
  55. (void)memcpy(buf, (char *)a + i, s - i);
  56. (void)memcpy((char *)a + i, (char *)b + i, s - i);
  57. (void)memcpy((char *)b + i, buf, s - i);
  58. }
  59. }