[svn:parrot] r39314 - in branches/io_rewiring: src/io src/pmc t/pmc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Tue Jun 2 01:17:47 UTC 2009


Author: whiteknight
Date: Tue Jun  2 01:17:46 2009
New Revision: 39314
URL: https://trac.parrot.org/parrot/changeset/39314

Log:
[io_rewiring] changes from the weekend. Convert the read and write methods. Lots of fixes throughout

Modified:
   branches/io_rewiring/src/io/api.c
   branches/io_rewiring/src/pmc/filehandle.pmc
   branches/io_rewiring/src/pmc/pipe.pmc
   branches/io_rewiring/src/pmc/stringhandle.pmc
   branches/io_rewiring/t/pmc/io.t

Modified: branches/io_rewiring/src/io/api.c
==============================================================================
--- branches/io_rewiring/src/io/api.c	Tue Jun  2 00:45:33 2009	(r39313)
+++ branches/io_rewiring/src/io/api.c	Tue Jun  2 01:17:46 2009	(r39314)
@@ -19,6 +19,10 @@
 The C<FileHandle> PMC provides the class-based interface for filehandles that
 is used in Parrot ops.
 
+TODO: Where possible, extract some of the filehandle-related details into
+src/io/filehandle.c, and extract the stringhandle details into
+src/io/io_string.c.
+
 =cut
 
 */
@@ -118,30 +122,35 @@
     ASSERT_ARGS(Parrot_io_open)
     PMC *new_filehandle, *filehandle;
     INTVAL flags;
-
-    if (PMC_IS_NULL(pmc))
+    if (PMC_IS_NULL(pmc)) {
         /* TODO: We should look up the HLL mapped type, instead of always
            using FileHandle here */
         new_filehandle = pmc_new(interp, enum_class_FileHandle);
-    else {
-        if (!VTABLE_does(interp, pmc, CONST_STRING(interp, "file")))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Can only open a PMC that does 'file'");
-        new_filehandle = pmc;
+        PARROT_ASSERT(new_filehandle->vtable->base_type == enum_class_FileHandle);
     }
+    else
+        new_filehandle = pmc;
 
     flags = Parrot_io_parse_open_flags(interp, mode);
-    filehandle = PIO_OPEN(interp, new_filehandle, path, flags);
-
-    if (PMC_IS_NULL(filehandle))
+    if (VTABLE_does(interp, new_filehandle, CONST_STRING(interp, "file"))) {
+        PARROT_ASSERT(new_filehandle->vtable->base_type == enum_class_FileHandle);
+        filehandle = PIO_OPEN(interp, new_filehandle, path, flags);
+        if (PMC_IS_NULL(filehandle))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Unable to open filehandle from path '%S'", path);
+        PARROT_ASSERT(filehandle->vtable->base_type == enum_class_FileHandle);
+        SETATTR_FileHandle_flags(interp, new_filehandle, flags);
+        SETATTR_FileHandle_filename(interp, new_filehandle, path);
+        SETATTR_FileHandle_mode(interp, new_filehandle, mode);
+        Parrot_io_setbuf(interp, filehandle, PIO_UNBOUND);
+    }
+    else if (VTABLE_does(interp, new_filehandle, CONST_STRING(interp, "string"))) {
+        SETATTR_StringHandle_flags(interp, pmc, flags);
+        filehandle = pmc;
+    }
+    else
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-            "Unable to open filehandle from path '%S'",
-            path);
-
-    SETATTR_FileHandle_flags(interp, new_filehandle, flags);
-    SETATTR_FileHandle_filename(interp, new_filehandle, path);
-    SETATTR_FileHandle_mode(interp, new_filehandle, mode);
-    Parrot_io_setbuf(interp, filehandle, PIO_UNBOUND);
+            "Attempt to open a PMC with unknown roles");
     return filehandle;
 }
 
