CharacterBuffer.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace JsUtil
  7. {
  8. static const charcount_t MAX_FAST_HASH_LENGTH = 256;
  9. // A buffer of characters, may have embedded null.
  10. template <typename T>
  11. class CharacterBuffer
  12. {
  13. public:
  14. CharacterBuffer() : string(nullptr), len((charcount_t)-1) {}
  15. CharacterBuffer(T const * string, charcount_t len) : string(string), len(len) {}
  16. CharacterBuffer(const CharacterBuffer& other) : string(other.string), len(other.len) {}
  17. bool operator==(CharacterBuffer const& other) const
  18. {
  19. Assert(string != nullptr);
  20. if (this->len != other.len)
  21. {
  22. return false;
  23. }
  24. return this->string == other.string || StaticEquals(string, other.string, this->len);
  25. }
  26. operator hash_t() const
  27. {
  28. Assert(string != nullptr);
  29. return StaticGetHashCode(string, len);
  30. }
  31. hash_t FastHash() const
  32. {
  33. Assert(string != nullptr);
  34. return InternalGetHashCode<true>(string, len);
  35. }
  36. CharacterBuffer& operator=(T const * s)
  37. {
  38. Assert(s == nullptr);
  39. string = nullptr;
  40. len = (charcount_t)-1;
  41. return *this;
  42. }
  43. static bool StaticEquals(__in_z T const * s1, __in_z T const* s2, __in charcount_t length);
  44. static hash_t StaticGetHashCode(__in_z T const * s, __in charcount_t length)
  45. {
  46. return InternalGetHashCode<false>(s, length);
  47. }
  48. template <bool fastHash>
  49. static hash_t InternalGetHashCode(__in_z T const * s, __in charcount_t length)
  50. {
  51. hash_t hash = CC_HASH_OFFSET_VALUE;
  52. charcount_t hashLength = length;
  53. if (fastHash)
  54. {
  55. hashLength = min(length, MAX_FAST_HASH_LENGTH);
  56. }
  57. for (charcount_t i = 0; i < hashLength; i++)
  58. {
  59. CC_HASH_LOGIC(hash, s[i]);
  60. }
  61. return hash;
  62. }
  63. T const * GetBuffer() const { return string; }
  64. charcount_t GetLength() const { return len; }
  65. private:
  66. Field(T const *) string;
  67. Field(charcount_t) len;
  68. };
  69. template<>
  70. inline bool
  71. CharacterBuffer<WCHAR>::StaticEquals(__in_z WCHAR const * s1, __in_z WCHAR const * s2, __in charcount_t length)
  72. {
  73. return (s1 == s2) || wmemcmp(s1, s2, length) == 0;
  74. }
  75. template<>
  76. inline bool
  77. CharacterBuffer<unsigned char>::StaticEquals(__in_z unsigned char const * s1, __in_z unsigned char const *s2, __in charcount_t length)
  78. {
  79. return (s1 == s2) || memcmp(s1, s2, length) == 0;
  80. }
  81. }