[svn:parrot] r48710 - trunk/src/pmc

bacek at svn.parrot.org bacek at svn.parrot.org
Sat Aug 28 11:44:33 UTC 2010


Author: bacek
Date: Sat Aug 28 11:44:33 2010
New Revision: 48710
URL: https://trac.parrot.org/parrot/changeset/48710

Log:
Try to read whole file in FileHandle.readall. Closes #1749

Modified:
   trunk/src/pmc/filehandle.pmc

Modified: trunk/src/pmc/filehandle.pmc
==============================================================================
--- trunk/src/pmc/filehandle.pmc	Sat Aug 28 09:40:23 2010	(r48709)
+++ trunk/src/pmc/filehandle.pmc	Sat Aug 28 11:44:33 2010	(r48710)
@@ -438,46 +438,67 @@
 */
 
     METHOD readall(STRING *name :optional, INTVAL got_name :opt_flag) {
-        STRING *result;
+        PMC    *filehandle;
+        STRING *result      = STRINGNULL;
+        size_t  size        = 0;
 
         if (got_name) {
             /* called as class method - open, slurp, close file */
-            PMC    *filehandle;
             STRING *encoding;
-            size_t  size;
-
-            GET_ATTR_encoding(INTERP, SELF, encoding);
 
             if (!Parrot_io_is_closed_filehandle(INTERP, SELF))
                 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_PIO_ERROR,
                     "Cannot readall on a new file from an already open filehandle");
 
-            filehandle  = Parrot_io_open(INTERP, PMCNULL, name, NULL);
+            GET_ATTR_encoding(INTERP, SELF, encoding);
 
+            filehandle  = Parrot_io_open(INTERP, PMCNULL, name, NULL);
             PARROT_ASSERT(filehandle->vtable->base_type == enum_class_FileHandle);
 
             SET_ATTR_encoding(INTERP, filehandle, encoding);
             size = (size_t)(Parrot_stat_info_intval(INTERP, name, STAT_FILESIZE));
-
-            result = Parrot_io_reads(INTERP, filehandle, size);
-            Parrot_io_close(INTERP, filehandle);
         }
         else {
-            /* slurp open file */
+            /* Just get size of already opened file */
+            STRING *filename;
+            Parrot_runloop   jump_point;
+
             if (Parrot_io_is_closed_filehandle(INTERP, SELF))
                 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_PIO_ERROR,
                     "Cannot readall without a file name or open filehandle");
 
-            /* Do line buffering on the filehandle */
-            if (!(PARROT_FILEHANDLE(SELF)->flags & PIO_F_LINEBUF))
-                Parrot_io_setlinebuf(INTERP, SELF);
+            GET_ATTR_filename(INTERP, SELF, filename);
 
-            result = STRINGNULL;
-            do {
-                STRING * const part = Parrot_io_reads(INTERP, SELF, 0);
-                result = STRING_IS_NULL(result) ? part :
+            /* stat_info ca throw exception. Switch to chunked loading */
+            if (setjmp(jump_point.resume)) {
+                /* caught exception */
+                Parrot_cx_delete_handler_local(interp,
+                    Parrot_str_new_constant(interp, "exception"));
+
+                /* Do line buffering on the filehandle */
+                if (!(PARROT_FILEHANDLE(SELF)->flags & PIO_F_LINEBUF))
+                    Parrot_io_setlinebuf(INTERP, SELF);
+
+                do {
+                    STRING * const part = Parrot_io_reads(INTERP, SELF, 0);
+                    result = STRING_IS_NULL(result) ? part :
                         Parrot_str_concat(INTERP, result, part);
-            } while (!Parrot_io_eof(INTERP, SELF));
+                } while (!Parrot_io_eof(INTERP, SELF));
+            }
+            else {
+                /* run normally */
+                Parrot_ex_add_c_handler(interp, &jump_point);
+
+                size = (size_t)(Parrot_stat_info_intval(INTERP, filename, STAT_FILESIZE));
+                filehandle = SELF;
+            }
+        }
+
+        if (size)
+            result = Parrot_io_reads(INTERP, filehandle, size);
+
+        if (got_name) {
+            Parrot_io_close(INTERP, filehandle);
         }
 
         RETURN(STRING *result);


More information about the parrot-commits mailing list