@@ -453,6 +453,76 @@ Object deflateCompress(DeflaterWrapper stream, PIBytesLike pb, int mode) {
453453 }
454454 }
455455
456+ @ Builtin (name = "zlib_inflateInit" , fixedNumOfPositionalArgs = 2 )
457+ @ GenerateNodeFactory
458+ abstract static class InflateInitNode extends PythonBinaryBuiltinNode {
459+ @ Child BytesNodes .ToBytesNode toBytes = BytesNodes .ToBytesNode .create ();
460+
461+ @ Specialization
462+ @ TruffleBoundary
463+ Object init (int wbits , PBytes zdict ) {
464+ Inflater inflater ;
465+ if (wbits < 0 ) {
466+ // generate a RAW stream, i.e., no wrapping
467+ inflater = new Inflater (true );
468+ } else if (wbits >= 25 ) {
469+ // include gzip container
470+ throw raise (PythonBuiltinClassType .NotImplementedError , "gzip containers" );
471+ } else {
472+ // wrap stream with zlib header and trailer
473+ inflater = new Inflater (false );
474+ }
475+
476+ inflater .setDictionary (toBytes .execute (zdict ));
477+ return new InflaterWrapper (inflater );
478+ }
479+ }
480+
481+ static class InflaterWrapper implements TruffleObject {
482+ private final Inflater inflater ;
483+
484+ public InflaterWrapper (Inflater inflater ) {
485+ this .inflater = inflater ;
486+ }
487+
488+ public ForeignAccess getForeignAccess () {
489+ return null ;
490+ }
491+ }
492+
493+ @ Builtin (name = "zlib_inflateDecompress" , fixedNumOfPositionalArgs = 3 )
494+ @ GenerateNodeFactory
495+ abstract static class InflaterDecompress extends PythonTernaryBuiltinNode {
496+ @ Child BytesNodes .ToBytesNode toBytes = BytesNodes .ToBytesNode .create ();
497+
498+ @ Specialization
499+ @ TruffleBoundary
500+ Object decompress (InflaterWrapper stream , PIBytesLike pb , int maxLen ) {
501+ int maxLength = maxLen == 0 ? Integer .MAX_VALUE : maxLen ;
502+
503+ ByteArrayOutputStream baos = new ByteArrayOutputStream ();
504+ byte [] data = toBytes .execute (pb );
505+ byte [] result = new byte [DEF_BUF_SIZE ];
506+ stream .inflater .setInput (data );
507+
508+ int bytesWritten = result .length ;
509+ while (baos .size () < maxLength && bytesWritten == result .length ) {
510+ try {
511+ bytesWritten = stream .inflater .inflate (result , 0 , result .length );
512+ } catch (DataFormatException e ) {
513+ throw raise (ZLibError , e .getMessage ());
514+ }
515+ baos .write (result , 0 , bytesWritten );
516+ }
517+
518+ return factory ().createTuple (new Object []{
519+ factory ().createBytes (baos .toByteArray ()),
520+ stream .inflater .needsInput (),
521+ stream .inflater .getRemaining ()
522+ });
523+ }
524+ }
525+
456526 // zlib.compress(data, level=-1)
457527 @ Builtin (name = "compress" , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 2 , keywordArguments = {"level" })
458528 @ TypeSystemReference (PythonArithmeticTypes .class )
0 commit comments