| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- namespace JsUtil
- {
- static const charcount_t MAX_FAST_HASH_LENGTH = 256;
- // A buffer of characters, may have embedded null.
- template <typename T>
- class CharacterBuffer
- {
- public:
- CharacterBuffer() : string(nullptr), len((charcount_t)-1) {}
- CharacterBuffer(T const * string, charcount_t len) : string(string), len(len) {}
- CharacterBuffer(const CharacterBuffer& other) : string(other.string), len(other.len) {}
- bool operator==(CharacterBuffer const& other) const
- {
- Assert(string != nullptr);
- if (this->len != other.len)
- {
- return false;
- }
- return this->string == other.string || StaticEquals(string, other.string, this->len);
- }
- operator hash_t() const
- {
- Assert(string != nullptr);
- return StaticGetHashCode(string, len);
- }
- int FastHash() const
- {
- Assert(string != nullptr);
- return InternalGetHashCode<true>(string, len);
- }
- CharacterBuffer& operator=(T const * s)
- {
- Assert(s == nullptr);
- string = nullptr;
- len = (charcount_t)-1;
- return *this;
- }
- static bool StaticEquals(__in_z T const * s1, __in_z T const* s2, __in charcount_t length);
- static int StaticGetHashCode(__in_z T const * s, __in charcount_t length)
- {
- return InternalGetHashCode<false>(s, length);
- }
- // This must be identical to Trident's getHash function in fastDOMCompiler.pl
- template <bool fastHash>
- static int InternalGetHashCode(__in_z T const * s, __in charcount_t length)
- {
- // TODO: This hash performs poorly on small strings, consider finding a better hash function
- // now that some type handlers hash by string instead of PropertyId.
- int hash = 0;
- charcount_t hashLength = length;
- if (fastHash)
- {
- hashLength = min(length, MAX_FAST_HASH_LENGTH);
- }
- for (charcount_t i = 0; i < hashLength; i++)
- {
- hash = _rotl(hash, 7);
- hash ^= s[i];
- }
- return hash;
- }
- T const * GetBuffer() const { return string; }
- charcount_t GetLength() const { return len; }
- private:
- Field(T const *) string;
- Field(charcount_t) len;
- };
- template<>
- inline bool
- CharacterBuffer<WCHAR>::StaticEquals(__in_z WCHAR const * s1, __in_z WCHAR const * s2, __in charcount_t length)
- {
- return wmemcmp(s1, s2, length) == 0;
- }
- template<>
- inline bool
- CharacterBuffer<unsigned char>::StaticEquals(__in_z unsigned char const * s1, __in_z unsigned char const *s2, __in charcount_t length)
- {
- return memcmp(s1, s2, length) == 0;
- }
- }
|