@@ -319,6 +328,9 @@
 {
     ASSERT_ARGS(Parrot_io_reads)
     STRING *result = NULL;
+    if (PMC_IS_NULL(pmc) || !VTABLE_does(interp, pmc, CONST_STRING(interp, "read")))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+            "Attempt to read from null or invalid PMC");
     if (VTABLE_does(interp, pmc, CONST_STRING(interp, "file"))) {
         INTVAL  ignored;
 
@@ -384,8 +396,39 @@
 {
     ASSERT_ARGS(Parrot_io_readline)
     STRING *result;
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "readline"), "->S",
-            &result);
+    if (VTABLE_does(interp, pmc, CONST_STRING(interp, "file"))) {
+        INTVAL flags;
+        if (Parrot_io_is_closed_filehandle(interp, pmc))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Cannot read from a closed filehandle");
+        GETATTR_FileHandle_flags(interp, pmc, flags);
+        if (!(flags & PIO_F_LINEBUF))
+            Parrot_io_setlinebuf(interp, pmc);
+
+        result = Parrot_io_reads(interp, pmc, 0);
+    }
+    else if (VTABLE_does(interp, pmc, CONST_STRING(interp, "string"))) {
+        INTVAL offset, newline_pos, read_length, orig_length;
+
+        GETATTR_StringHandle_stringhandle(interp, pmc, result);
+        if (STRING_IS_NULL(result))
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+                "Cannot read from a closed stringhandle");
+
+        orig_length = Parrot_str_byte_length(interp, result);
+        GETATTR_StringHandle_read_offset(interp, pmc, offset);
+        newline_pos = Parrot_str_find_index(interp, result, CONST_STRING(interp, "\n"), offset);
+
+        /* No newline found, read the rest of the string. */
+        if (newline_pos == -1)
+            read_length = orig_length - offset;
+        else
+            read_length = newline_pos - offset + 1; /* +1 to include the newline */
+
+        result = Parrot_str_substr(interp, result, offset,
+                read_length, NULL, 0);
+        SETATTR_StringHandle_read_offset(interp, pmc, newline_pos + 1);
+    }
     return result;
 }
 
@@ -441,7 +484,8 @@
 Parrot_io_seek(PARROT_INTERP, ARGMOD(PMC *pmc), PIOOFF_T offset, INTVAL w)
 {
     ASSERT_ARGS(Parrot_io_seek)
-    if (Parrot_io_is_closed(interp, pmc))
+    if (!VTABLE_does(interp, pmc, CONST_STRING(interp, "file")) 
+     || Parrot_io_is_closed(interp, pmc))
         return -1;
 
     return Parrot_io_seek_buffer(interp, pmc, offset, w);
@@ -463,7 +507,8 @@
 Parrot_io_tell(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_io_tell)
-    if (Parrot_io_is_closed(interp, pmc))
+    if (!VTABLE_does(interp, pmc, CONST_STRING(interp, "file")) 
+     || Parrot_io_is_closed(interp, pmc))
         return -1;
 
     return Parrot_io_get_file_position(interp, pmc);
@@ -487,7 +532,8 @@
 Parrot_io_peek(PARROT_INTERP, ARGMOD(PMC *pmc), ARGOUT(STRING **buffer))
 {
     ASSERT_ARGS(Parrot_io_peek)
-    if (Parrot_io_is_closed(interp, pmc))
+    if (!VTABLE_does(interp, pmc, CONST_STRING(interp, "file")) 
+     || Parrot_io_is_closed(interp, pmc))
         return -1;
 
     return Parrot_io_peek_buffer(interp, pmc, buffer);
@@ -510,19 +556,23 @@
 Parrot_io_eof(PARROT_INTERP, ARGMOD(PMC *pmc))
 {
     ASSERT_ARGS(Parrot_io_eof)
-    INTVAL result;
+    INTVAL flags;
 
     /* io could be null here, but rather than return a negative error
      * we just fake EOF since eof test is usually in a boolean context.
      */
-    if (PMC_IS_NULL(pmc))
-            return 1;
-
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "eof"), "->I",
-            &result);
+    if (PMC_IS_NULL(pmc)
+     || !VTABLE_does(interp, pmc, CONST_STRING(interp, "file")) 
+     || Parrot_io_is_closed(interp, pmc))
+        return 1;
+    if (Parrot_io_is_closed_filehandle(interp, pmc))
+        return 1;
 
-    return result;
+    GETATTR_FileHandle_flags(interp, pmc, flags);
+    if (flags & PIO_F_EOF)
+        return 1;
 
+    return 0;
 }
 
 /*
@@ -564,9 +614,21 @@
     if (PMC_IS_NULL(pmc))
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
             "Cannot write to null PMC");
+    if (STRING_IS_NULL(s))
+        return 0;
+    if (!VTABLE_does(interp, pmc, CONST_STRING(interp, "write")))
+        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
+            "Target PMC is not writable");
+    if (VTABLE_does(interp, pmc, CONST_STRING(interp, "file"))) {
+        INTVAL flags;
+        GETATTR_FileHandle_flags(interp, pmc, flags);
+
+        if (Parrot_io_is_encoding(interp, pmc, CONST_STRING(interp, "utf8")))
+            result = Parrot_io_write_utf8(interp, pmc, s);
+        else
+            result = Parrot_io_write_buffer(interp, pmc, s);
+    }
 
-    Parrot_PCCINVOKE(interp, pmc, CONST_STRING(interp, "puts"), "S->I",
-            s, &result);
     return result;
 
 }

Modified: branches/io_rewiring/src/pmc/filehandle.pmc
==============================================================================
--- branches/io_rewiring/src/pmc/filehandle.pmc	Tue Jun  2 00:45:33 2009	(r39313)
+++ branches/io_rewiring/src/pmc/filehandle.pmc	Tue Jun  2 01:17:46 2009	(r39314)
@@ -102,12 +102,12 @@
         Parrot_FileHandle_attributes * const attrs = PARROT_FILEHANDLE(SELF);
         if (Parrot_str_equal(interp, role, CONST_STRING(interp, "file")))
             return 1;
-        if (attrs->flags != 0) {
-            if((attrs->flags & PIO_F_READ) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "read")))
+        if (attrs->flags != 0 && !Parrot_io_is_closed(INTERP, SELF)) {
+            if ((attrs->flags & PIO_F_READ) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "read")))
                 return 1;
-            if((attrs->flags & PIO_F_WRITE) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "write")))
+            if ((attrs->flags & PIO_F_WRITE) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "write")))
                 return 1;
-            if((attrs->flags & PIO_F_APPEND) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "append")))
+            if ((attrs->flags & PIO_F_APPEND) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "append")))
                 return 1;
         }
         return SUPER(role);
@@ -367,11 +367,7 @@
 
     METHOD readline() {
         STRING *string_result;
-        if (!(PARROT_FILEHANDLE(SELF)->flags & PIO_F_LINEBUF))
-            Parrot_io_setlinebuf(INTERP, SELF);
-
-        string_result = Parrot_io_reads(INTERP, SELF, 0);
-
+        string_result = Parrot_io_readline(INTERP, SELF);
         RETURN(STRING *string_result);
     }
 
@@ -461,6 +457,7 @@
                                 "Cannot readall on a new file from an already open filehandle");
             }
             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));
 
@@ -534,30 +531,8 @@
 */
 
     METHOD puts(STRING *to_print) {
-        INTVAL flags, status;
-        if (Parrot_io_is_closed_filehandle(interp, SELF))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot write to a closed filehandle");
-
-        GET_ATTR_flags(INTERP, SELF, flags);
-        if (!(flags & PIO_F_WRITE))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot write to a filehandle not opened for write");
-
-        if (STRING_IS_NULL(to_print))
-            RETURN(INTVAL 0);
-
-#if ! DISABLE_GC_DEBUG
-        /* trigger GC for debug - but not during tests */
-        if (0 && GC_DEBUG(interp))
-            Parrot_gc_mark_and_sweep(interp, GC_trace_stack_FLAG);
-#endif
-
-        if (Parrot_io_is_encoding(interp, SELF, CONST_STRING(interp, "utf8")))
-            status = Parrot_io_write_utf8(interp, SELF, to_print);
-        else
-            status = Parrot_io_write_buffer(interp, SELF, to_print);
-
+        INTVAL status;
+        status = Parrot_io_putps(INTERP, SELF, to_print);
         RETURN(INTVAL status);
     }
 
