2010-06-18 14:47:09 +00:00
|
|
|
/* <!-- copyright */
|
|
|
|
/*
|
|
|
|
* aria2 - The high speed download utility
|
|
|
|
*
|
|
|
|
* Copyright (C) 2010 Tatsuhiro Tsujikawa
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*
|
|
|
|
* In addition, as a special exception, the copyright holders give
|
|
|
|
* permission to link the code of portions of this program with the
|
|
|
|
* OpenSSL library under certain conditions as described in each
|
|
|
|
* individual source file, and distribute linked combinations
|
|
|
|
* including the two.
|
|
|
|
* You must obey the GNU General Public License in all respects
|
|
|
|
* for all of the code used other than OpenSSL. If you modify
|
|
|
|
* file(s) with this exception, you may extend this exception to your
|
|
|
|
* version of the file(s), but you are not obligated to do so. If you
|
|
|
|
* do not wish to do so, delete this exception statement from your
|
|
|
|
* version. If you delete this exception statement from all source
|
|
|
|
* files in the program, then also delete it here.
|
|
|
|
*/
|
|
|
|
/* copyright --> */
|
|
|
|
#include "bencode2.h"
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
2010-11-20 09:36:14 +00:00
|
|
|
#include "fmt.h"
|
2010-06-18 14:47:09 +00:00
|
|
|
#include "DlAbortEx.h"
|
2010-12-01 12:26:58 +00:00
|
|
|
#include "error_code.h"
|
2011-08-06 16:43:24 +00:00
|
|
|
#include "BufferedFile.h"
|
2011-11-05 03:01:57 +00:00
|
|
|
#include "util.h"
|
2012-07-26 12:07:10 +00:00
|
|
|
#include "ValueBaseBencodeParser.h"
|
2010-06-18 14:47:09 +00:00
|
|
|
|
|
|
|
namespace aria2 {
|
|
|
|
|
|
|
|
namespace bencode2 {
|
|
|
|
|
2012-07-26 12:07:10 +00:00
|
|
|
SharedHandle<ValueBase> decode(const unsigned char* data, size_t len)
|
2010-06-18 14:47:09 +00:00
|
|
|
{
|
|
|
|
size_t end;
|
2012-07-26 12:07:10 +00:00
|
|
|
return decode(data, len, end);
|
2010-06-18 14:47:09 +00:00
|
|
|
}
|
|
|
|
|
2012-07-26 12:07:10 +00:00
|
|
|
SharedHandle<ValueBase> decode(const std::string& data)
|
2010-06-18 14:47:09 +00:00
|
|
|
{
|
2011-11-05 03:01:57 +00:00
|
|
|
size_t end;
|
2012-07-26 12:07:10 +00:00
|
|
|
return decode(reinterpret_cast<const unsigned char*>(data.c_str()),
|
|
|
|
data.size(), end);
|
2010-06-18 14:47:09 +00:00
|
|
|
}
|
|
|
|
|
2012-07-26 12:07:10 +00:00
|
|
|
SharedHandle<ValueBase> decode(const unsigned char* data, size_t len,
|
|
|
|
size_t& end)
|
2010-06-18 14:47:09 +00:00
|
|
|
{
|
2012-07-26 12:07:10 +00:00
|
|
|
ssize_t error;
|
|
|
|
bittorrent::ValueBaseBencodeParser parser;
|
|
|
|
SharedHandle<ValueBase> res =
|
|
|
|
parser.parseFinal(reinterpret_cast<const char*>(data), len, error);
|
|
|
|
if(error < 0) {
|
|
|
|
throw DL_ABORT_EX2(fmt("Bencode decoding failed: error=%d",
|
|
|
|
static_cast<int>(error)),
|
|
|
|
error_code::BENCODE_PARSE_ERROR);
|
2010-06-18 14:47:09 +00:00
|
|
|
}
|
2012-07-26 12:07:10 +00:00
|
|
|
end = error;
|
|
|
|
return res;
|
2010-06-18 14:47:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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";
|
|
|
|
}
|
|
|
|
|
2011-03-09 14:07:27 +00:00
|
|
|
virtual void visit(const Bool& v) {}
|
|
|
|
virtual void visit(const Null& v) {}
|
|
|
|
|
2010-06-18 14:47:09 +00:00
|
|
|
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<ValueBase>& vlb)
|
|
|
|
{
|
|
|
|
return encode(vlb.get());
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace bencode2
|
|
|
|
|
|
|
|
} // namespace aria2
|