void Insert(const void* p,const size_t sz,const char* msg,const char* file,const int line) { if (m_mem.find(p)!=m_mem.end()) ERROR("pointer already in debug memory map"); m_mem[p]=make_pair(sz,string(file) + ":" + tostring(line) + ": " + string(msg)); m_accumulated += sz; ++m_calls; }
void insert(const std::string& name) { struct _stati64 b; if (boost::iequals(base_name(name), "desktop.ini") || boost::iequals(base_name(name), "thumbs.db") || _stati64(name.c_str(), &b)) return; if (g_map.empty()) g_name = base_name(name).c_str(); if (b.st_mode & S_IFDIR) { // name is a directory, so add it's contents WIN32_FIND_DATA finddata; HANDLE findhandle = FindFirstFile((name + "\\*").c_str(), &finddata); if (findhandle != INVALID_HANDLE_VALUE) { do { if (*finddata.cFileName != '.') insert(name + "\\" + finddata.cFileName); } while (FindNextFile(findhandle, &finddata)); FindClose(findhandle); } return; } // don't add empty files if (!b.st_size) return; int id = g_map.empty() ? 0 : g_map.rbegin()->first + 1; t_map_entry& e = g_map[id]; e.name = name; e.size = b.st_size; }
void Dump(const int verbose) const { MESSAGE("Cuda memory dump: allocated:%d bytes=%.1f Mb, accumulated:%.0f bytes=%.1f Mb, calls=%d",size(),size()/1024./1024.,m_accumulated,m_accumulated/1024.0/1024.0,m_calls); if (!verbose) return; for (t_map::const_iterator itt=m_mem.begin();itt!=m_mem.end();++itt){ const size_t base=reinterpret_cast<size_t>(itt->first); string m = "p=" + tostring(base) + ":" + tostring(base+itt->second.first-1) + " s=" + tostring(itt->second.first) + "=" + HumanReadable(itt->second.first) + " msg=" + itt->second.second; MESSAGE(m.c_str()); t_map::const_iterator itt2=itt; ++itt2; if (itt2!=m_mem.end()){ const size_t base2=reinterpret_cast<size_t>(itt2->first); ASSERT_GX(base2>=base+itt->second.first); const size_t v=base2-(base+itt->second.first); if (v>0) { m = "v=" + tostring(v) + " =" + HumanReadable(v); MESSAGE(m.c_str()); } } } }
size_t size() const { size_t sz=0; for(t_map::const_iterator itt=m_mem.begin();itt!=m_mem.end();++itt) sz += itt->second.first; return sz; }
void Remove(const void* p) { t_map::iterator itt=m_mem.find(p); if (itt==m_mem.end()) ERROR("pointer not found in debug memory map"); m_mem.erase(itt); }
void prop_kv_config::g_save(const t_map & data, stream_writer * writer, abort_callback & abort) throw() { try { // Write count writer->write_lendian_t(data.get_count(), abort); for (t_map::const_iterator iter = data.first(); iter.is_valid(); ++iter) { // Write key writer->write_string(iter->m_key, abort); // Write vt writer->write_lendian_t(iter->m_value.vt, abort); // Write value int cbWrite = 0; switch (iter->m_value.vt) { case VT_UI1: case VT_I1: cbWrite = sizeof(BYTE); break; case VT_I2: case VT_UI2: case VT_BOOL: cbWrite = sizeof(short); break; case VT_I4: case VT_UI4: case VT_R4: case VT_INT: case VT_UINT: cbWrite = sizeof(long); break; case VT_I8: case VT_UI8: cbWrite = sizeof(LONGLONG); break; case VT_R8: case VT_CY: case VT_DATE: cbWrite = sizeof(double); break; } if (cbWrite != 0) { writer->write(&iter->m_value.bVal, cbWrite, abort); } else if (iter->m_value.vt == VT_BSTR) { pfc::stringcvt::string_utf8_from_wide conv = iter->m_value.bstrVal; writer->write_string(conv, abort); } } } catch (std::exception &) { } }
void prop_kv_config::g_load(t_map & data, stream_reader * reader, abort_callback & abort) throw() { t_size count; data.remove_all(); try { // Get count reader->read_lendian_t(count, abort); for (t_size i = 0; i < count; ++i) { pfc::string8_fast key; t_val val; VARTYPE vt; int cbRead = 0; // read key reader->read_string(key, abort); // read vtype reader->read_lendian_t(vt, abort); switch (vt) { case VT_UI1: case VT_I1: cbRead = sizeof(BYTE); break; case VT_I2: case VT_UI2: case VT_BOOL: cbRead = sizeof(short); break; case VT_I4: case VT_UI4: case VT_R4: case VT_INT: case VT_UINT: cbRead = sizeof(long); break; case VT_I8: case VT_UI8: cbRead = sizeof(LONGLONG); break; case VT_R8: case VT_CY: case VT_DATE: cbRead = sizeof(double); break; } val.vt = vt; if (cbRead != 0) { reader->read(&val.bVal, cbRead, abort); } else { // Read to bstr pfc::string8_fast str; reader->read_string(str, abort); val.bstrVal = SysAllocString(pfc::stringcvt::string_wide_from_utf8_fast(str)); } data[key] = val; } } catch (std::exception &) { } }
// reads property maps from data files bool get_fileprops(const char* pcFile, t_map& mapProps) { std::ifstream ifstr(pcFile); if(!ifstr) { tl::log_err("Cannot open file \"", pcFile, "\"."); return 0; } std::string strLine; while(std::getline(ifstr, strLine)) { tl::trim(strLine); // only collect lines starting with "#" if(!strLine.size() || strLine[0] != '#') continue; // ignore comments starting with "##" if(strLine.size()>=2 && strLine[0]=='#' && strLine[1]=='#') continue; strLine = strLine.substr(1); std::pair<std::string, std::string> strKeyVal = tl::split_first(strLine, std::string("="), 1); std::string& strKey = strKeyVal.first; std::string& _strVal = strKeyVal.second; if(!strKey.size()) continue; std::vector<t_real> vecHKLE; tl::get_tokens<t_real>(_strVal, std::string(" \t"), vecHKLE); // value & error pair if(_strVal.find("+-") != std::string::npos) { std::pair<std::string, std::string> strValErr = tl::split_first(_strVal, std::string("+-"), 1, 1); std::string& strVal = strValErr.first; std::string& strErr = strValErr.second; //std::cout << strKey << ": " << strVal << ", " << strErr << std::endl; if(strVal.length()) { t_real dVal = tl::str_to_var<t_real>(strVal); t_real dErr = tl::str_to_var<t_real>(strErr); mapProps.insert(t_map::value_type(strKey, {dVal, dErr})); } } // hklE values -> split them, e.g. "scan_dir = 0 0 0 1" -> "scan_dir_h = 0", ... else if(vecHKLE.size()==3 || vecHKLE.size()==4) { std::vector<std::string> vecSuffixes = {"_h", "_k", "_l", "_E"}; std::size_t iNumCoords = std::min(vecSuffixes.size(), vecHKLE.size()); for(std::size_t iCoord=0; iCoord<iNumCoords; ++iCoord) { std::string strNewKey = strKey + vecSuffixes[iCoord]; mapProps.insert(t_map::value_type(strNewKey, {vecHKLE[iCoord], 0.})); } } else { tl::log_warn("Unknown key: \"", strKey, "\"."); continue; } } return 1; }
int main(int argc, char* argv[]) { time_t t = time(NULL); if (argc < 2) { std::cerr << "Usage: " << argv[0] << " <file> <tracker> [--v1]" << std::endl; return 1; } std::string tracker = argc >= 3 ? argv[2] : "udp://localhost:2710"; bool use_merkle = argc >= 4 ? strcmp(argv[3], "--v1") : true; // set to false for a non-merkle torrent insert(argv[1]); // use 1 mbyte pieces by default int cb_piece = 1 << 20; if (!use_merkle) { // find optimal piece size for a non-merkle torrent long long cb_total = 0; for (t_map::const_iterator i = g_map.begin(); i != g_map.end(); i++) cb_total += i->second.size; cb_piece = 256 << 10; while (cb_total / cb_piece > 4 << 10) cb_piece <<= 1; } Cbvalue files; std::string pieces; Cvirtual_binary d; byte* w = d.write_start(cb_piece); for (t_map::const_iterator i = g_map.begin(); i != g_map.end(); i++) { int f = open(i->second.name.c_str(), O_BINARY | O_RDONLY); if (!f) continue; long long cb_f = 0; std::string merkle_hash; int cb_d; if (use_merkle) { // calculate merkle root hash as explained in XBT Make Merkle Tree.cpp typedef std::map<int, std::string> t_map; t_map map; char d[1025]; while (cb_d = read(f, d + 1, 1024)) { if (cb_d < 0) break; *d = 0; std::string h = Csha1(const_memory_range(d, cb_d + 1)).read(); *d = 1; int i; for (i = 0; map.find(i) != map.end(); i++) { memcpy(d + 1, map.find(i)->second.c_str(), 20); memcpy(d + 21, h.c_str(), 20); h = Csha1(const_memory_range(d, 41)).read(); map.erase(i); } map[i] = h; cb_f += cb_d; } *d = 1; while (map.size() > 1) { memcpy(d + 21, map.begin()->second.c_str(), 20); map.erase(map.begin()); memcpy(d + 1, map.begin()->second.c_str(), 20); map.erase(map.begin()); map[0] = Csha1(const_memory_range(d, 41)).read(); } if (!map.empty()) merkle_hash = map.begin()->second; } else { // calculate piece hashes while (cb_d = read(f, w, d.data_end() - w)) { if (cb_d < 0) break; w += cb_d; if (w == d.data_end()) { pieces += Csha1(const_memory_range(d, w - d)).read(); w = d.data_edit(); } cb_f += cb_d; } } close(f); // add file to files key files.l(merkle_hash.empty() ? Cbvalue().d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(i->second.name))) : Cbvalue().d(bts_merkle_hash, merkle_hash).d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(i->second.name)))); } if (w != d) pieces += Csha1(const_memory_range(d, w - d)).read(); Cbvalue info; info.d(bts_piece_length, cb_piece); if (!pieces.empty()) info.d(bts_pieces, pieces); if (g_map.size() == 1) { // single-file torrent if (use_merkle) info.d(bts_merkle_hash, files.l().front().d(bts_merkle_hash)); info.d(bts_length, files.l().front().d(bts_length)); info.d(bts_name, files.l().front().d(bts_path).l().front()); } else { // multi-file torrent info.d(bts_files, files); info.d(bts_name, g_name); } Cbvalue torrent; torrent.d(bts_announce, tracker); torrent.d(bts_info, info); Cvirtual_binary s = torrent.read(); if (use_merkle) s = gzip(s); s.save(g_name + ".torrent"); std::cout << time(NULL) - t << " s" << std::endl; return 0; }