+static int computeHash(docstring const & name,
+ docstring const & email)
+{
+ string const full_author_string = to_utf8(name + email);
+ // Bernstein's hash function
+ unsigned int hash = 5381;
+ for (unsigned int i = 0; i < full_author_string.length(); ++i)
+ hash = ((hash << 5) + hash) + (unsigned int)(full_author_string[i]);
+ return int(hash);
+}
+
+
+Author::Author(docstring const & name, docstring const & email, docstring const & initials)
+ : name_(name), email_(email), initials_(initials), used_(true),
+ buffer_id_(computeHash(name, email))
+{}
+
+
+Author::Author(int buffer_id)
+ : name_(convert<docstring>(buffer_id)), email_(docstring()), initials_(docstring()), used_(false),
+ buffer_id_(buffer_id)
+{}
+
+
+docstring Author::nameAndEmail() const
+{
+ if (email().empty())
+ return name();
+ else
+ return bformat(_("%1$s[[name]] (%2$s[[email]])"), name(), email());
+}
+
+
+bool Author::valid() const
+{
+ //this cannot be equal if the buffer_id was produced by the hash function.
+ return name_ != convert<docstring>(buffer_id_);
+}
+