Back to Site
Loading...
Searching...
No Matches
bencode.h
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <string>
5#include <unordered_map>
6#include <memory>
7#include <variant>
8#include <cstdint>
9
10// Use shared_ptr variant for GCC 11 and lower compatibility
11#ifndef LIBRATS_USE_SHARED_PTR_VARIANT
12#if defined(__GNUC__) && (__GNUC__ <= 11)
13#define LIBRATS_USE_SHARED_PTR_VARIANT 1
14#else
15#define LIBRATS_USE_SHARED_PTR_VARIANT 0
16#endif
17#endif
18
19namespace librats {
20
21// Forward declarations
22class BencodeValue;
23using BencodeDict = std::unordered_map<std::string, BencodeValue>;
24using BencodeList = std::vector<BencodeValue>;
25
34public:
35 enum class Type {
36 Integer,
37 String,
38 List,
40 };
41
42 // Constructors
44 BencodeValue(int64_t value);
45 BencodeValue(const std::string& value);
46 BencodeValue(const char* value);
49
50 // Copy and move constructors
52 BencodeValue(BencodeValue&& other) noexcept;
55
57
58 // Type checking
59 Type get_type() const { return type_; }
60 bool is_integer() const { return type_ == Type::Integer; }
61 bool is_string() const { return type_ == Type::String; }
62 bool is_list() const { return type_ == Type::List; }
63 bool is_dict() const { return type_ == Type::Dictionary; }
64
65 // Value access
66 int64_t as_integer() const;
67 const std::string& as_string() const;
68 const BencodeList& as_list() const;
69 const BencodeDict& as_dict() const;
70
71 // Mutable access
74
75 // Dictionary operations
76 bool has_key(const std::string& key) const;
77 const BencodeValue& operator[](const std::string& key) const;
78 BencodeValue& operator[](const std::string& key);
79
80 // List operations
81 const BencodeValue& operator[](size_t index) const;
82 BencodeValue& operator[](size_t index);
83 void push_back(const BencodeValue& value);
84 size_t size() const;
85
86 // Encoding
87 std::vector<uint8_t> encode() const;
88 std::string encode_string() const;
89
90 // Static creation methods
91 static BencodeValue create_integer(int64_t value);
92 static BencodeValue create_string(const std::string& value);
95
96private:
97 Type type_;
98#if LIBRATS_USE_SHARED_PTR_VARIANT
99 std::variant<int64_t, std::string, std::shared_ptr<BencodeList>, std::shared_ptr<BencodeDict>> value_;
100#else
101 std::variant<int64_t, std::string, BencodeList, BencodeDict> value_;
102#endif
103
104 void encode_to_buffer(std::vector<uint8_t>& buffer) const;
105};
106
111public:
112 static BencodeValue decode(const std::vector<uint8_t>& data);
113 static BencodeValue decode(const std::string& data);
114 static BencodeValue decode(const uint8_t* data, size_t size);
115
116private:
117 const uint8_t* data_;
118 size_t size_;
119 size_t pos_;
120
121 BencodeDecoder(const uint8_t* data, size_t size);
122
123 BencodeValue decode_value();
124 BencodeValue decode_integer();
125 BencodeValue decode_string();
126 BencodeValue decode_list();
127 BencodeValue decode_dict();
128
129 bool has_more() const { return pos_ < size_; }
130 uint8_t current_byte() const;
131 uint8_t consume_byte();
132 std::string consume_string(size_t length);
133};
134
138namespace bencode {
139 BencodeValue decode(const std::vector<uint8_t>& data);
140 BencodeValue decode(const std::string& data);
141 std::vector<uint8_t> encode(const BencodeValue& value);
142 std::string encode_string(const BencodeValue& value);
143}
144
145} // namespace librats
Bencode decoder.
Definition bencode.h:110
static BencodeValue decode(const std::vector< uint8_t > &data)
static BencodeValue decode(const std::string &data)
static BencodeValue decode(const uint8_t *data, size_t size)
Represents a bencoded value which can be:
Definition bencode.h:33
BencodeValue & operator[](size_t index)
Type get_type() const
Definition bencode.h:59
bool is_string() const
Definition bencode.h:61
const BencodeValue & operator[](size_t index) const
static BencodeValue create_dict()
bool has_key(const std::string &key) const
bool is_dict() const
Definition bencode.h:63
const BencodeValue & operator[](const std::string &key) const
BencodeValue(const std::string &value)
static BencodeValue create_string(const std::string &value)
BencodeList & as_list()
std::vector< uint8_t > encode() const
std::string encode_string() const
BencodeValue(const BencodeDict &value)
BencodeDict & as_dict()
static BencodeValue create_list()
BencodeValue(const char *value)
const std::string & as_string() const
BencodeValue & operator=(BencodeValue &&other) noexcept
BencodeValue(const BencodeList &value)
BencodeValue(int64_t value)
BencodeValue & operator=(const BencodeValue &other)
BencodeValue & operator[](const std::string &key)
BencodeValue(const BencodeValue &other)
bool is_list() const
Definition bencode.h:62
const BencodeDict & as_dict() const
size_t size() const
BencodeValue(BencodeValue &&other) noexcept
bool is_integer() const
Definition bencode.h:60
static BencodeValue create_integer(int64_t value)
void push_back(const BencodeValue &value)
int64_t as_integer() const
const BencodeList & as_list() const
std::unordered_map< std::string, BencodeValue > BencodeDict
Definition bencode.h:23
std::vector< BencodeValue > BencodeList
Definition bencode.h:24