[svn:parrot] r45941 - in trunk: src/dynpmc t/dynpmc

fperrad at svn.parrot.org fperrad at svn.parrot.org
Fri Apr 23 18:35:32 UTC 2010


Author: fperrad
Date: Fri Apr 23 18:35:32 2010
New Revision: 45941
URL: https://trac.parrot.org/parrot/changeset/45941

Log:
[GzipHandle] implements it

Modified:
   trunk/src/dynpmc/gziphandle.pmc
   trunk/t/dynpmc/gziphandle.t

Modified: trunk/src/dynpmc/gziphandle.pmc
==============================================================================
--- trunk/src/dynpmc/gziphandle.pmc	Fri Apr 23 18:30:48 2010	(r45940)
+++ trunk/src/dynpmc/gziphandle.pmc	Fri Apr 23 18:35:32 2010	(r45941)
@@ -27,7 +27,8 @@
 /* HEADERIZER BEGIN: static */
 /* HEADERIZER END: static */
 
-pmclass GzipHandle extends Handle dynpmc auto_attrs {
+pmclass GzipHandle provides Handle dynpmc auto_attrs {
+    ATTR void *file;
 
 /*
 
@@ -38,8 +39,23 @@
 =cut
 
 */
-
     VTABLE void init() {
+        PARROT_GZIPHANDLE(SELF)->file = NULL;
+    }
+
+/*
+
+=item C<INTVAL get_bool()>
+
+Returns whether the GzipHandle has reached the end of the file.
+
+=cut
+
+*/
+    VTABLE INTVAL get_bool() {
+        gzFile file;
+        GET_ATTR_file(INTERP, SELF, file);
+        return !gzeof(file);
     }
 
 /*
@@ -50,8 +66,161 @@
 
 =over 4
 
+=item C<METHOD open(STRING *filename, STRING *mode :optional)>
+
+Opens the file at the given filename (including path) with the given mode. The
+invocant is modified and becomes an open filehandle.
+
+=cut
+
+*/
+    METHOD open(STRING *filename, STRING *mode :optional,
+                               INTVAL has_mode :opt_flag) {
+        gzFile file;
+        char *path;
+        char *mod = (char *)"rb";
+        path = Parrot_str_to_cstring(INTERP, filename);
+        if (has_mode)
+            mod = Parrot_str_to_cstring(INTERP, mode);
+        file = gzopen (path, mod);
+        Parrot_str_free_cstring(path);
+        if (has_mode)
+            Parrot_str_free_cstring(mod);
+        if (NULL == file) {
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_ILL_INHERIT,
+                "gzopen fails");
+        }
+        SET_ATTR_file(INTERP, SELF, file);
+        RETURN(PMC SELF);
+    }
+
+/*
+
+=item C<METHOD close()>
+
+Close the gziphandle.
+
+=cut
+
 */
+    METHOD close() {
+        INTVAL status;
+        gzFile file;
+        GET_ATTR_file(INTERP, SELF, file);
+        status = gzclose(file);
+        RETURN(INTVAL status);
+    }
+
+/*
+
+=item C<METHOD eof()>
 
+Returns true if the filehandle is at end-of-file, returns false otherwise.
+
+=cut
+
+*/
+    METHOD eof() {
+        INTVAL status;
+        gzFile file;
+        GET_ATTR_file(INTERP, SELF, file);
+        status = gzeof(file);
+        RETURN(INTVAL status);
+    }
+
+/*
+
+=item C<METHOD flush()>
+
+Flushes the gziphandle.
+
+=cut
+
+*/
+    METHOD flush() {
+        INTVAL status;
+        gzFile file;
+        GET_ATTR_file(INTERP, SELF, file);
+        status = gzflush(file, Z_SYNC_FLUSH);
+        RETURN(INTVAL status);
+    }
+
+/*
+
+=item C<METHOD print([INTVAL|FLOATVAL|STRING *|PMC*] value)>
+
+Print the passed in integer, number, string, or PMC to the gziphandle.
+(Integers, numbers, and strings are auto-boxed as PMCs.)
+
+=cut
+
+*/
+    METHOD print(PMC *value) {
+        gzFile file;
+        STRING * const str = VTABLE_get_string(INTERP, value);
+        CHAR *buf = Parrot_str_to_cstring(INTERP, str);
+        INTVAL len =  Parrot_str_byte_length(INTERP, str);
+        GET_ATTR_file(INTERP, SELF, file);
+        (void)gzwrite(file, buf, len);
+        Parrot_str_free_cstring(buf);
+    }
+
+
+/*
+
+=item C<METHOD puts(STRING *value)>
+
+Print the string to the gziphandle.
+
+=cut
+
+*/
+    METHOD puts(STRING *value) {
+        INTVAL status;
+        gzFile file;
+        CHAR *buf = Parrot_str_to_cstring(INTERP, value);
+        INTVAL len =  Parrot_str_byte_length(INTERP, value);
+        GET_ATTR_file(INTERP, SELF, file);
+        status =  gzwrite(file, buf, len);
+        Parrot_str_free_cstring(buf);
+        RETURN(INTVAL status);
+    }
+
+/*
+
+=item C<METHOD read(INTVAL bytes)>
+
+Read the given number of bytes from the gziphandle and return them in a string.
+
+=cut
+
+*/
+    METHOD read(INTVAL length) {
+        INTVAL result;
+        gzFile file;
+        STRING *str = STRINGNULL;
+        CHAR * const buf = mem_sys_allocate_zeroed(length);
+        GET_ATTR_file(INTERP, SELF, file);
+        result = gzread(file, buf, length);
+        if (result > 0) {
+            str = Parrot_str_new(INTERP, buf, result);
+        }
+        mem_sys_free(buf);
+        RETURN(STRING *str);
+    }
+
+/*
+
+=item C<METHOD is_tty()>
+
+GzipHandles are never tty's, returns false.
+
+=cut
+
+*/
+    METHOD is_tty() {
+        RETURN(INTVAL 0);
+    }
 
 /*
 
@@ -61,13 +230,57 @@
 
 =over 4
 
-*/
+=item C<METHOD version()>
+
+Returns a string with the zlib version.
 
+*/
     METHOD version() {
         STRING *version = Parrot_str_new_constant(INTERP, zlibVersion());
         RETURN(STRING *version);
     }
 
+    METHOD compress(STRING *str) {
+        INTVAL rc;
+        UCHAR *buf;
+        STRING *dst = NULL;
+        UINTVAL srcLen, bufSize, dstLen;
+        CHAR *src = Parrot_str_to_cstring(INTERP, str);
+        if (NULL == src) {
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_ILL_INHERIT,
+                "failed to allocate");
+        }
+        srcLen = Parrot_str_byte_length(INTERP, str);
+        bufSize = 12 + srcLen + srcLen / 1000;
+        buf = mem_sys_allocate_zeroed(bufSize);
+        if (NULL == buf) {
+            Parrot_str_free_cstring(src);
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_ILL_INHERIT,
+                "failed to allocate");
+        }
+        rc = compress(buf, &dstLen, src, srcLen);
+        Parrot_str_free_cstring(src);
+        switch (rc) {
+          case Z_OK:
+            dst = Parrot_str_new(INTERP, buf, dstLen);
+            mem_sys_free(buf);
+            break;
+
+          case Z_MEM_ERROR:
+            mem_sys_free(buf);
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_ILL_INHERIT,
+                "not enough memory");
+            break;
+
+          case Z_BUF_ERROR:
+            mem_sys_free(buf);
+            Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_ILL_INHERIT,
+                "output buffer error");
+            break;
+        }
+        RETURN(STRING *dst);
+    }
+
 /*
 
 =back

Modified: trunk/t/dynpmc/gziphandle.t
==============================================================================
--- trunk/t/dynpmc/gziphandle.t	Fri Apr 23 18:30:48 2010	(r45940)
+++ trunk/t/dynpmc/gziphandle.t	Fri Apr 23 18:35:32 2010	(r45941)
@@ -21,13 +21,14 @@
     .include 'iglobals.pasm'
     .local pmc config_hash, interp
 
-    plan(2)
+    plan(3)
     interp = getinterp
     config_hash = interp[.IGLOBALS_CONFIG_HASH]
     $S0 = config_hash['has_zlib']
     unless $S0 goto no_zlib
 
     $P0 = loadlib 'gziphandle'
+    test_handle()
     test_version()
     .return()
 
@@ -37,10 +38,16 @@
 .end
 
 
-.sub 'test_version'
+.sub 'test_handle'
     $P0 = new 'GzipHandle'
     $S0 = typeof $P0
     is($S0, 'GzipHandle', 'GzipHandle typeof')
+    $I0 = does $P0, 'Handle'
+    ok($I0, 'does Handle')
+.end
+
+.sub 'test_version'
+    $P0 = new 'GzipHandle'
     $S0 =$P0.'version'()
     diag($S0)
     $I0 = index $S0, '1.'


More information about the parrot-commits mailing list