int bencode_recursive(OutIt& out, const entry& e) { int ret = 0; switch(e.type()) { case entry::int_t: write_char(out, 'i'); ret += write_integer(out, e.integer()); write_char(out, 'e'); ret += 2; break; case entry::string_t: ret += write_integer(out, e.string().length()); write_char(out, ':'); ret += write_string(e.string(), out); ret += 1; break; case entry::list_t: write_char(out, 'l'); for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) ret += bencode_recursive(out, *i); write_char(out, 'e'); ret += 2; break; case entry::dictionary_t: write_char(out, 'd'); for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) { // write key ret += write_integer(out, i->first.length()); write_char(out, ':'); ret += write_string(i->first, out); // write value ret += bencode_recursive(out, i->second); ret += 1; } write_char(out, 'e'); ret += 2; break; case entry::preformatted_t: std::copy(e.preformatted().begin(), e.preformatted().end(), out); ret += int(e.preformatted().size()); break; case entry::undefined_t: // empty string write_char(out, '0'); write_char(out, ':'); ret += 2; break; } return ret; }
int bencode_recursive(OutIt& out, const entry& e) { int ret = 0; switch(e.type()) { case entry::int_t: write_char(out, 'i'); ret += write_integer(out, e.integer()); write_char(out, 'e'); ret += 2; break; case entry::string_t: ret += write_integer(out, e.string().length()); write_char(out, ':'); ret += write_string(e.string(), out); ret += 1; break; case entry::list_t: write_char(out, 'l'); for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) ret += bencode_recursive(out, *i); write_char(out, 'e'); ret += 2; break; case entry::dictionary_t: write_char(out, 'd'); for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) { // write key ret += write_integer(out, i->first.length()); write_char(out, ':'); ret += write_string(i->first, out); // write value ret += bencode_recursive(out, i->second); ret += 1; } write_char(out, 'e'); ret += 2; break; case entry::undefined_t: // trying to encode a structure with uninitialized values! // TORRENT_ASSERT_VAL(false, e.type()); // do nothing break; } return ret; }
void entry::copy(entry const& e) { switch (e.type()) { case int_t: new (&data) integer_type(e.integer()); break; case string_t: new (&data) string_type(e.string()); break; case list_t: new (&data) list_type(e.list()); break; case dictionary_t: new (&data) dictionary_type(e.dict()); break; case undefined_t: TORRENT_ASSERT(e.type() == undefined_t); break; case preformatted_t: new (&data) preformatted_type(e.preformatted()); break; } m_type = e.type(); #if TORRENT_USE_ASSERTS m_type_queried = true; #endif }
int bencode_recursive(OutIt& out, const entry& e) { int ret = 0; switch(e.type()) { case entry::int_t: write_char(out, 'i'); ret += write_integer(out, e.integer()); write_char(out, 'e'); ret += 2; break; case entry::string_t: ret += write_integer(out, e.string().length()); write_char(out, ':'); ret += write_string(out, e.string()); ret += 1; break; case entry::list_t: write_char(out, 'l'); for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) ret += bencode_recursive(out, *i); write_char(out, 'e'); ret += 2; break; case entry::dictionary_t: write_char(out, 'd'); for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) { // write key ret += write_integer(out, i->first.length()); write_char(out, ':'); ret += write_string(out, i->first); // write value ret += bencode_recursive(out, i->second); ret += 1; } write_char(out, 'e'); ret += 2; break; default: // do nothing break; } return ret; }
void bencode_recursive(OutIt& out, const entry& e) { switch(e.type()) { case entry::int_t: write_char(out, 'i'); write_integer(out, e.integer()); write_char(out, 'e'); break; case entry::string_t: write_integer(out, e.string().length()); write_char(out, ':'); write_string(out, e.string()); break; case entry::list_t: write_char(out, 'l'); for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) bencode_recursive(out, *i); write_char(out, 'e'); break; case entry::dictionary_t: write_char(out, 'd'); for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) { // write key write_integer(out, i->first.length()); write_char(out, ':'); write_string(out, i->first); // write value bencode_recursive(out, i->second); } write_char(out, 'e'); break; default: throw invalid_encoding(); } }
static object convert0(entry const& e) { switch (e.type()) { case entry::int_t: return object(e.integer()); case entry::string_t: return object(e.string()); case entry::list_t: return convert(e.list()); case entry::dictionary_t: return convert(e.dict()); default: return object(); } }
bool entry::operator==(entry const& e) const { if (m_type != e.m_type) return false; switch(m_type) { case int_t: return integer() == e.integer(); case string_t: return string() == e.string(); case list_t: return list() == e.list(); case dictionary_t: return dict() == e.dict(); default: assert(m_type == undefined_t); return true; } }
bool entry::operator==(entry const& e) const { if (type() != e.type()) return false; switch (m_type) { case int_t: return integer() == e.integer(); case string_t: return string() == e.string(); case list_t: return list() == e.list(); case dictionary_t: return dict() == e.dict(); case preformatted_t: return preformatted() == e.preformatted(); default: TORRENT_ASSERT(m_type == undefined_t); return true; } }
void entry::copy(const entry& e) { m_type = e.m_type; switch(m_type) { case int_t: new(data) integer_type(e.integer()); break; case string_t: new(data) string_type(e.string()); break; case list_t: new(data) list_type(e.list()); break; case dictionary_t: new (data) dictionary_type(e.dict()); break; default: m_type = undefined_t; } }
Value entryToJson(const entry &e) { Array lst; Object o; switch( e.type() ) { case entry::int_t: return e.integer(); case entry::string_t: return e.string(); case entry::list_t: for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) { lst.push_back( entryToJson(*i) ); } return lst; case entry::dictionary_t: for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) { o.push_back(Pair(i->first, entryToJson(i->second))); } return o; default: return string("<uninitialized>"); } }
void entry::copy(entry const& e) { switch (e.type()) { case int_t: new(data) integer_type(e.integer()); break; case string_t: new(data) string_type(e.string()); break; case list_t: new(data) list_type(e.list()); break; case dictionary_t: new (data) dictionary_type(e.dict()); break; default: TORRENT_ASSERT(e.type() == undefined_t); } m_type = e.type(); #ifdef TORRENT_DEBUG m_type_queried = true; #endif }
void bdecode_recursive(InIt& in, InIt end, entry& ret) { if (in == end) throw invalid_encoding(); switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e'); assert(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); ret.integer() = boost::lexical_cast<entry::integer_type>(val); } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e); if (in == end) throw invalid_encoding(); } assert(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key); entry& e = ret[key.string()]; bdecode_recursive(in, end, e); if (in == end) throw invalid_encoding(); } assert(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (isdigit(*in)) { std::string len_s = read_until(in, end, ':'); assert(*in == ':'); ++in; // ':' int len = std::atoi(len_s.c_str()); ret = entry(entry::string_t); ret.string() = read_string(in, end, len); } else { throw invalid_encoding(); } } }
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth) { if (depth >= 100) { err = true; return; } if (in == end) { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e', err); if (err) return; TORRENT_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); char* end_pointer; ret.integer() = strtoll(val.c_str(), &end_pointer, 10); #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif if (end_pointer == val.c_str()) { err = true; return; } } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e, err, depth + 1); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } if (in == end) { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } } #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key, err, depth + 1); if (err || key.type() != entry::string_t) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } entry& e = ret[key.string()]; bdecode_recursive(in, end, e, err, depth + 1); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } if (in == end) { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } } #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (is_digit(boost::uint8_t(*in))) { std::string len_s = read_until(in, end, ':', err); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } TORRENT_ASSERT(*in == ':'); ++in; // ':' int len = atoi(len_s.c_str()); ret = entry(entry::string_t); read_string(in, end, len, ret.string(), err); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } } else { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif } }
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth) { if (depth >= 100) { err = true; return; } if (in == end) { err = true; return; } switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e', err); if (err) return; TORRENT_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); ret.integer() = boost::lexical_cast<entry::integer_type>(val); } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e, err, depth + 1); if (err) return; if (in == end) { err = true; return; } } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key, err, depth + 1); if (err) return; entry& e = ret[key.string()]; bdecode_recursive(in, end, e, err, depth + 1); if (err) return; if (in == end) { err = true; return; } } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (isdigit((unsigned char)*in)) { std::string len_s = read_until(in, end, ':', err); if (err) return; TORRENT_ASSERT(*in == ':'); ++in; // ':' int len = std::atoi(len_s.c_str()); ret = entry(entry::string_t); read_string(in, end, len, ret.string(), err); if (err) return; } else { err = true; return; } } }
void wx_entry_print(entry e, int depth) { wxString padding(wxT("")); switch(e.type()) { case entry::int_t: wxLogMessage(wxT("print:")+padding.Pad(depth, '\t')+wxString::Format(_T("int: %u"), e.integer())); break; case entry::string_t: wxLogMessage(wxT("print:")+padding.Pad(depth, '\t')+wxString::Format(wxT("str-len: %u "), e.string().length())+wxT("str: ")+wxString(e.string().c_str(), wxConvUTF8)); break; case entry::list_t: for (entry::list_type::const_iterator i = e.list().begin(); i != e.list().end(); ++i) { wx_entry_print(*i, depth+1); } break; case entry::dictionary_t: for (entry::dictionary_type::const_iterator i = e.dict().begin(); i != e.dict().end(); ++i) { wx_entry_print(i->first, depth+1);// write key wx_entry_print(i->second, depth+1);// write value } break; default: break; } }
int wx_bdecode(wxFileInputStream &file, wxDataInputStream &data, entry &ret, int depth) { char myByte; wxString padding(wxT("")); if (depth >= 100) { return 0; } if (file.Eof()) { return 0; } switch(file.Peek()) { case 'i': { if (file.Peek() == 'i') data.Read8(); ret = entry(entry::int_t); std::string val = read_until(file, data, 'e'); ret.integer() = boost::lexical_cast<entry::integer_type>(val); if (file.Peek() == 'e') data.Read8(); wxLogMessage(wxT("num: ")+wxString(val.c_str(), wxConvUTF8)); } break; case 'l': { if (file.Peek() == 'l') data.Read8(); ret = entry(entry::list_t); while (file.Peek() != 'e') { ret.list().push_back(entry()); entry& list = ret.list().back(); wx_bdecode(file, data, list, depth + 1); } if (file.Peek() == 'e') data.Read8(); } break; case 'd': { if (file.Peek() == 'd') data.Read8(); ret = entry(entry::dictionary_t); while (file.Peek() != 'e') { entry key; wx_bdecode(file, data, key, depth + 1); if (key.type() != entry::string_t) { return 0; } entry dict; wx_bdecode(file, data, dict, depth + 1); ret.dict().insert(std::pair<std::string, entry>(key.string(), dict)); } if (file.Peek() == 'e') data.Read8(); } break; default: if(isdigit(file.Peek())) { ret = entry(entry::string_t); std::string len_s = read_until(file, data, ':'); if (file.Peek() == ':') data.Read8(); int len = std::atoi(len_s.c_str()); read_string(file, data, len, ret.string()); } else { return 0; } break; }// switch }
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth) { if (depth >= 100) { err = true; return; } if (in == end) { err = true; return; } switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e', err); if (err) return; BOOST_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); char* end_pointer; #if defined WIN32 && !defined _MINGW ret.integer() = _strtoi64(val.c_str(), &end_pointer, 10); #else ret.integer() = strtoll(val.c_str(), &end_pointer, 10); #endif if (end_pointer == val.c_str()) { err = true; return; } } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e, err, depth + 1); if (err) { return; } if (in == end) { err = true; return; } } BOOST_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key, err, depth + 1); if (err || key.type() != entry::string_t) { return; } entry& e = ret[key.string()]; bdecode_recursive(in, end, e, err, depth + 1); if (err) { return; } if (in == end) { err = true; return; } } BOOST_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (is_digit((unsigned char)*in)) { std::string len_s = read_until(in, end, ':', err); if (err) { return; } BOOST_ASSERT(*in == ':'); ++in; // ':' int len = std::atoi(len_s.c_str()); ret = entry(entry::string_t); read_string(in, end, len, ret.string(), err); if (err) { return; } } else { err = true; return; } } }