src/JavaZipSupport.st
branchjk_new_structure
changeset 1536 8d5abf068003
parent 1155 d6f6d5fc0343
child 1537 0072327ccc71
equal deleted inserted replaced
1535:bec377806f12 1536:8d5abf068003
    22 
    22 
    23 Object subclass:#JavaZipSupport
    23 Object subclass:#JavaZipSupport
    24 	instanceVariableNames:''
    24 	instanceVariableNames:''
    25 	classVariableNames:''
    25 	classVariableNames:''
    26 	poolDictionaries:''
    26 	poolDictionaries:''
    27 	category:'Languages-Java-Support'
    27 	category:'Languages-Java-Support-Native'
       
    28 !
       
    29 
       
    30 Object subclass:#Deflater
       
    31 	instanceVariableNames:'vm z_stream'
       
    32 	classVariableNames:''
       
    33 	poolDictionaries:''
       
    34 	privateIn:JavaZipSupport
    28 !
    35 !
    29 
    36 
    30 Object subclass:#Inflater
    37 Object subclass:#Inflater
    31 	instanceVariableNames:'vm z_stream'
    38 	instanceVariableNames:'vm z_stream'
    32 	classVariableNames:''
    39 	classVariableNames:''
    78 
    85 
    79 !JavaZipSupport class methodsFor:'instance creation'!
    86 !JavaZipSupport class methodsFor:'instance creation'!
    80 
    87 
    81 inflaterFor: vm
    88 inflaterFor: vm
    82 
    89 
    83     ^Inflater new vm: vm
    90     ^Deflater new vm: vm
    84 
    91 
    85     "Created: / 30-08-2011 / 09:05:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    92     "Created: / 30-08-2011 / 09:05:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
    93 ! !
       
    94 
       
    95 !JavaZipSupport::Deflater methodsFor:'accessing'!
       
    96 
       
    97 vm: javaVM
       
    98 
       
    99     vm := javaVM.
       
   100 
       
   101     "Created: / 30-08-2011 / 09:05:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   102 ! !
       
   103 
       
   104 !JavaZipSupport::Deflater methodsFor:'inflater methods'!
       
   105 
       
   106 adler
       
   107 
       
   108 %{
       
   109 	RETURN ( __MKEXTERNALADDRESS ( __zStreamVal(__INST(z_stream))->adler ) );
       
   110 %}
       
   111 
       
   112 "
       
   113 OpenJDK 7 Implementation:
       
   114 
       
   115 JNIEXPORT jint JNICALL
       
   116 Java_java_util_zip_Inflater_getAdler(JNIEnv *env, jclass cls, jlong addr)
       
   117 {
       
   118     return ((z_stream *)jlong_to_ptr(addr))->adler;
       
   119 }
       
   120 "
       
   121 
       
   122     "Created: / 31-08-2011 / 09:30:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   123 !
       
   124 
       
   125 bytesRead
       
   126 
       
   127 %{
       
   128 	RETURN ( __MKSMALLINT( __zStreamVal(__INST(z_stream))->total_in));
       
   129 %}
       
   130 
       
   131 
       
   132 "
       
   133 OpenJDK 7 Implementation:
       
   134 
       
   135 JNIEXPORT jlong JNICALL
       
   136 Java_java_util_zip_Inflater_getBytesRead(JNIEnv *env, jclass cls, jlong addr)
       
   137 {
       
   138     return ((z_stream *)jlong_to_ptr(addr))->total_in;
       
   139 }
       
   140 "
       
   141 
       
   142     "Created: / 31-08-2011 / 09:30:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   143 !
       
   144 
       
   145 bytesWritten
       
   146 
       
   147 %{
       
   148 	RETURN ( __MKSMALLINT( __zStreamVal(__INST(z_stream))->total_out));
       
   149 %}
       
   150 
       
   151 
       
   152 "
       
   153 OpenJDK 7 Implementation:
       
   154 
       
   155 JNIEXPORT jlong JNICALL
       
   156 Java_java_util_zip_Inflater_getBytesWritten(JNIEnv *env, jclass cls, jlong addr)
       
   157 {
       
   158     return ((z_stream *)jlong_to_ptr(addr))->total_out;
       
   159 }
       
   160 "
       
   161 
       
   162     "Created: / 31-08-2011 / 09:30:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   163 !
       
   164 
       
   165 deflate:"byte[]" out_buf offset: "int" out_off length: "int" out_len flush: flush deflaterr: deflater
       
   166 
       
   167         | in_buf in_off in_len finished needDict errorType errorMsg ret |
       
   168         in_buf := deflater instVarNamed:#buf.
       
   169         in_off := deflater instVarNamed:#off.
       
   170         in_len := deflater instVarNamed:#len.
       
   171 
       
   172         finished := needDict := 0.
       
   173 
       
   174 %{
       
   175 #define strm (__zStreamVal(__INST(z_stream)))
       
   176         int code, consumed;
       
   177         
       
   178         strm->next_in = (Bytef *) (__ByteArrayInstPtr(in_buf)->ba_element + __intVal(in_off));
       
   179         strm->next_out = (Bytef *) (__ByteArrayInstPtr(out_buf)->ba_element + __intVal(out_off));
       
   180         strm->avail_in = __intVal(in_len);      
       
   181         strm->avail_out = __intVal(out_len);
       
   182 
       
   183         
       
   184         code = inflate(strm, Z_PARTIAL_FLUSH);
       
   185 
       
   186         switch (code) {
       
   187                 case Z_STREAM_END:
       
   188                         finished = __MKSMALLINT(1);
       
   189                         /* fall through */
       
   190                 case Z_OK:
       
   191                         consumed = __intVal(in_len) - strm->avail_in;
       
   192                         in_off = __MKSMALLINT(_intVal(in_off) + consumed);
       
   193                         in_len = __MKSMALLINT(_intVal(in_len) - consumed);
       
   194                         ret = __MKSMALLINT(__intVal(out_len) - strm->avail_out);
       
   195                         break;
       
   196                 case Z_NEED_DICT:
       
   197                         needDict = __MKSMALLINT(1);
       
   198                         /* Might have consumed some input here! */
       
   199                         consumed = __intVal(in_len) - strm->avail_in;
       
   200                         in_off = __MKSMALLINT(_intVal(in_off) + consumed);
       
   201                         in_len = __MKSMALLINT(_intVal(in_len) - consumed);
       
   202                         ret = __MKSMALLINT(0);
       
   203                         break;
       
   204                 case Z_BUF_ERROR:
       
   205                         ret = __MKSMALLINT(0);
       
   206                         break;
       
   207                 case Z_DATA_ERROR:
       
   208             errorMsg = __MKSTRING(__zStreamVal(__INST(z_stream))->msg);
       
   209             errorType = @symbol(DataFormatException);
       
   210 
       
   211                         break;
       
   212                 case Z_MEM_ERROR:
       
   213             errorType = @symbol(OutOfMemoryError);
       
   214                         break;
       
   215                 default:
       
   216             errorMsg = __MKSTRING(__zStreamVal(__INST(z_stream))->msg);
       
   217             errorType = @symbol(InternalError);
       
   218                         break;
       
   219     }   
       
   220 #undef strm
       
   221 %}.
       
   222     errorType == #DataFormatException ifTrue:[
       
   223         vm throwDataFormatException: errorMsg.
       
   224         ^0.
       
   225     ].
       
   226     errorType == #OutOfMemoryError ifTrue:[
       
   227         vm throwOutOfMemoryError.
       
   228         ^0.
       
   229     ].
       
   230     errorType == #InternalError ifTrue:[
       
   231         vm internalError: errorMsg.
       
   232         ^0.
       
   233     ].
       
   234 
       
   235         deflater instVarNamed:#off put: in_off.
       
   236         deflater instVarNamed:#len put: in_len.
       
   237         deflater instVarNamed:#finished put: finished.
       
   238         deflater instVarNamed:#needDict put: needDict.
       
   239         ^ret
       
   240 
       
   241 "
       
   242 OpenJDK 7 Implementation
       
   243 
       
   244 JNIEXPORT jint JNICALL
       
   245 Java_java_util_zip_Inflater_inflateBytes(JNIEnv *env, jobject this, jlong addr,
       
   246                                          jarray b, jint off, jint len)
       
   247 {
       
   248     z_stream *strm = jlong_to_ptr(addr);
       
   249 
       
   250     jarray this_buf = (jarray)(*env)->GetObjectField(env, this, bufID);
       
   251     jint this_off = (*env)->GetIntField(env, this, offID);
       
   252     jint this_len = (*env)->GetIntField(env, this, lenID);
       
   253     jbyte *in_buf;
       
   254     jbyte *out_buf;
       
   255     int ret;
       
   256     /*
       
   257      * Avoid excess copying.
       
   258      *   zlib stream usually has a few bytes of overhead for header info
       
   259      *   (depends on the underlying data)
       
   260      *
       
   261      *   (a) 5 bytes per 16KB
       
   262      *   (b) 6 bytes for entire stream
       
   263      *   (c) 4 bytes for gzip header
       
   264      *   (d) 2 bytes for crc
       
   265      *
       
   266      * Use 20 bytes as the 'safe cutoff' number.
       
   267      */
       
   268     jint in_len = MIN2(this_len, len + 20);
       
   269     jint consumed;
       
   270 
       
   271     in_buf = (jbyte *) malloc(in_len);
       
   272     if (in_buf == 0) {
       
   273         JNU_ThrowOutOfMemoryError(env, 0);
       
   274         return 0;
       
   275     }
       
   276     (*env)->GetByteArrayRegion(env, this_buf, this_off, in_len, in_buf);
       
   277 
       
   278     out_buf = (jbyte *) malloc(len);
       
   279     if (out_buf == 0) {
       
   280         free(in_buf);
       
   281         JNU_ThrowOutOfMemoryError(env, 0);
       
   282         return 0;
       
   283     }
       
   284 
       
   285     strm->next_in  = (Bytef *) in_buf;
       
   286     strm->next_out = (Bytef *) out_buf;
       
   287     strm->avail_in  = in_len;
       
   288     strm->avail_out = len;
       
   289     ret = inflate(strm, Z_PARTIAL_FLUSH);
       
   290 
       
   291     if (ret == Z_STREAM_END || ret == Z_OK) {
       
   292         (*env)->SetByteArrayRegion(env, b, off, len - strm->avail_out, out_buf);
       
   293     }
       
   294     free(out_buf);
       
   295     free(in_buf);
       
   296 
       
   297     switch (ret) {
       
   298     case Z_STREAM_END:
       
   299         (*env)->SetBooleanField(env, this, finishedID, JNI_TRUE);
       
   300         /* fall through */
       
   301     case Z_OK:
       
   302         consumed = in_len - strm->avail_in;
       
   303         (*env)->SetIntField(env, this, offID, this_off + consumed);
       
   304         (*env)->SetIntField(env, this, lenID, this_len - consumed);
       
   305         return len - strm->avail_out;
       
   306     case Z_NEED_DICT:
       
   307         (*env)->SetBooleanField(env, this, needDictID, JNI_TRUE);
       
   308         /* Might have consumed some input here!! */
       
   309         consumed = in_len - strm->avail_in;
       
   310         (*env)->SetIntField(env, this, offID, this_off + consumed);
       
   311         (*env)->SetIntField(env, this, lenID, this_len - consumed);
       
   312         return 0;
       
   313     case Z_BUF_ERROR:
       
   314         return 0;
       
   315     case Z_DATA_ERROR:
       
   316         ThrowDataFormatException(env, strm->msg);
       
   317         return 0;
       
   318     case Z_MEM_ERROR:
       
   319         JNU_ThrowOutOfMemoryError(env, 0);
       
   320         return 0;
       
   321     default:
       
   322         JNU_ThrowInternalError(env, strm->msg);
       
   323         return 0;
       
   324     }
       
   325 }
       
   326 
       
   327 "
       
   328 
       
   329     "Created: / 20-07-2012 / 17:55:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   330 !
       
   331 
       
   332 end
       
   333 
       
   334 	| ok |
       
   335 
       
   336 	ok := true.
       
   337 	
       
   338 %{
       
   339     if (inflateEnd(__zStreamVal(__INST(z_stream))) == Z_STREAM_ERROR) {
       
   340 		ok = false;
       
   341 	}
       
   342 %}.
       
   343 	z_stream free.
       
   344 	ok ifFalse:[
       
   345         vm internalError: 'Cannot call inflateEnd()'.
       
   346 	].
       
   347 
       
   348 "
       
   349 OpenJDK 7 Implementation:
       
   350 
       
   351 JNIEXPORT void JNICALL
       
   352 Java_java_util_zip_Inflater_end(JNIEnv *env, jclass cls, jlong addr)
       
   353 {
       
   354     if (inflateEnd(jlong_to_ptr(addr)) == Z_STREAM_ERROR) {
       
   355         JNU_ThrowInternalError(env, 0);
       
   356     } else {
       
   357         free(jlong_to_ptr(addr));
       
   358     }
       
   359 }
       
   360 
       
   361 "
       
   362 
       
   363     "Created: / 30-08-2011 / 20:50:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   364 !
       
   365 
       
   366 init: nowrap
       
   367 
       
   368     | z_stream_size errorType errorMsg |
       
   369 
       
   370 %{  z_stream_size = __MKSMALLINT(sizeof(z_stream)); %}.
       
   371 
       
   372     z_stream := ExternalBytes unprotectedNew: z_stream_size.
       
   373     
       
   374 
       
   375 %{
       
   376     switch (inflateInit2(__zStreamVal(__INST(z_stream)), nowrap ? -MAX_WBITS : MAX_WBITS)) {
       
   377         case Z_OK:
       
   378             RETURN ( self );
       
   379         case Z_MEM_ERROR:
       
   380             errorType = @symbol(OutOfMemoryError);
       
   381             break;
       
   382         default:
       
   383             errorMsg = __MKSTRING(__zStreamVal(__INST(z_stream))->msg);
       
   384             errorType = @symbol(InternalError);
       
   385             break;
       
   386     }    
       
   387 %}.
       
   388 
       
   389     z_stream free.
       
   390     errorType == #OutOfMemoryError ifTrue:[
       
   391         vm throwOutOfMemoryError.
       
   392         ^self.
       
   393     ].
       
   394     errorType == #InternalError ifTrue:[
       
   395         vm internalError: errorMsg.
       
   396         ^self.
       
   397     ].
       
   398     
       
   399 
       
   400 
       
   401     "
       
   402 OpenJDK 7 Implementation:
       
   403 JNIEXPORT jlong JNICALL
       
   404 Java_java_util_zip_Inflater_init(JNIEnv *env, jclass cls, jboolean nowrap)
       
   405 {
       
   406     z_stream *strm = calloc(1, sizeof(z_stream));
       
   407 
       
   408     if (strm == 0) {
       
   409         JNU_ThrowOutOfMemoryError(env, 0);
       
   410         return jlong_zero;
       
   411     } else {
       
   412         char *msg;
       
   413         switch (inflateInit2(strm, nowrap ? -MAX_WBITS : MAX_WBITS)) {
       
   414           case Z_OK:
       
   415             return ptr_to_jlong(strm);
       
   416           case Z_MEM_ERROR:
       
   417             free(strm);
       
   418             JNU_ThrowOutOfMemoryError(env, 0);
       
   419             return jlong_zero;
       
   420           default:
       
   421             msg = strm->msg;
       
   422             free(strm);
       
   423             JNU_ThrowInternalError(env, msg);
       
   424             return jlong_zero;
       
   425         }
       
   426     }
       
   427 }
       
   428 
       
   429     "
       
   430 
       
   431     "Created: / 29-08-2011 / 17:22:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   432 !
       
   433 
       
   434 reset
       
   435 
       
   436 %{
       
   437 	if (inflateReset(__zStreamVal(__INST(z_stream))) == Z_OK) {
       
   438 		RETURN ( self );
       
   439 	}
       
   440 %}.
       
   441 
       
   442 	vm internalError: 'Cannot reset inflater'.
       
   443 
       
   444 "
       
   445 OpenJDK 7 Implementation:
       
   446 
       
   447 JNIEXPORT void JNICALL
       
   448 Java_java_util_zip_Inflater_reset(JNIEnv *env, jclass cls, jlong addr)
       
   449 {
       
   450     if (inflateReset(jlong_to_ptr(addr)) !!= Z_OK) {
       
   451         JNU_ThrowInternalError(env, 0);
       
   452     }
       
   453 }
       
   454 
       
   455 "
       
   456 
       
   457     "Created: / 30-08-2011 / 12:45:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    86 ! !
   458 ! !
    87 
   459 
    88 !JavaZipSupport::Inflater methodsFor:'accessing'!
   460 !JavaZipSupport::Inflater methodsFor:'accessing'!
    89 
   461 
    90 vm: javaVM
   462 vm: javaVM