module Cannon
  module Rpc
    # Helper macros
    module Macro
      # Implements the "djb2" hashing algorithm, based on
      # http://www.cse.yorku.ca/~oz/hash.html
      macro hash(string)
        begin
          %h = 5381u32
          {% for c in string.downcase.split("").map do |c|
              {
                " " => 32u32, "!" => 33u32, "\"" => 34u32, "#" => 35u32,
                "$" => 36u32, "%" => 37u32, "&" => 38u32, "'" => 39u32,
                "(" => 40u32, ")" => 41u32, "*" => 42u32, "+" => 43u32,
                "," => 44u32, "-" => 45u32, "." => 46u32, "/" => 47u32,
                "0" => 48u32, "1" => 49u32, "2" => 50u32, "3" => 51u32,
                "4" => 52u32, "5" => 53u32, "6" => 54u32, "7" => 55u32,
                "8" => 56u32, "9" => 57u32,
                ":" => 58u32, ";" => 59u32, "<" => 60u32, "=" => 61u32,
                ">" => 62u32, "?" => 63u32, "@" => 64u32,
                "A" => 65u32, "B" => 66u32, "C" => 67u32, "D" => 68u32,
                "E" => 69u32, "F" => 70u32, "G" => 71u32, "H" => 72u32,
                "I" => 73u32, "J" => 74u32, "K" => 75u32, "L" => 76u32,
                "M" => 77u32, "N" => 78u32, "O" => 79u32, "P" => 80u32,
                "Q" => 81u32, "R" => 82u32, "S" => 83u32, "T" => 84u32,
                "U" => 85u32, "V" => 86u32, "W" => 87u32, "X" => 88u32,
                "Y" => 89u32, "Z" => 90u32,
                "[" => 91u32, "\\" => 92u32, "]" => 93u32, "^" => 94u32,
                "_" => 95u32, "`" => 96u32,
                "a" => 97u32, "b" => 98u32, "c" => 99u32, "d" => 100u32,
                "e" => 101u32, "f" => 102u32, "g" => 103u32, "h" => 104u32,
                "i" => 105u32, "j" => 106u32, "k" => 107u32, "l" => 108u32,
                "m" => 109u32, "n" => 110u32, "o" => 111u32, "p" => 112u32,
                "q" => 113u32, "r" => 114u32, "s" => 115u32, "t" => 116u32,
                "u" => 117u32, "v" => 118u32, "w" => 119u32, "x" => 120u32,
                "y" => 121u32, "z" => 122u32,
                "{" => 123u32, "|" => 124u32, "}" => 125u32, "~" => 126u32,
              }[c]
            end %}
            %h = ((%h << 5) + %h) + {{ c }}
          {% end %}
          %h
        end
      end
    end
  end
end
