RfcString.cc 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /* RfcString.cc
  2. *
  3. */
  4. #include <stdlib.h>
  5. #include "RfcString.h"
  6. int
  7. RfcString::compare(const RfcString& str, size_t n) const noexcept
  8. {
  9. if (rfc_casecmp != _rfc_casecmp)
  10. return String::compare(str, n);
  11. /* Same string? */
  12. if (cbegin() == str.cbegin() && length() == str.length())
  13. return 0;
  14. if (n == npos)
  15. n = std::max(length(), str.length());
  16. auto s1 = cbegin();
  17. auto s2 = str.cbegin();
  18. /* XXX: std::lexicographical_compare_3way would be nice ... */
  19. int cmp = 0;
  20. while (n > 0 && s1 != cend() && s2 != str.cend()) {
  21. if ((cmp = _rfc_toupper(*s1) - _rfc_toupper(*s2)) != 0)
  22. return cmp;
  23. ++s1;
  24. ++s2;
  25. --n;
  26. }
  27. if (n == 0)
  28. return 0;
  29. else if (s1 != cend())
  30. return 1;
  31. else if (s2 != str.cend())
  32. return -1;
  33. else
  34. return 0;
  35. return _rfc_toupper(*s1) - _rfc_toupper(*s2);
  36. }
  37. size_t
  38. RfcString::hash() const noexcept {
  39. if (my_hash != 0) return my_hash;
  40. if (rfc_casecmp != _rfc_casecmp)
  41. return String::hash();
  42. std::hash<value_type> hasher;
  43. size_t _hash = 5381;
  44. for(size_t i = 0; i < this->length(); ++i)
  45. _hash = ((_hash << 5) + _hash) + hasher(_rfc_toupper(this->data()[i]));
  46. return (my_hash = (_hash & 0x7FFFFFFF));
  47. }