@@ -697,14 +672,8 @@
 
     METHOD eof() {
         INTVAL flags;
-        if (Parrot_io_is_closed_filehandle(interp, SELF))
-            RETURN(INTVAL 1);
-
-        GET_ATTR_flags(INTERP, SELF, flags);
-        if (flags & PIO_F_EOF)
-            RETURN(INTVAL 1);
-
-        RETURN(INTVAL 0);
+        flags = Parrot_io_eof(INTERP, SELF);
+        RETURN(INTVAL flags);
     }
 
 

Modified: branches/io_rewiring/src/pmc/pipe.pmc
==============================================================================
--- branches/io_rewiring/src/pmc/pipe.pmc	Tue Jun  2 00:45:33 2009	(r39313)
+++ branches/io_rewiring/src/pmc/pipe.pmc	Tue Jun  2 01:17:46 2009	(r39314)
@@ -83,6 +83,21 @@
         return SELF;
     }
 
+/*
+
+=item C<INTVAL does(STRING * role)>
+
+=cut
+
+*/
+
+    VTABLE INTVAL does(STRING * role) {
+        if (Parrot_str_equal(INTERP, role, CONST_STRING(INTERP, "pipe")))
+            return 1;
+        /* TODO: Pipe should does read or write also, depending on what
+           type of pipe it is */
+        return SUPER(role);
+    }
 
 /*
 

Modified: branches/io_rewiring/src/pmc/stringhandle.pmc
==============================================================================
--- branches/io_rewiring/src/pmc/stringhandle.pmc	Tue Jun  2 00:45:33 2009	(r39313)
+++ branches/io_rewiring/src/pmc/stringhandle.pmc	Tue Jun  2 01:17:46 2009	(r39314)
@@ -90,8 +90,17 @@
 */
 
     VTABLE INTVAL does(STRING * role) {
-        if (Parrot_str_equal(INTERP, SELF, CONST_STRING(INTERP, "string")))
+        Parrot_StringHandle_attributes * const attrs = PMC_data(SELF);
+        if (Parrot_str_equal(INTERP, role, CONST_STRING(INTERP, "string")))
             return 1;
+        if (attrs->flags != 0 && !STRING_IS_NULL(attrs->stringhandle)) {
+            if((attrs->flags & PIO_F_READ) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "read")))
+                return 1;
+            if((attrs->flags & PIO_F_WRITE) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "write")))
+                return 1;
+            if((attrs->flags & PIO_F_APPEND) && Parrot_str_equal(interp, role, CONST_STRING(INTERP, "append")))
+                return 1;
+        }
         return SUPER(role);
     }
 
