1
1
Fork 0
mirror of https://github.com/oxen-io/lokinet synced 2023-12-14 06:53:00 +01:00
lokinet/include/llarp/aligned.hpp

180 lines
2.9 KiB
C++
Raw Normal View History

2018-06-01 16:08:54 +02:00
#ifndef LLARP_ALIGNED_HPP
#define LLARP_ALIGNED_HPP
#include <llarp/bencode.h>
2018-06-01 16:08:54 +02:00
#include <llarp/crypto.h>
#include <sodium.h>
2018-06-01 16:24:58 +02:00
#include <iomanip>
2018-06-01 16:08:54 +02:00
#include <iostream>
2018-06-13 15:18:18 +02:00
#include <llarp/encode.hpp>
#include <llarp/logger.hpp>
2018-06-01 16:08:54 +02:00
namespace llarp
{
/// aligned buffer, sz must be multiple of 8 bytes
template < size_t sz >
struct AlignedBuffer
{
2018-06-13 18:32:34 +02:00
static_assert(sz % 8 == 0, "aligned buffer size is not a multiple of 8");
2018-06-04 19:22:24 +02:00
AlignedBuffer() = default;
2018-06-01 16:08:54 +02:00
2018-06-22 02:25:30 +02:00
AlignedBuffer(const AlignedBuffer& other)
{
for(size_t idx = 0; idx < (sz / 8); ++idx)
2018-07-17 06:37:50 +02:00
l[idx] = other.l[idx];
2018-06-22 02:25:30 +02:00
}
AlignedBuffer(const byte_t* data)
2018-06-01 16:08:54 +02:00
{
for(size_t idx = 0; idx < sz; ++idx)
2018-07-17 06:37:50 +02:00
b[idx] = data[idx];
2018-06-01 16:08:54 +02:00
}
AlignedBuffer&
operator=(const byte_t* data)
2018-06-01 16:08:54 +02:00
{
for(size_t idx = 0; idx < sz; ++idx)
2018-07-17 06:37:50 +02:00
b[idx] = data[idx];
2018-06-01 16:08:54 +02:00
return *this;
}
friend std::ostream&
operator<<(std::ostream& out, const AlignedBuffer& self)
2018-06-01 16:08:54 +02:00
{
2018-06-13 15:18:18 +02:00
char tmp[(1 + sz) * 2] = {0};
return out << HexEncode(self, tmp);
2018-06-01 16:08:54 +02:00
}
bool
operator==(const AlignedBuffer& other) const
{
return memcmp(data(), other.data(), sz) == 0;
}
bool
operator!=(const AlignedBuffer& other) const
{
return !(*this == other);
}
bool
operator<(const AlignedBuffer& other) const
{
return memcmp(l, other.l, sz) < 0;
}
2018-06-01 16:08:54 +02:00
size_t
size() const
{
return sz;
}
size_t
size()
{
return sz;
}
2018-06-14 16:04:42 +02:00
void
Fill(byte_t f)
{
for(size_t idx = 0; idx < sz; ++idx)
2018-07-17 06:37:50 +02:00
b[idx] = f;
2018-06-14 16:04:42 +02:00
}
bool
IsZero() const
{
AlignedBuffer< sz > b;
b.Zero();
return memcmp(l, b.l, sz) == 0;
}
2018-06-14 16:04:42 +02:00
2018-06-01 16:08:54 +02:00
void
Zero()
{
2018-06-14 16:04:42 +02:00
for(size_t idx = 0; idx * 8 < sz; ++idx)
2018-07-17 06:37:50 +02:00
l[idx] = 0;
2018-06-01 16:08:54 +02:00
}
void
Randomize()
{
2018-06-12 18:45:12 +02:00
randombytes(b, sz);
2018-06-01 16:08:54 +02:00
}
byte_t*
data()
{
2018-06-06 14:46:26 +02:00
return &b[0];
2018-06-01 16:08:54 +02:00
}
const byte_t*
data() const
{
2018-06-06 14:46:26 +02:00
return &b[0];
}
uint64_t*
data_l()
{
2018-06-06 14:46:26 +02:00
return &l[0];
2018-06-01 16:08:54 +02:00
}
const uint64_t*
data_l() const
{
2018-06-06 14:46:26 +02:00
return &l[0];
2018-06-01 16:08:54 +02:00
}
operator const byte_t*() const
2018-06-01 16:08:54 +02:00
{
2018-06-06 14:46:26 +02:00
return &b[0];
2018-06-01 16:08:54 +02:00
}
operator byte_t*()
2018-06-01 16:08:54 +02:00
{
2018-06-06 14:46:26 +02:00
return &b[0];
2018-06-01 16:08:54 +02:00
}
bool
BEncode(llarp_buffer_t* buf) const
{
return bencode_write_bytestring(buf, b, sz);
}
bool
BDecode(llarp_buffer_t* buf)
{
llarp_buffer_t strbuf;
if(!bencode_read_string(buf, &strbuf))
return false;
if(strbuf.sz != sz)
{
llarp::LogError("bdecode buffer size missmatch ", strbuf.sz, "!=", sz);
return false;
}
memcpy(b, strbuf.base, sz);
return true;
}
2018-07-19 06:58:39 +02:00
struct Hash
{
size_t
operator()(const AlignedBuffer< sz >& buf) const
{
return *buf.data_l();
}
};
2018-06-14 16:04:42 +02:00
protected:
2018-06-01 16:08:54 +02:00
union {
byte_t b[sz];
uint64_t l[sz / 8];
2018-06-06 14:46:26 +02:00
};
2018-06-01 16:08:54 +02:00
};
2018-06-19 00:03:50 +02:00
} // namespace llarp
2018-06-01 16:08:54 +02:00
#endif