Qt-jambi-interest Archive, May 2007
UnsatisfiedLinkError: inputStream.readBytes()
Message 1 in thread
Hi
A QT-newbie-question:
I'm trying calculate a md5-digest of a (potentially) huge file.
Something that would mimic md5sum(as in
http://www.linuxmanpages.com/man1/md5sum.1.php)
So, being a qt-newbie I went out doing it the newbie-way.
I iterate over a inputStream using readBytes reading bytes into a
byte-buffer.
But I get:
Exception in thread "main" java.lang.UnsatisfiedLinkError: readBytes
at com.trolltech.qt.core.QDataStream.readBytes(Native Method)
at com.trolltech.qt.core.QDataStream.readBytes(QDataStream.java:382)
at Test.calcDigest(Test.java:52)
at Test.<init>(Test.java:34)
at Test.main(Test.java:18)
If I change from readBytes(... ) to readByte() then and all is well
except it's utterly slooooow (as expected). But it gives the same result
as md5sum.
a stripped-down version of my method looks like:
public String calcDigest(String hugeFile){
QFile file = new QFile(hugeFile);
file.open(QIODevice.OpenModeFlag.ReadOnly);
QDataStream inputStream = new QDataStream(file);
QCryptographicHash cryptoHash = new
QCryptographicHash(QCryptographicHash.Algorithm.Md5);
byte[] byteBuff = new byte[16384];
QByteArray qarr = new QByteArray();
while( !inputStream.atEnd() ) {
int cnt = inputStream.readBytes(byteBuff,16384);
QByteArray tmp = new QByteArray(qarr);
qarr.append(tmp);
}
cryptoHash.addData(qarr);
QByteArray result = cryptoHash.result();
return result.toHex().toString();
}
what more....
well, I'm using Linux/Ubuntu 6.10
and
qtjambi-gpl-linux-1.0.0-beta2
and
java version "1.5.0_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)
It's not _acutally_ a problem. I'could use java.security.DigestInputStream
But... but... but... it makes me somewhat mad^H^H^H curious.
cheers
Patrik
Message 2 in thread
Hi, Patrik.
Patrik Johansson skrev:
>
>
> But I get:
>
> Exception in thread "main" java.lang.UnsatisfiedLinkError: readBytes
> at com.trolltech.qt.core.QDataStream.readBytes(Native Method)
> at com.trolltech.qt.core.QDataStream.readBytes(QDataStream.java:382)
> at Test.calcDigest(Test.java:52)
> at Test.<init>(Test.java:34)
> at Test.main(Test.java:18)
This is unfortunately a bug in Qt Jambi Beta2. I'm attaching a patch to
this mail if you want to fix the source package yourself.
Since you don't seem to be using the serialization features of
QDataStream, I think a workaround for you is to call read() on the QFile
directly:
http://doc.trolltech.com/qtjambi-1.0/com/trolltech/qt/core/QIODevice.html#read(long)
There are two versions that you can use:
1. QByteArray ba = file.read(16384); // where you pass in the maximum
number of bytes to read and Qt Jambi will allocate the buffer
2. byte[] byteBuff = new byte[16384]; file.read(byteBuff); // where you
use your already existing byte[] buffer
Example of approach #2:
QFile file = new QFile(hugeFile);
if (file.open(QIODevice.OpenModeFlag.ReadOnly)) {
byte bytes[] = new byte[16384];
QCryptographicHash hash = new
QCryptographicHash(QCryptographicHash.Algorithm.Md5);
int sizeRead;
while ((sizeRead = file.read(bytes)) > 0) {
hash.addData(Arrays.copyOf(bytes, sizeRead));
}
if (sizeRead < 0) System.err.println("An error occured: " +
file.errorString());
else System.out.println("Result: " + hash.result().toHex());
}
(note that java.util.Arrays.copyOf() requires Java 6)
>
> But... but... but... it makes me somewhat mad^H^H^H curious.
Sorry about that and thank you for reporting the bug. Hope this helped
relieve your "curiosity" ;-)
-- Eskil
==== generator/typesystem_core.txt#49 (text) ====
==== generator/typesystem_core.txt#49 (text) ====
@@ -2486,7 +2486,7 @@
</inject-code>
<template name="core.qdatastream_readorwrite_bytes">
- extern "C" JNIEXPORT jint JNICALL QTJAMBI_FUNCTION_PREFIX(Java_com_trolltech_qt_core_QDataStream_%FUNCTION_NAME%_native)
+ extern "C" JNIEXPORT jint JNICALL QTJAMBI_FUNCTION_PREFIX(Java_com_trolltech_qt_core_QDataStream_%FUNCTION_NAME%)
(JNIEnv *env, jobject, jlong stream, jbyteArray array, jint length)
{
QTJAMBI_DEBUG_TRACE("(native) entering: QDataStream::%FUNCTION_NAME%");
Message 3 in thread
Hi Eskil.
Eskil Abrahamsen Blomfeldt wrote:
> Hi, Patrik.
>
> Patrik Johansson skrev:
>>
>>
>> But I get:
>>
>> Exception in thread "main" java.lang.UnsatisfiedLinkError: readBytes
>> at com.trolltech.qt.core.QDataStream.readBytes(Native Method)
>> at com.trolltech.qt.core.QDataStream.readBytes(QDataStream.java:382)
>> at Test.calcDigest(Test.java:52)
>> at Test.<init>(Test.java:34)
>> at Test.main(Test.java:18)
>
> This is unfortunately a bug in Qt Jambi Beta2. I'm attaching a patch
> to this mail if you want to fix the source package yourself.
>
No, worries. Beta is a Beta...and I'm just fooling around.
(though, it is for a purpose - to check if we could use qtjambi as a
tool for cross-plattform-UI for my company)
> Since you don't seem to be using the serialization features of
> QDataStream, I think a workaround for you is to call read() on the
> QFile directly:
>
>
> http://doc.trolltech.com/qtjambi-1.0/com/trolltech/qt/core/QIODevice.html#read(long)
>
>
> There are two versions that you can use:
> 1. QByteArray ba = file.read(16384); // where you pass in the maximum
> number of bytes to read and Qt Jambi will allocate the buffer
> 2. byte[] byteBuff = new byte[16384]; file.read(byteBuff); // where
> you use your already existing byte[] buffer
>
> Example of approach #2:
>
> QFile file = new QFile(hugeFile);
> if (file.open(QIODevice.OpenModeFlag.ReadOnly)) {
> byte bytes[] = new byte[16384];
> QCryptographicHash hash = new
> QCryptographicHash(QCryptographicHash.Algorithm.Md5);
> int sizeRead;
> while ((sizeRead = file.read(bytes)) > 0) {
> hash.addData(Arrays.copyOf(bytes, sizeRead));
> }
> if (sizeRead < 0) System.err.println("An error
> occured: " + file.errorString());
> else System.out.println("Result: " + hash.result().toHex());
> }
>
> (note that java.util.Arrays.copyOf() requires Java 6)
>
>
>>
>> But... but... but... it makes me somewhat mad^H^H^H curious.
>
> Sorry about that and thank you for reporting the bug. Hope this helped
> relieve your "curiosity" ;-)
>
>
> -- Eskil
>
I'm cured ... no curiosity no more :-)
I should probably try to implement my md5-method using your suggestions
above (with a tweak since I need to be Java 5 compatible)
and run some more unscientific tests. I mean, since I'm being a curious
guy and all.
Somewhat of topic but, being a curios guy, I did a implementation using
java.security.DigestInputStream
It's somewhat faster then the native md5sum(1) ... oops!
I smell a stand-off ! md5sum native vs. java/DigestInputStream vs.
java/jambi.
who will win ... WHO WILL LOSE!?
[the audience is holding it's breath]
...to be continued ...
:-)
BTW, thanks man
cheers
Patrik