Line data Source code
1 : /**
2 : * @file Decoder.h
3 : * @copyright (c) 2014 by Petr Zemek (s3rvac@gmail.com) and contributors
4 : * @license BSD, see the @c LICENSE file for more details
5 : * @brief Decoder of bencoded data.
6 : */
7 :
8 : #ifndef BENCODING_DECODER_H
9 : #define BENCODING_DECODER_H
10 :
11 : #include <exception>
12 : #include <memory>
13 : #include <string>
14 :
15 : #include "BItem.h"
16 :
17 : namespace bencoding {
18 :
19 : class BDictionary;
20 : class BInteger;
21 : class BList;
22 : class BString;
23 :
24 : /**
25 : * @brief Exception thrown when there is an error during the decoding.
26 : */
27 25 : class DecodingError: public std::runtime_error {
28 : public:
29 : explicit DecodingError(const std::string &what);
30 : };
31 :
32 : /**
33 : * @brief Decoder of bencoded data.
34 : *
35 : * The format is based on the <a
36 : * href="https://wiki.theory.org/BitTorrentSpecification#Bencoding">BitTorrent
37 : * specification</a>.
38 : *
39 : * Use create() to create instances.
40 : */
41 : class Decoder {
42 : public:
43 : static std::unique_ptr<Decoder> create();
44 :
45 : std::unique_ptr<BItem> decode(const std::string &data);
46 : std::unique_ptr<BItem> decode(std::istream &input);
47 :
48 : private:
49 : Decoder();
50 :
51 : void readExpectedChar(std::istream &input, char expected_char) const;
52 :
53 : /// @name Integer Decoding
54 : /// @{
55 : std::unique_ptr<BDictionary> decodeDictionary(std::istream &input);
56 : std::unique_ptr<BDictionary> decodeDictionaryItemsIntoDictionary(
57 : std::istream &input);
58 : std::shared_ptr<BString> decodeDictionaryKey(std::istream &input);
59 : std::unique_ptr<BItem> decodeDictionaryValue(std::istream &input);
60 : /// @}
61 :
62 : /// @name Integer Decoding
63 : /// @{
64 : std::unique_ptr<BInteger> decodeInteger(std::istream &input) const;
65 : std::string readEncodedInteger(std::istream &input) const;
66 : std::unique_ptr<BInteger> decodeEncodedInteger(
67 : const std::string &encodedInteger) const;
68 : /// @}
69 :
70 : /// @name List Decoding
71 : /// @{
72 : std::unique_ptr<BList> decodeList(std::istream &input);
73 : std::unique_ptr<BList> decodeListItemsIntoList(std::istream &input);
74 : /// @}
75 :
76 : /// @name String Decoding
77 : /// @{
78 : std::unique_ptr<BString> decodeString(std::istream &input) const;
79 : std::string::size_type readStringLength(std::istream &input) const;
80 : std::string readStringOfGivenLength(std::istream &input,
81 : std::string::size_type length) const;
82 : /// @}
83 :
84 : void validateInputDoesNotContainUndecodedCharacters(std::istream &input);
85 : };
86 :
87 : /// @name Decoding Without Explicit Decoder Creation
88 : /// @{
89 : std::unique_ptr<BItem> decode(const std::string &data);
90 : std::unique_ptr<BItem> decode(std::istream &input);
91 : /// @}
92 :
93 : } // namespace bencoding
94 :
95 : #endif
|