/* */ #include "bencode2.h" #include #include "fmt.h" #include "DlAbortEx.h" #include "error_code.h" #include "BufferedFile.h" #include "util.h" #include "ValueBaseBencodeParser.h" namespace aria2 { namespace bencode2 { std::unique_ptr decode(const unsigned char* data, size_t len) { size_t end; return decode(data, len, end); } std::unique_ptr decode(const std::string& data) { size_t end; return decode(reinterpret_cast(data.c_str()), data.size(), end); } std::unique_ptr decode(const unsigned char* data, size_t len, size_t& end) { ssize_t error; bittorrent::ValueBaseBencodeParser parser; auto res = parser.parseFinal(reinterpret_cast(data), len, error); if (error < 0) { throw DL_ABORT_EX2( fmt("Bencode decoding failed: error=%d", static_cast(error)), error_code::BENCODE_PARSE_ERROR); } end = error; return res; } std::string encode(const ValueBase* vlb) { class BencodeValueBaseVisitor : public ValueBaseVisitor { private: std::ostringstream out_; public: virtual void visit(const String& string) CXX11_OVERRIDE { const std::string& s = string.s(); out_ << s.size() << ":"; out_.write(s.data(), s.size()); } virtual void visit(const Integer& integer) CXX11_OVERRIDE { out_ << "i" << integer.i() << "e"; } virtual void visit(const Bool& v) CXX11_OVERRIDE {} virtual void visit(const Null& v) CXX11_OVERRIDE {} virtual void visit(const List& list) CXX11_OVERRIDE { out_ << "l"; for (const auto& e : list) { e->accept(*this); } out_ << "e"; } virtual void visit(const Dict& dict) CXX11_OVERRIDE { out_ << "d"; for (const auto& e : dict) { auto& key = e.first; out_ << key.size() << ":"; out_.write(key.data(), key.size()); e.second->accept(*this); } out_ << "e"; } std::string getResult() const { return out_.str(); } }; BencodeValueBaseVisitor visitor; vlb->accept(visitor); return visitor.getResult(); } } // namespace bencode2 } // namespace aria2