added some precautionary checks in bdecoder
[libtorrent.git] / include / libtorrent / peer_id.hpp
blob0ec096de369c84955c8850f5554069c0dc739149
1 /*
3 Copyright (c) 2003, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #ifndef TORRENT_PEER_ID_HPP_INCLUDED
34 #define TORRENT_PEER_ID_HPP_INCLUDED
36 #include <iostream>
37 #include <iomanip>
38 #include <cctype>
39 #include <algorithm>
40 #include <string>
41 #include <cstring>
43 #include "libtorrent/config.hpp"
44 #include "libtorrent/assert.hpp"
46 namespace libtorrent
49 class TORRENT_EXPORT big_number
51 // the number of bytes of the number
52 enum { number_size = 20 };
53 public:
54 enum { size = number_size };
56 big_number() {}
58 explicit big_number(char const* s)
60 if (s == 0) clear();
61 else std::memcpy(m_number, s, size);
64 explicit big_number(std::string const& s)
66 TORRENT_ASSERT(s.size() >= 20);
67 int sl = int(s.size()) < size ? int(s.size()) : size;
68 std::memcpy(m_number, &s[0], sl);
71 void clear()
73 std::fill(m_number,m_number+number_size,0);
76 bool is_all_zeros() const
78 return std::count(m_number,m_number+number_size,0) == number_size;
81 bool operator==(big_number const& n) const
83 return std::equal(n.m_number, n.m_number+number_size, m_number);
86 bool operator!=(big_number const& n) const
88 return !std::equal(n.m_number, n.m_number+number_size, m_number);
91 bool operator<(big_number const& n) const
93 for (int i = 0; i < number_size; ++i)
95 if (m_number[i] < n.m_number[i]) return true;
96 if (m_number[i] > n.m_number[i]) return false;
98 return false;
101 big_number operator~()
103 big_number ret;
104 for (int i = 0; i< number_size; ++i)
105 ret.m_number[i] = ~m_number[i];
106 return ret;
109 big_number& operator &= (big_number const& n)
111 for (int i = 0; i< number_size; ++i)
112 m_number[i] &= n.m_number[i];
113 return *this;
116 big_number& operator |= (big_number const& n)
118 for (int i = 0; i< number_size; ++i)
119 m_number[i] |= n.m_number[i];
120 return *this;
123 big_number& operator ^= (big_number const& n)
125 for (int i = 0; i< number_size; ++i)
126 m_number[i] ^= n.m_number[i];
127 return *this;
130 unsigned char& operator[](int i)
131 { TORRENT_ASSERT(i >= 0 && i < number_size); return m_number[i]; }
133 unsigned char const& operator[](int i) const
134 { TORRENT_ASSERT(i >= 0 && i < number_size); return m_number[i]; }
136 typedef const unsigned char* const_iterator;
137 typedef unsigned char* iterator;
139 const_iterator begin() const { return m_number; }
140 const_iterator end() const { return m_number+number_size; }
142 iterator begin() { return m_number; }
143 iterator end() { return m_number+number_size; }
145 std::string to_string() const
146 { return std::string((char const*)&m_number[0], number_size); }
148 private:
150 unsigned char m_number[number_size];
154 typedef big_number peer_id;
155 typedef big_number sha1_hash;
157 inline std::ostream& operator<<(std::ostream& os, big_number const& peer)
159 for (big_number::const_iterator i = peer.begin();
160 i != peer.end(); ++i)
162 os << std::hex << std::setw(2) << std::setfill('0')
163 << static_cast<unsigned int>(*i);
165 os << std::dec << std::setfill(' ');
166 return os;
169 inline std::istream& operator>>(std::istream& is, big_number& peer)
171 using namespace std;
173 for (big_number::iterator i = peer.begin();
174 i != peer.end(); ++i)
176 char c[2];
177 is >> c[0] >> c[1];
178 c[0] = tolower(c[0]);
179 c[1] = tolower(c[1]);
180 if (
181 ((c[0] < '0' || c[0] > '9') && (c[0] < 'a' || c[0] > 'f'))
182 || ((c[1] < '0' || c[1] > '9') && (c[1] < 'a' || c[1] > 'f'))
183 || is.fail())
185 is.setstate(ios_base::failbit);
186 return is;
188 *i = ((isdigit(c[0])?c[0]-'0':c[0]-'a'+10) << 4)
189 + (isdigit(c[1])?c[1]-'0':c[1]-'a'+10);
191 return is;
196 #endif // TORRENT_PEER_ID_HPP_INCLUDED