@@ -206,8 +215,7 @@
             SET_ATTR_mode(INTERP, SELF, open_mode);
         }
 
-        flags = Parrot_io_parse_open_flags(interp, open_mode);
-        SET_ATTR_flags(INTERP, SELF, flags);
+        Parrot_io_open(INTERP, SELF, filename, open_mode);
 
         RETURN(PMC *SELF);
     }
@@ -270,6 +278,7 @@
 
     METHOD read(INTVAL length) {
         STRING *string_result;
+        string_result = Parrot_io_reads(INTERP, SELF, length);
         RETURN(STRING *string_result);
     }
 
@@ -286,27 +295,7 @@
 
     METHOD readline() {
         STRING *string_result;
-        INTVAL offset, newline_pos, read_length, orig_length;
-
-        GET_ATTR_stringhandle(INTERP, SELF, string_result);
-        if (STRING_IS_NULL(string_result))
-            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
-                "Cannot read from a closed filehandle");
-
-        orig_length = Parrot_str_byte_length(INTERP, string_result);
-        GET_ATTR_read_offset(INTERP, SELF, offset);
-        newline_pos = Parrot_str_find_index(INTERP, string_result, CONST_STRING(INTERP, "\n"), offset);
-
-        /* No newline found, read the rest of the string. */
-        if (newline_pos == -1)
-            read_length = orig_length - offset;
-        else
-            read_length = newline_pos - offset + 1; /* +1 to include the newline */
-
-        string_result = Parrot_str_substr(INTERP, string_result, offset,
-                read_length, NULL, 0);
-        SET_ATTR_read_offset(INTERP, SELF, newline_pos + 1);
-
+        string_result = Parrot_io_readline(INTERP, SELF);
         RETURN(STRING *string_result);
     }
 

Modified: branches/io_rewiring/t/pmc/io.t
==============================================================================
--- branches/io_rewiring/t/pmc/io.t	Tue Jun  2 00:45:33 2009	(r39313)
+++ branches/io_rewiring/t/pmc/io.t	Tue Jun  2 01:17:46 2009	(r39314)
@@ -7,7 +7,7 @@
 use lib qw( . lib ../lib ../../lib );
 
 use Test::More;
-use Parrot::Test tests => 42;
+use Parrot::Test tests => 41;
 use Parrot::Test::Util 'create_tempfile';
 use Parrot::Test::Util 'create_tempfile';
 
@@ -39,58 +39,6 @@
     close $FOO;
 }
 
-TODO: {
-    local $TODO = "IO on some invalid types";
-
-    pir_output_is( <<'CODE', <<'OUTPUT', "IO on some invalid types" );
-.sub main
-    $P0 = null
-    test($P0, "Undef")
-    new $P0, ['Integer']
-    test($P0, "null")
-    new $P0, ['Undef']
-    test($P0, "Integer")
-    new $P0, ['String']
-    test($P0, "String")
-.end
-.sub test
-    .param pmc io
-    .param string name
-
-    print name
-    read $S0, io, 1
-    length $I0, $S0
-    if $I0 == 0 goto ok1
-    print " not"
-ok1:
-    print " ok 1\n"
-
-    print name
-    # what should happen here?
-    close io
-    print " ok 2\n"
-
-    print name
-    # what should happen here?
-    print io, "not"
-    print " ok 3\n"
-.end
-CODE
-Undef ok 1
-Undef ok 2
-Undef ok 3
-null ok 1
-null ok 2
-null ok 3
-Integer ok 1
-Integer ok 2
-Integer ok 3
-String ok 1
-String ok 2
-String ok 3
-OUTPUT
-}
-
 my (undef, $temp_file) = create_tempfile( UNLINK => 1 );
 
 pasm_output_is( <<"CODE", <<'OUTPUT', "open/close" );


More information about the parrot-commits mailing list