File indexing completed on 2024-05-12 04:56:45
0001 /*************************************************************************** 0002 * Copyright (C) 2013 by Linuxstopmotion contributors; * 0003 * see the AUTHORS file for details. * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 0021 #include "hash.h" 0022 0023 #include <ios> 0024 0025 Hash::Hash() { 0026 h = 5381; 0027 } 0028 0029 void Hash::add(uint64_t n) { 0030 h = h * 33 + n; 0031 } 0032 0033 void Hash::addS(int64_t n) { 0034 add(static_cast<uint64_t>(n)); 0035 } 0036 0037 void Hash::add(const char* string) { 0038 Hash s; 0039 while (*string) { 0040 s.add(static_cast<uint64_t>(*string)); 0041 ++string; 0042 } 0043 add(s); 0044 } 0045 0046 void Hash::add(Hash h) { 0047 add(h.h); 0048 } 0049 0050 void Hash::add(FILE* fh) { 0051 Hash s; 0052 long fpos = ftell(fh); 0053 fseek(fh, 0, SEEK_SET); 0054 char buffer[256]; 0055 size_t r = 0; 0056 while (0 < (r = fread(buffer, 1, sizeof(buffer), fh))) { 0057 for (size_t i = 0; i != r; ++i) 0058 s.add(buffer[i]); 0059 } 0060 if (r == 0) { 0061 if (ferror(fh)) 0062 throw std::ios_base::failure("error reading file for hash"); 0063 } 0064 fseek(fh, fpos, SEEK_SET); 0065 add(s); 0066 } 0067 0068 bool Hash::equals(const Hash& other) const { 0069 return h == other.h; 0070 } 0071 0072 void Hash::appendTo(std::string& out) { 0073 out.reserve(out.length() + 16); 0074 for (int i = 60; i != 0; i -= 4) { 0075 int digit = (h >> i) & 0xF; 0076 if (digit < 10) 0077 out.append(1, '0' + digit); 0078 else 0079 out.append(1, 'A' - 10 + digit); 0080 } 0081 } 0082 0083 bool operator==(const Hash& a, const Hash& b) { 0084 return a.equals(b); 0085 } 0086 0087 bool operator!=(const Hash& a, const Hash& b) { 0088 return !a.equals(b); 0089 } 0090 0091 Hash::Hash(const Hash& other) : h(other.h) { 0092 } 0093 0094 Hash& Hash::operator=(const Hash& other) { 0095 h = other.h; 0096 return *this; 0097 }