use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.
the class GlobalManagerImpl method getDMAdapter.
protected DownloadManagerInitialisationAdapter getDMAdapter(DownloadManagerInitialisationAdapter adapter) {
List<DownloadManagerInitialisationAdapter> adapters = dm_adapters.getList();
adapters = new ArrayList(adapters);
if (adapter != null) {
adapters.add(adapter);
}
List<DownloadManagerInitialisationAdapter> tag_assigners = new ArrayList<>();
List<DownloadManagerInitialisationAdapter> tag_processors = new ArrayList<>();
for (DownloadManagerInitialisationAdapter a : adapters) {
int actions = a.getActions();
if ((actions & DownloadManagerInitialisationAdapter.ACT_ASSIGNS_TAGS) != 0) {
tag_assigners.add(a);
}
if ((actions & DownloadManagerInitialisationAdapter.ACT_PROCESSES_TAGS) != 0) {
tag_processors.add(a);
}
}
if (tag_assigners.size() > 0 && tag_processors.size() > 0) {
for (DownloadManagerInitialisationAdapter a : tag_processors) {
adapters.remove(a);
}
int pos = adapters.indexOf(tag_assigners.get(tag_assigners.size() - 1));
for (DownloadManagerInitialisationAdapter a : tag_processors) {
adapters.add(++pos, a);
}
}
final List<DownloadManagerInitialisationAdapter> f_adapters = adapters;
return (new DownloadManagerInitialisationAdapter() {
@Override
public int getActions() {
// not relevant this is
return (ACT_NONE);
}
@Override
public void initialised(DownloadManager manager, boolean for_seeding) {
for (int i = 0; i < f_adapters.size(); i++) {
try {
f_adapters.get(i).initialised(manager, for_seeding);
} catch (Throwable e) {
Debug.printStackTrace(e);
}
}
if (Constants.isOSX) {
fixLongFileName(manager);
}
if (COConfigurationManager.getBooleanParameter("Rename Incomplete Files")) {
String ext = COConfigurationManager.getStringParameter("Rename Incomplete Files Extension").trim();
boolean use_prefix = COConfigurationManager.getBooleanParameter("Use Incomplete File Prefix");
DownloadManagerState state = manager.getDownloadState();
String existing_ext = state.getAttribute(DownloadManagerState.AT_INCOMP_FILE_SUFFIX);
if (ext.length() > 0 && existing_ext == null) {
DiskManagerFileInfo[] fileInfos = manager.getDiskManagerFileInfo();
if (fileInfos.length <= DownloadManagerStateFactory.MAX_FILES_FOR_INCOMPLETE_AND_DND_LINKAGE) {
ext = FileUtil.convertOSSpecificChars(ext, false);
String prefix = "";
if (use_prefix) {
try {
prefix = Base32.encode(manager.getTorrent().getHash()).substring(0, 12).toLowerCase(Locale.US) + "_";
} catch (Throwable e) {
}
}
try {
state.suppressStateSave(true);
List<Integer> from_indexes = new ArrayList<>();
List<File> from_links = new ArrayList<>();
List<File> to_links = new ArrayList<>();
for (int i = 0; i < fileInfos.length; i++) {
DiskManagerFileInfo fileInfo = fileInfos[i];
File base_file = fileInfo.getFile(false);
File existing_link = state.getFileLink(i, base_file);
if (existing_link == null && base_file.exists()) {
// file already exists, do nothing as probably adding for seeding
} else if (existing_link == null || !existing_link.exists()) {
File new_link;
if (existing_link == null) {
new_link = new File(base_file.getParentFile(), prefix + base_file.getName() + ext);
} else {
String link_name = existing_link.getName();
if (!link_name.startsWith(prefix)) {
link_name = prefix + link_name;
}
new_link = new File(existing_link.getParentFile(), link_name + ext);
}
from_indexes.add(i);
from_links.add(base_file);
to_links.add(new_link);
}
}
if (from_links.size() > 0) {
state.setFileLinks(from_indexes, from_links, to_links);
}
} finally {
state.setAttribute(DownloadManagerState.AT_INCOMP_FILE_SUFFIX, ext);
if (use_prefix) {
state.setAttribute(DownloadManagerState.AT_DND_PREFIX, prefix);
}
state.suppressStateSave(false);
}
}
}
}
}
});
}
use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.
the class DownloadManagerStatsImpl method recalcDownloadCompleteBytes.
@Override
public void recalcDownloadCompleteBytes() {
DiskManager dm = getDiskManagerIfNotTransient();
if (dm != null) {
long total = dm.getTotalLength();
saved_completed_download_bytes = total - dm.getRemaining();
}
if (saved_completed_download_bytes < 0) {
// recalc
DiskManagerFileInfo[] files = download_manager.getDiskManagerFileInfoSet().getFiles();
long total_size = 0;
for (DiskManagerFileInfo file : files) {
total_size += file.getDownloaded();
}
saved_completed_download_bytes = total_size;
}
}
use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.
the class EnhancedDownloadManager method getContiguousAvailableBytes.
public long getContiguousAvailableBytes(int file_index, long file_start_offset, long stop_counting_after) {
if (file_index < 0 || file_index >= enhanced_files.length) {
return (-1);
}
EnhancedDownloadManagerFile efile = enhanced_files[file_index];
DiskManagerFileInfo file = efile.getFile();
DiskManager dm = download_manager.getDiskManager();
if (dm == null) {
if (file.getDownloaded() == file.getLength()) {
return (file.getLength() - file_start_offset);
}
return (-1);
}
int piece_size = dm.getPieceLength();
long start_index = efile.getByteOffestInTorrent() + file_start_offset;
int first_piece_index = (int) (start_index / piece_size);
int first_piece_offset = (int) (start_index % piece_size);
int last_piece_index = file.getLastPieceNumber();
DiskManagerPiece[] pieces = dm.getPieces();
DiskManagerPiece first_piece = pieces[first_piece_index];
long available = 0;
if (!first_piece.isDone()) {
boolean[] blocks = first_piece.getWritten();
if (blocks == null) {
if (first_piece.isDone()) {
available = first_piece.getLength() - first_piece_offset;
}
} else {
int piece_offset = 0;
for (int j = 0; j < blocks.length; j++) {
if (blocks[j]) {
int block_size = first_piece.getBlockSize(j);
piece_offset = piece_offset + block_size;
if (available == 0) {
if (piece_offset > first_piece_offset) {
available = piece_offset - first_piece_offset;
}
} else {
available += block_size;
}
} else {
break;
}
}
}
} else {
available = first_piece.getLength() - first_piece_offset;
for (int i = first_piece_index + 1; i <= last_piece_index; i++) {
if (stop_counting_after > 0 && available >= stop_counting_after) {
break;
}
DiskManagerPiece piece = pieces[i];
if (piece.isDone()) {
available += piece.getLength();
} else {
boolean[] blocks = piece.getWritten();
if (blocks == null) {
if (piece.isDone()) {
available += piece.getLength();
} else {
break;
}
} else {
for (int j = 0; j < blocks.length; j++) {
if (blocks[j]) {
available += piece.getBlockSize(j);
} else {
break;
}
}
}
break;
}
}
}
long max_available = file.getLength() - file_start_offset;
if (available > max_available) {
available = max_available;
}
return (available);
}
use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.
the class HTTPNetworkConnectionFile method decodeHeader.
@Override
protected void decodeHeader(HTTPMessageDecoder decoder, final String header) throws IOException {
if (switching) {
Debug.out("new header received while paused");
throw (new IOException("Bork"));
}
if (!isSeed()) {
return;
}
PEPeerControl control = getPeerControl();
DiskManager dm = control.getDiskManager();
if (dm == null) {
Debug.out("Disk manager is null");
throw (new IOException("Disk manager unavailable"));
}
TOTorrent to_torrent = dm.getTorrent();
char[] chars = header.toCharArray();
int last_pos = 0;
int line_num = 0;
String target_str = null;
DiskManagerFileInfo target_file = null;
long file_offset = 0;
List<long[]> ranges = new ArrayList<>();
boolean keep_alive = false;
for (int i = 1; i < chars.length; i++) {
if (chars[i - 1] == '\r' && chars[i] == '\n') {
String line = new String(chars, last_pos, i - last_pos).trim();
last_pos = i;
line_num++;
if (line_num == 1) {
line = line.substring(line.indexOf("files/") + 6);
int hash_end = line.indexOf("/");
final byte[] old_hash = control.getHash();
final byte[] new_hash = URLDecoder.decode(line.substring(0, hash_end), "ISO-8859-1").getBytes("ISO-8859-1");
if (!Arrays.equals(new_hash, old_hash)) {
switching = true;
decoder.pauseInternally();
flushRequests(new flushListener() {
private boolean triggered;
@Override
public void flushed() {
synchronized (this) {
if (triggered) {
return;
}
triggered = true;
}
getManager().reRoute(HTTPNetworkConnectionFile.this, old_hash, new_hash, header);
}
});
return;
}
line = line.substring(hash_end + 1);
line = line.substring(0, line.lastIndexOf(' '));
String file = line;
if (to_torrent.isSimpleTorrent()) {
// optimise for simple torrents. also support the case where
// client has the hash but doesn't know the file name
target_file = dm.getFiles()[0];
} else {
target_str = file;
StringTokenizer tok = new StringTokenizer(file, "/");
List<byte[]> bits = new ArrayList<>();
while (tok.hasMoreTokens()) {
bits.add(URLDecoder.decode(tok.nextToken(), "ISO-8859-1").getBytes("ISO-8859-1"));
}
if (!to_torrent.isSimpleTorrent() && bits.size() > 1) {
if (Arrays.equals(to_torrent.getName(), (byte[]) bits.get(0))) {
bits.remove(0);
}
}
DiskManagerFileInfo[] files = dm.getFiles();
file_offset = 0;
for (int j = 0; j < files.length; j++) {
TOTorrentFile torrent_file = files[j].getTorrentFile();
byte[][] comps = torrent_file.getPathComponents();
if (comps.length == bits.size()) {
boolean match = true;
for (int k = 0; k < comps.length; k++) {
if (!Arrays.equals(comps[k], (byte[]) bits.get(k))) {
match = false;
break;
}
}
if (match) {
target_file = files[j];
break;
}
}
file_offset += torrent_file.getLength();
}
}
} else {
line = line.toLowerCase(MessageText.LOCALE_ENGLISH);
if (line.startsWith("range") && target_file != null) {
line = line.substring(5).trim();
if (line.startsWith(":")) {
String range_str = line.substring(1).trim();
if (range_str.startsWith("bytes=")) {
long file_length = target_file.getLength();
StringTokenizer tok2 = new StringTokenizer(range_str.substring(6), ",");
while (tok2.hasMoreTokens()) {
String range = tok2.nextToken();
try {
int pos = range.indexOf('-');
if (pos != -1) {
String lhs = range.substring(0, pos);
String rhs = range.substring(pos + 1);
long start;
long end;
if (lhs.length() == 0) {
// -222 is last 222 bytes of file
end = file_length - 1;
start = file_length - Long.parseLong(rhs);
} else if (rhs.length() == 0) {
end = file_length - 1;
start = Long.parseLong(lhs);
} else {
start = Long.parseLong(lhs);
end = Long.parseLong(rhs);
}
ranges.add(new long[] { start, end });
}
} catch (Throwable e) {
}
}
}
if (ranges.size() == 0) {
log("Invalid range specification: '" + line + "'");
sendAndClose(getManager().getRangeNotSatisfiable());
return;
}
}
} else if (line.contains("keep-alive")) {
keep_alive = true;
}
}
}
}
if (target_file == null) {
log("Failed to find file '" + target_str + "'");
sendAndClose(getManager().getNotFound());
return;
}
try {
String name = target_file.getFile(true).getName();
int pos = name.lastIndexOf(".");
if (pos != -1) {
setContentType(HTTPUtils.guessContentTypeFromFileType(name.substring(pos + 1)));
}
} catch (Throwable e) {
}
long file_length = target_file.getLength();
boolean partial_content = ranges.size() > 0;
if (!partial_content) {
ranges.add(new long[] { 0, file_length - 1 });
}
long[] offsets = new long[ranges.size()];
long[] lengths = new long[ranges.size()];
for (int i = 0; i < ranges.size(); i++) {
long[] range = (long[]) ranges.get(i);
long start = range[0];
long end = range[1];
if (start < 0 || start >= file_length || end < 0 || end >= file_length || start > end) {
log("Invalid range specification: '" + start + "-" + end + "'");
sendAndClose(getManager().getRangeNotSatisfiable());
return;
}
offsets[i] = file_offset + start;
lengths[i] = (end - start) + 1;
}
addRequest(new httpRequest(offsets, lengths, file_length, partial_content, keep_alive));
}
use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.
the class StatsWriterImpl method writeSupport.
protected void writeSupport() {
writeLineRaw("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
boolean export_peer_stats = COConfigurationManager.getBooleanParameter("Stats Export Peer Details");
boolean export_file_stats = COConfigurationManager.getBooleanParameter("Stats Export File Details");
String xsl = COConfigurationManager.getStringParameter("Stats XSL File");
if (xsl.length() > 0) {
writeLineRaw("<?xml-stylesheet type=\"text/xsl\" href=\"" + xsl + "\"?>");
}
writeLineRaw("<STATS>");
GlobalManager global = core.getGlobalManager();
try {
indent();
writeTag("AZUREUS_VERSION", Constants.AZUREUS_VERSION);
writeLineRaw("<GLOBAL>");
try {
indent();
GlobalManagerStats gm_stats = global.getStats();
writeRawCookedAverageTag("DOWNLOAD_SPEED", gm_stats.getDataReceiveRate() + gm_stats.getProtocolReceiveRate());
writeRawCookedAverageTag("UPLOAD_SPEED", gm_stats.getDataSendRate() + gm_stats.getProtocolSendRate());
} finally {
exdent();
}
writeLineRaw("</GLOBAL>");
writeLineRaw("<DOWNLOADS>");
try {
indent();
List _dms = global.getDownloadManagers();
DownloadManager[] dms = new DownloadManager[_dms.size()];
// sort by position, downloads then seeders
_dms.toArray(dms);
Arrays.sort(dms, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
DownloadManager d1 = (DownloadManager) o1;
DownloadManager d2 = (DownloadManager) o2;
int d1_index = d1.getPosition();
int d2_index = d2.getPosition();
if (d1.isDownloadComplete(false)) {
d1_index += 1000000;
}
if (d2.isDownloadComplete(false)) {
d2_index += 1000000;
}
return (d1_index - d2_index);
}
});
for (int i = 0; i < dms.length; i++) {
DownloadManager dm = (DownloadManager) dms[i];
DownloadManagerStats dm_stats = dm.getStats();
writeLineRaw("<DOWNLOAD>");
try {
indent();
writeLineRaw("<TORRENT>");
// torrent can be null if broken torrent!
TOTorrent torrent = dm.getTorrent();
try {
indent();
writeTag("NAME", dm.getDisplayName());
writeTag("TORRENT_FILE", dm.getTorrentFileName());
if (torrent != null) {
writeTag("HASH", TorrentUtils.nicePrintTorrentHash(torrent, true));
writeRawCookedTag("SIZE", torrent.getSize());
writeTag("PIECE_LENGTH", torrent.getPieceLength());
writeTag("PIECE_COUNT", torrent.getNumberOfPieces());
writeTag("FILE_COUNT", torrent.getFiles().length);
writeTag("COMMENT", dm.getTorrentComment());
writeTag("CREATED_BY", dm.getTorrentCreatedBy());
writeTag("CREATION_DATE", torrent.getCreationDate());
}
} finally {
exdent();
}
writeLineRaw("</TORRENT>");
writeTag("DOWNLOAD_STATUS", DisplayFormatters.formatDownloadStatusDefaultLocale(dm));
writeTag("DOWNLOAD_DIR", dm.getSaveLocation().toString());
if (torrent != null) {
if (torrent.isSimpleTorrent()) {
writeTag("TARGET_FILE", dm.getSaveLocation().toString());
} else {
writeTag("TARGET_DIR", dm.getSaveLocation().toString());
}
}
writeTag("TRACKER_STATUS", dm.getTrackerStatus());
writeTag("COMPLETED", dm_stats.getCompleted());
writeTag("NON_DND_COMPLETED", dm.isDownloadComplete(false));
writeRawCookedTag("DOWNLOADED", dm_stats.getTotalDataBytesReceived());
writeRawCookedTag("UPLOADED", dm_stats.getTotalDataBytesSent());
writeRawCookedTag("DISCARDED", dm_stats.getDiscarded());
writeRawCookedAverageTag("DOWNLOAD_SPEED", dm_stats.getDataReceiveRate());
writeRawCookedAverageTag("UPLOAD_SPEED", dm_stats.getDataSendRate());
writeRawCookedAverageTag("TOTAL_SPEED", dm_stats.getTotalAverage());
writeRawCookedAverageTag("DOWNLOAD_SPEED_SMOOTH", dm_stats.getSmoothedDataReceiveRate());
writeRawCookedAverageTag("UPLOAD_SPEED_SMOOTH", dm_stats.getSmoothedDataSendRate());
writeTag("ELAPSED", dm_stats.getElapsedTime());
writeTag("ETA", DisplayFormatters.formatETA(dm_stats.getSmoothedETA()));
writeTag("HASH_FAILS", dm_stats.getHashFailCount());
writeTag("SHARE_RATIO", dm_stats.getShareRatio());
writeTag("TOTAL_SEEDS", dm.getNbSeeds());
writeTag("TOTAL_LEECHERS", dm.getNbPeers());
if (export_file_stats) {
try {
writeLineRaw("<FILES>");
indent();
DiskManagerFileInfo[] files = dm.getDiskManagerFileInfo();
for (int j = 0; j < files.length; j++) {
DiskManagerFileInfo file = files[j];
try {
writeLineRaw("<FILE>");
indent();
writeTag("NAME", file.getTorrentFile().getRelativePath());
writeTag("DND", file.isSkipped());
writeRawCookedTag("SIZE", file.getLength());
writeRawCookedTag("DOWNLOADED", file.getDownloaded());
} finally {
exdent();
writeLineRaw("</FILE>");
}
}
} finally {
exdent();
writeLineRaw("</FILES>");
}
}
if (export_peer_stats) {
try {
writeLineRaw("<PEERS>");
indent();
PEPeerManager pm = dm.getPeerManager();
if (pm != null) {
List peers = pm.getPeers();
for (int j = 0; j < peers.size(); j++) {
PEPeer peer = (PEPeer) peers.get(j);
PEPeerStats peer_stats = peer.getStats();
byte[] id = peer.getId();
if (id == null) {
continue;
}
try {
String peer_id = PeerClassifier.getPrintablePeerID(id);
peer_id = escapeXML(peer_id);
String type = escapeXML(peer.getClient());
writeLineRaw("<PEER hex_id=\"" + ByteFormatter.encodeString(id) + "\" printable_id=\"" + peer_id + "\" type=\"" + type + "\">");
indent();
writeTag("IP", peer.getIp());
writeTag("IS_SEED", peer.isSeed());
writeRawCookedTag("DOWNLOADED", peer_stats.getTotalDataBytesReceived());
writeRawCookedTag("UPLOADED", peer_stats.getTotalDataBytesSent());
writeRawCookedAverageTag("DOWNLOAD_SPEED", peer_stats.getDataReceiveRate());
writeRawCookedAverageTag("UPLOAD_SPEED", peer_stats.getDataSendRate());
} catch (Throwable e) {
Debug.printStackTrace(e);
} finally {
exdent();
writeLineRaw("</PEER>");
}
}
}
} finally {
exdent();
writeLineRaw("</PEERS>");
}
}
} finally {
exdent();
}
writeLineRaw("</DOWNLOAD>");
}
} finally {
exdent();
}
writeLineRaw("</DOWNLOADS>");
} finally {
exdent();
}
writeLineRaw("</STATS>");
}
Aggregations