/* */ #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 { SharedHandle decode(const unsigned char* data, size_t len) { size_t end; return decode(data, len, end); } SharedHandle decode(const std::string& data) { size_t end; return decode(reinterpret_cast(data.c_str()), data.size(), end); } SharedHandle decode(const unsigned char* data, size_t len, size_t& end) { ssize_t error; bittorrent::ValueBaseBencodeParser parser; SharedHandle 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) { const std::string& s = string.s(); out_ << s.size() << ":"; out_.write(s.data(), s.size()); } virtual void visit(const Integer& integer) { out_ << "i" << integer.i() << "e"; } virtual void visit(const Bool& v) {} virtual void visit(const Null& v) {} virtual void visit(const List& list) { out_ << "l"; for(List::ValueType::const_iterator i = list.begin(), eoi = list.end(); i != eoi; ++i){ (*i)->accept(*this); } out_ << "e"; } virtual void visit(const Dict& dict) { out_ << "d"; for(Dict::ValueType::const_iterator i = dict.begin(), eoi = dict.end(); i != eoi; ++i){ const std::string& key = (*i).first; out_ << key.size() << ":"; out_.write(key.data(), key.size()); (*i).second->accept(*this); } out_ << "e"; } std::string getResult() const { return out_.str(); } }; BencodeValueBaseVisitor visitor; vlb->accept(visitor); return visitor.getResult(); } std::string encode(const SharedHandle& vlb) { return encode(vlb.get()); } } // namespace bencode2 } // namespace aria2