bitfunc.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. *
  4. * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
  5. *
  6. */
  7. #include <linux/types.h>
  8. #include "ntfs_fs.h"
  9. #define BITS_IN_SIZE_T (sizeof(size_t) * 8)
  10. /*
  11. * fill_mask[i] - first i bits are '1' , i = 0,1,2,3,4,5,6,7,8
  12. * fill_mask[i] = 0xFF >> (8-i)
  13. */
  14. static const u8 fill_mask[] = { 0x00, 0x01, 0x03, 0x07, 0x0F,
  15. 0x1F, 0x3F, 0x7F, 0xFF };
  16. /*
  17. * zero_mask[i] - first i bits are '0' , i = 0,1,2,3,4,5,6,7,8
  18. * zero_mask[i] = 0xFF << i
  19. */
  20. static const u8 zero_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0,
  21. 0xE0, 0xC0, 0x80, 0x00 };
  22. /*
  23. * are_bits_clear
  24. *
  25. * Return: True if all bits [bit, bit+nbits) are zeros "0".
  26. */
  27. bool are_bits_clear(const void *lmap, size_t bit, size_t nbits)
  28. {
  29. size_t pos = bit & 7;
  30. const u8 *map = (u8 *)lmap + (bit >> 3);
  31. if (pos) {
  32. if (8 - pos >= nbits)
  33. return !nbits || !(*map & fill_mask[pos + nbits] &
  34. zero_mask[pos]);
  35. if (*map++ & zero_mask[pos])
  36. return false;
  37. nbits -= 8 - pos;
  38. }
  39. pos = ((size_t)map) & (sizeof(size_t) - 1);
  40. if (pos) {
  41. pos = sizeof(size_t) - pos;
  42. if (nbits >= pos * 8) {
  43. for (nbits -= pos * 8; pos; pos--, map++) {
  44. if (*map)
  45. return false;
  46. }
  47. }
  48. }
  49. for (pos = nbits / BITS_IN_SIZE_T; pos; pos--, map += sizeof(size_t)) {
  50. if (*((size_t *)map))
  51. return false;
  52. }
  53. for (pos = (nbits % BITS_IN_SIZE_T) >> 3; pos; pos--, map++) {
  54. if (*map)
  55. return false;
  56. }
  57. pos = nbits & 7;
  58. if (pos && (*map & fill_mask[pos]))
  59. return false;
  60. return true;
  61. }
  62. /*
  63. * are_bits_set
  64. *
  65. * Return: True if all bits [bit, bit+nbits) are ones "1".
  66. */
  67. bool are_bits_set(const void *lmap, size_t bit, size_t nbits)
  68. {
  69. u8 mask;
  70. size_t pos = bit & 7;
  71. const u8 *map = (u8 *)lmap + (bit >> 3);
  72. if (pos) {
  73. if (8 - pos >= nbits) {
  74. mask = fill_mask[pos + nbits] & zero_mask[pos];
  75. return !nbits || (*map & mask) == mask;
  76. }
  77. mask = zero_mask[pos];
  78. if ((*map++ & mask) != mask)
  79. return false;
  80. nbits -= 8 - pos;
  81. }
  82. pos = ((size_t)map) & (sizeof(size_t) - 1);
  83. if (pos) {
  84. pos = sizeof(size_t) - pos;
  85. if (nbits >= pos * 8) {
  86. for (nbits -= pos * 8; pos; pos--, map++) {
  87. if (*map != 0xFF)
  88. return false;
  89. }
  90. }
  91. }
  92. for (pos = nbits / BITS_IN_SIZE_T; pos; pos--, map += sizeof(size_t)) {
  93. if (*((size_t *)map) != MINUS_ONE_T)
  94. return false;
  95. }
  96. for (pos = (nbits % BITS_IN_SIZE_T) >> 3; pos; pos--, map++) {
  97. if (*map != 0xFF)
  98. return false;
  99. }
  100. pos = nbits & 7;
  101. if (pos) {
  102. mask = fill_mask[pos];
  103. if ((*map & mask) != mask)
  104. return false;
  105. }
  106. return true;
  107. }