[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