Trolltech Home | Qt-jambi-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

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