Windows NT 4.0 source code leak
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.

118 lines
2.7 KiB

4 years ago
  1. // BitUtils.c -- Functions for scanning bit strings
  2. #include "stdafx.h"
  3. #include "BitUtils.h"
  4. #include "ByteMaps.h"
  5. int ConstructMasks(UINT ibitStart, UINT ibitLimit, PUINT pfMaskLeft, PUINT pfMaskRight)
  6. {
  7. ASSERT(ibitStart <= ibitLimit);
  8. UINT fMaskLeft = ~(UINT(~0) >> (32 - ibitStart & 0x1F));
  9. UINT fMaskRight = ~(UINT(~0) << ( ibitLimit & 0x1F));
  10. int cdwSpan= (ibitLimit >> 5) - ((ibitStart+31) >> 5);
  11. if (cdwSpan < 0) *pfMaskLeft= fMaskLeft & fMaskRight;
  12. else
  13. {
  14. *pfMaskLeft= fMaskLeft; *pfMaskRight= fMaskRight;
  15. }
  16. return cdwSpan;
  17. }
  18. UINT C1sInDWord(UINT ui)
  19. {
  20. if (!ui) return 0;
  21. return acBits[ui >>24] + acBits[0xFF & (ui >> 16)]
  22. + acBits[0xFF & (ui >> 8)]
  23. + acBits[0xFF & ui ];
  24. }
  25. UINT SumOfBitsInRange(PUINT pdw, UINT ibitStart, UINT ibitLimit)
  26. {
  27. if (ibitStart >= ibitLimit) return 0;
  28. UINT fMaskLeft, fMaskRight;
  29. int cdwMiddle= ConstructMasks(ibitStart, ibitLimit, &fMaskLeft, &fMaskRight);
  30. pdw += ibitStart >> 5;
  31. if (cdwMiddle < 0) return C1sInDWord(fMaskLeft & *pdw);
  32. UINT c1s= 0;
  33. if (fMaskLeft) c1s += C1sInDWord(*pdw++ & fMaskLeft);
  34. while (cdwMiddle--) c1s += C1sInDWord(*pdw++);
  35. if (fMaskRight) c1s += C1sInDWord(*pdw++ & fMaskRight);
  36. return c1s;
  37. }
  38. UINT Leading0sInDWord(UINT ui)
  39. {
  40. if (!ui) return 32;
  41. if (ui & 0x0000FFFF)
  42. if (ui & 0x000000FF) return acLeadingZeroes[0xFF & ui ];
  43. else return 8 + acLeadingZeroes[0xFF & (ui >> 8)];
  44. else
  45. if (ui & 0x00FF0000) return 16 + acLeadingZeroes[0xFF & (ui >> 16)];
  46. else return 24 + acLeadingZeroes[ ui >> 24 ];
  47. }
  48. inline UINT minui(UINT a, UINT b)
  49. {
  50. return (a < b)? a : b;
  51. }
  52. UINT Leading0sInRange(PUINT pdw, UINT ibitStart, UINT ibitLimit)
  53. {
  54. if (ibitStart >= ibitLimit) return 0;
  55. UINT fMaskLeft, fMaskRight;
  56. int cdwMiddle= ConstructMasks(ibitStart, ibitLimit, &fMaskLeft, &fMaskRight);
  57. pdw += ibitStart >> 5;
  58. ibitStart &= 0x1F;
  59. if (cdwMiddle < 0)
  60. return minui(ibitLimit - ibitStart, Leading0sInDWord(fMaskLeft & *pdw) - ibitStart);
  61. UINT c0s;
  62. UINT ui;
  63. if (fMaskLeft)
  64. {
  65. ui= *pdw++ & fMaskLeft;
  66. if (ui) return Leading0sInDWord(ui) - ibitStart;
  67. else c0s= 32 - ibitStart;
  68. }
  69. else c0s= 0;
  70. while (cdwMiddle--)
  71. {
  72. ui= *pdw++;
  73. if (ui) return Leading0sInDWord(ui) + c0s;
  74. else c0s+= 32;
  75. }
  76. if (fMaskRight)
  77. {
  78. ui= *pdw & fMaskRight;
  79. return minui(ibitLimit & 0x1F, Leading0sInDWord(ui)) + c0s;
  80. }
  81. return c0s;
  82. }