context: // ***************************************************************
  // <copyright file="HashCode.cs" company="Microsoft">
  //      Copyright (C) Microsoft Corporation.  All rights reserved.
  // </copyright>
  // <summary>
  //      ...
  // </summary>
  // ***************************************************************
  
  namespace Microsoft.Exchange.Data.TextConverters
  {
      using System;
  
      internal struct HashCode
      {
          int hash1;
          int hash2;
          int offset;
  
          public HashCode(bool ignore)
          {
              offset = 0;
              hash1 = hash2 = 5381;
          }
  
          public static int CalculateEmptyHash()
          {
              return 5381 + unchecked(5381 * 1566083941);
          }
  
          public static int Calculate(string obj)
          {
              var hash1 = 5381;
              var hash2 = hash1;
  
              unsafe
              {
                  fixed (char* src = obj)
                  {
                      var s = src;
                      var len = obj.Length;
  
                      while (len > 0)
                      {
                          hash1 = ((hash1 << 5) + hash1) ^ s[0];
                          if (len < 2)
                              break;
                          hash2 = ((hash2 << 5) + hash2) ^ s[1];
                          s += 2;
                          len -= 2;
                      }
                  }
              }
  
              return hash1 + (hash2 * 1566083941);
          }
  
  #if !DATAGEN
  
          public static int Calculate(BufferString obj)
          {
              var hash1 = 5381;
              var hash2 = hash1;
  
              unsafe
              {
                  fixed (char* src = obj.Buffer)
                  {
                      var s = src + obj.Offset;
                      var len = obj.Length;
  
                      while (len > 0)
                      {
                          hash1 = ((hash1 << 5) + hash1) ^ s[0];
                          if (len == 1)
                              break;
                          hash2 = ((hash2 << 5) + hash2) ^ s[1];
                          s += 2;
                          len -= 2;
                      }
                  }
              }
  
              return hash1 + (hash2 * 1566083941);
          }
  #endif
          public static int CalculateLowerCase(string obj)
          {
              var hash1 = 5381;
              var hash2 = hash1;
  
              unsafe
              {
                  fixed (char* src = obj)
                  {
                      var s = src;
                      var len = obj.Length;
  
                      while (len > 0)
                      {
                          hash1 = ((hash1 << 5) + hash1) ^ ParseSupport.ToLowerCase(s[0]);
                          if (len == 1)
                              break;
                          hash2 = ((hash2 << 5) + hash2) ^ ParseSupport.ToLowerCase(s[1]);
                          s += 2;
                          len -= 2;
                      }
                  }
              }
  
              return hash1 + (hash2 * 1566083941);
          }
  
  #if !DATAGEN
  
          public static int CalculateLowerCase(BufferString obj)
          {
              var hash1 = 5381;
              var hash2 = hash1;
  
              unsafe
              {
                  fixed (char* src = obj.Buffer)
                  {
                      var s = src + obj.Offset;
                      var len = obj.Length;
  
                      while (len > 0)
                      {
                          hash1 = ((hash1 << 5) + hash1) ^ ParseSupport.ToLowerCase(s[0]);
                          if (len == 1)
                              break;
                          hash2 = ((hash2 << 5) + hash2) ^ ParseSupport.ToLowerCase(s[1]);
                          s += 2;
                          len -= 2;
                      }
                  }
              }
  
              return hash1 + (hash2 * 1566083941);
          }
  #endif
  
          public static int Calculate(char[] buffer, int offset, int length)
          {
              var hash1 = 5381;
              var hash2 = hash1;
  
              CheckArgs(buffer, offset, length);
  
              unsafe
              {
                  fixed (char* src = buffer)
                  {
                      var s = src + offset;
  
                      while (length > 0)
                      {
                          hash1 = ((hash1 << 5) + hash1) ^ s[0];
                          if (length == 1)
                              break;
                          hash2 = ((hash2 << 5) + hash2) ^ s[1];
                          s += 2;
                          length -= 2;
                      }
                  }
              }
  
              return hash1 + (hash2 * 1566083941);
          }
  
          public static int CalculateLowerCase(char[] buffer, int offset, int length)
          {
              var hash1 = 5381;
              var hash2 = hash1;
  
              CheckArgs(buffer, offset, length);
  
              unsafe
              {
                  fixed (char* src = buffer)
                  {
                      var s = src + offset;
  
                      while (length > 0)
                      {
                          hash1 = ((hash1 << 5) + hash1) ^ ParseSupport.ToLowerCase(s[0]);
                          if (length == 1)
                              break;
                          hash2 = ((hash2 << 5) + hash2) ^ ParseSupport.ToLowerCase(s[1]);
                          s += 2;
                          length -= 2;
                      }
                  }
              }
  
              return hash1 + (hash2 * 1566083941);
          }
  
          public void Initialize()
          {
              offset = 0;
              hash1 = hash2 = 5381;
          }
  
          public unsafe void Advance(char* s, int len)
          {
              if (0 != (offset & 1))
              {
                  hash2 = ((hash2 << 5) + hash2) ^ s[0];
                  s++;
                  len--;
                  offset++;
              }
  
              offset += len;
  
              while (len > 0)
              {
                  hash1 = ((hash1 << 5) + hash1) ^ s[0];
                  if (len == 1)
                      break;
                  hash2 = ((hash2 << 5) + hash2) ^ s[1];
                  s += 2;
                  len -= 2;
              }
          }
  
          public unsafe void AdvanceLowerCase(char* s, int len)
          {
              if (0 != (offset & 1))
              {
                  hash2 = ((hash2 << 5) + hash2) ^ ParseSupport.ToLowerCase(s[0]);
                  s++;
                  len--;
                  offset++;
              }
  
              offset += len;
  
              while (len > 0)
              {
                  hash1 = ((hash1 << 5) + hash1) ^ ParseSupport.ToLowerCase(s[0]);
                  if (len == 1)
                      break;
  
gt:                 hash2 = ((hash2 << 5) + hash2) ^ ParseSupport.ToLowerCase(s[1]);