frostwire / frostwire-jlibtorrent

A swig Java interface for libtorrent by the makers of FrostWire. Develop libtorrent based apps with the joy of coding in Java.
http://www.frostwire.com
MIT License
444 stars 137 forks source link

How to get data from ReadPieceAlert? #232

Closed master255 closed 4 years ago

master255 commented 4 years ago

@gubatron , @frostwire , How can I get data from an Alert message? I have a pointer: (ReadPieceAlert)Alerts.cast(a)).bufferPtr() How do I get byte[]?

master255 commented 4 years ago

@gubatron @frostwire ?

gubatron commented 4 years ago

I believe you need to use byte_vector, the alert's size() should be useful.

Let me know if the methods you use on byte_vector are not accesible from outside, we might need to make them public.

I'd start playing with

// see libtorrent_jni.java
public final static native byte byte_vector_get(long jarg1, byte_vector jarg1_, int jarg2);

See if this works, I'm guessing this would allow you to treat the given pointer as a byte_vector, but I'm not sure

byte_vector my_byte_vector = byte_vector();
// with the alert's bufferPtr and its size
long bufferPtr = readAlert.bufferPtr();
byte[] result = new byte[readAlert.size()];
for (int i=0; i < readAlert.size(); i++) {
  result[i] = byte_vector_get(bufferPtr, my_byte_vector, i); 
}

perhaps @aldenml knows of a utility method in Vectors to do what you want. (Read N bytes from an alert's buffer pointer)

master255 commented 4 years ago

@gubatron Bad news. Reading returns a error: "2020-05-20 15:37:28.687 24019-24629 A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x5d712470db1409 in tid 24629 (SessionManager-)". in this line: result[i] = byte_vector_get(bufferPtr, my_byte_vector, i);

i'm use:

addTorrentParams.swig().set_disabled_storage();
torrentHandle.setFlags(TorrentFlags.SEQUENTIAL_DOWNLOAD);

Maybe the problem is that data is constantly being downloaded and overwritten in memory? For how long does the piece stay in memory?

Let me know if the methods you use on byte_vector are not accesible from outside, we might need to make them public.

I did my implementation and made it public, but it's better if you do it in the library.

upd: I put this code on the TORRENT_CHECKED event:

session.get_torrents().get(0).pause();
session.get_torrents().get(0).read_piece(0);

Now I have a message about the successful loading of the first piece. And the download stops. Error on the same line: result[u] = byte_vector_get(bufferPtr, my_byte_vector, u); But now the error text is this:

2020-05-20 16:41:47.102 2087-3551 E/AndroidRuntime: FATAL EXCEPTION: SessionManager-alertsLoop
    Process: com.media.library, PID: 2087
    java.lang.IndexOutOfBoundsException: vector index out of range
        at com.frostwire.jlibtorrent.swig.libtorrent_jni.byte_vector_get(Native Method)
gubatron commented 4 years ago

maybe it's not byte_vector_get what you need to use then, seems like you're trying to read/write into an empty byte_vector

master255 commented 4 years ago

@gubatron Why is it empty? The alert description says the piece was successfully read. How do I fill it up? It seems like the alert isn't working.

gubatron commented 4 years ago

I'm going to be building a new version of jlibtorrent, I know you're a little impatient, but I'll write a ReadAlertPieceTest and play with this.

Try looking at other source code samples on how to read a C++ pointer into a Java String (by using our Vector methods), It might give you clues if it's possible to be done with the current java api we have or if we have to add a custom wrapper on the swig file.

master255 commented 4 years ago

@gubatron Good news for everyone! I'm going to deal with the library. Now I'm trying to compile it with Ubuntu...

master255 commented 4 years ago

@gubatron Thank you for your help and support. I don't think that's what I need. If you want to open a bug, but I don't need that feature anymore. Like Arvidn said, I need to do custom storage. I don't know how to do it yet, but I'm thinking about moving in that direction. Now I've already learned how to compile a project.