/ libi2pd / Tag.h
Tag.h
  1  /*
  2  * Copyright (c) 2013-2025, The PurpleI2P Project
  3  *
  4  * This file is part of Purple i2pd project and licensed under BSD3
  5  *
  6  * See full license text in LICENSE file at top of project tree
  7  */
  8  
  9  #ifndef TAG_H__
 10  #define TAG_H__
 11  
 12  #include <boost/static_assert.hpp>
 13  #include <string.h>
 14  #include <openssl/rand.h>
 15  #include <string>
 16  #include <string_view>
 17  #include "Base.h"
 18  
 19  namespace i2p 
 20  {
 21  namespace data 
 22  {
 23  	template<size_t sz>
 24  	class Tag
 25  	{
 26  		BOOST_STATIC_ASSERT_MSG(sz % 8 == 0, "Tag size must be multiple of 8 bytes");
 27  
 28  		public:
 29  
 30  			Tag () = default;
 31  			Tag (const uint8_t * buf) { memcpy (m_Buf, buf, sz); }
 32  
 33  			bool operator== (const Tag& other) const { return !memcmp (m_Buf, other.m_Buf, sz); }
 34  			bool operator!= (const Tag& other) const { return !(*this == other); }
 35  			bool operator< (const Tag& other) const { return memcmp (m_Buf, other.m_Buf, sz) < 0; }
 36  
 37  			uint8_t * operator()() { return m_Buf; }
 38  			const uint8_t * operator()() const { return m_Buf; }
 39  
 40  			operator uint8_t * () { return m_Buf; }
 41  			operator const uint8_t * () const { return m_Buf; }
 42  
 43  			const uint8_t * data() const { return m_Buf; }
 44  			const uint64_t * GetLL () const { return ll; }
 45  
 46  			bool IsZero () const
 47  			{
 48  				for (size_t i = 0; i < sz/8; ++i)
 49  					if (ll[i]) return false;
 50  				return true;
 51  			}
 52  
 53  			void Fill(uint8_t c)
 54  			{
 55  				memset(m_Buf, c, sz);
 56  			}
 57  
 58  			void Randomize()
 59  			{
 60  				RAND_bytes(m_Buf, sz);
 61  			}
 62  
 63  			std::string ToBase64 (size_t len = sz) const
 64  			{
 65  				return i2p::data::ByteStreamToBase64 (m_Buf, len);
 66  			}
 67  
 68  			std::string ToBase32 (size_t len = sz) const
 69  			{
 70  				return i2p::data::ByteStreamToBase32 (m_Buf, len);
 71  			}
 72  
 73  			size_t FromBase32 (std::string_view s)
 74  			{
 75  				return i2p::data::Base32ToByteStream (s, m_Buf, sz);
 76  			}
 77  
 78  			size_t FromBase64 (std::string_view s)
 79  			{
 80  				return i2p::data::Base64ToByteStream (s, m_Buf, sz);
 81  			}
 82  
 83  			uint8_t GetBit (int i) const
 84  			{
 85  				int pos = i >> 3; // /8
 86  				if (pos >= (int)sz) return 0;
 87  				return m_Buf[pos] & (0x80 >> (i & 0x07)); 
 88  			}		
 89  		
 90  		private:
 91  
 92  			union // 8 bytes aligned
 93  			{
 94  				uint8_t m_Buf[sz];
 95  				uint64_t ll[sz/8];
 96  			};
 97  	};
 98  } // data
 99  } // i2p
100  
101  namespace std
102  {
103  	// hash for std::unordered_map
104  	template<size_t sz> struct hash<i2p::data::Tag<sz> >
105  	{
106  		size_t operator()(const i2p::data::Tag<sz>& s) const
107  		{
108  			return s.GetLL ()[0];
109  		}
110  	};
111  }
112  
113  #endif /* TAG_H__ */