[svn:parrot] r49646 - in trunk: . src/io t/pmc

nwellnhof at svn.parrot.org nwellnhof at svn.parrot.org
Sun Oct 24 20:08:37 UTC 2010


Author: nwellnhof
Date: Sun Oct 24 20:08:36 2010
New Revision: 49646
URL: https://trac.parrot.org/parrot/changeset/49646

Log:
[io] Fix unbuffered read

Unbuffered reads with sizes below 2048 seem to have been broken
for quite a while. Also includes a small fix to line-buffered reads
after EOF.

Added:
   trunk/t/pmc/io_stdin.t
Modified:
   trunk/MANIFEST
   trunk/src/io/buffer.c
   trunk/t/pmc/io.t

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST	Sun Oct 24 12:14:32 2010	(r49645)
+++ trunk/MANIFEST	Sun Oct 24 20:08:36 2010	(r49646)
@@ -1900,6 +1900,7 @@
 t/pmc/io.t                                                  [test]
 t/pmc/io_iterator.t                                         [test]
 t/pmc/io_status.t                                           [test]
+t/pmc/io_stdin.t                                            [test]
 t/pmc/iterator.t                                            [test]
 t/pmc/key.t                                                 [test]
 t/pmc/lexinfo.t                                             [test]

Modified: trunk/src/io/buffer.c
==============================================================================
--- trunk/src/io/buffer.c	Sun Oct 24 12:14:32 2010	(r49645)
+++ trunk/src/io/buffer.c	Sun Oct 24 20:08:36 2010	(r49646)
@@ -335,12 +335,13 @@
         size_t got;
 
         if (len >= Parrot_io_get_buffer_size(interp, filehandle)) {
-            STRING *sf;
+            STRING *sf  = Parrot_str_new_noinit(interp, len);
 
-            s->strlen = s->bufused = current + len;
-            sf        = STRING_substr(interp, s, current, len);
-            got       = PIO_READ(interp, filehandle, &sf);
-            s->strlen = s->bufused = current + got;
+            sf->bufused = len;
+            got         = PIO_READ(interp, filehandle, &sf);
+            s->strlen   = s->bufused = current + got;
+
+            memcpy(s->strstart + current, sf->strstart, got);
 
             Parrot_io_set_file_position(interp, filehandle,
                     (got + Parrot_io_get_file_position(interp, filehandle)));
@@ -469,8 +470,10 @@
 
     /* fill empty buffer */
     if (!(buffer_flags & PIO_BF_READBUF)) {
-        if (Parrot_io_fill_readbuf(interp, filehandle) == 0)
+        if (Parrot_io_fill_readbuf(interp, filehandle) == 0) {
+            s->bufused = 0;
             return 0;
+        }
     }
 
     /* Retrieve filled buffer */

Modified: trunk/t/pmc/io.t
==============================================================================
--- trunk/t/pmc/io.t	Sun Oct 24 12:14:32 2010	(r49645)
+++ trunk/t/pmc/io.t	Sun Oct 24 20:08:36 2010	(r49646)
@@ -291,10 +291,28 @@
     print $P0, "Howdy World\n"
 
     $P0.'close'()
+
+    $P0 = new ['FileHandle']
+    $P0.'open'(temp_file, 'r')
+
+#   set buffer type
+    $P0.'buffer_type'('unbuffered')
+
+#   get buffer type
+    $S0 = $P0.'buffer_type'()
+    print $S0
+    print "\n"
+
+    $S0 = $P0.'read'(50)
+    print $S0
+
+    $P0.'close'()
     end
 .end
 CODE
 unbuffered
+unbuffered
+Howdy World
 OUTPUT
 
 file_content_is( $temp_file, <<'OUTPUT', 'unbuffered file contents' );

Added: trunk/t/pmc/io_stdin.t
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/t/pmc/io_stdin.t	Sun Oct 24 20:08:36 2010	(r49646)
@@ -0,0 +1,152 @@
+#! perl
+# Copyright (C) 2010, Parrot Foundation.
+# $Id:$
+
+use strict;
+use warnings;
+use lib qw( . lib ../lib ../../lib );
+
+use Test::More tests => 3;
+use Parrot::Test;
+use Parrot::Config;
+
+use Parrot::Test::Util 'create_tempfile';
+
+=head1 NAME
+
+t/pmc/stdin-io.t - IO Ops from stdin
+
+=head1 SYNOPSIS
+
+    % prove t/pmc/io_stdin.t
+
+=head1 DESCRIPTION
+
+Tests the Parrot IO operations from stdin.
+
+=cut
+
+sub pir_stdin_output_is {
+    my ($input_string, $code, $expected_output, $test_name) = @_;
+
+    my $stuff = sub {
+	# Put the string on a file.
+	my $string = shift;
+
+	my (undef, $file) = create_tempfile(UNLINK => 1);
+	open(my $out, ">$file") or die "bug";
+	print $out $string;
+	return $file;
+    };
+
+    # Write the input and code strings.
+    my $input_file = $stuff->($input_string);
+    my $code_file = $stuff->($code);
+
+    # Slurp and compare the output.
+    my $result = do {
+	local $/;
+	open(my $in, "./parrot '$code_file' < '$input_file' |")
+	    or die "bug";
+	<$in>;
+    };
+    Test::More::is($result, $expected_output, $test_name);
+}
+
+pir_stdin_output_is(<<'INPUT', <<'CODE', <<'OUTPUT', 'simple stdin use');
+foo
+INPUT
+.sub test :main
+	.local pmc stdin
+	stdin = getstdin
+	read_str(stdin, 1)
+	read_str(stdin, 2)
+	read_str(stdin, 5)
+	read_str(stdin, 5)
+.end
+.sub read_str
+	.param pmc stream
+	.param int n_chars
+	.local string input_string
+	.local int len
+	input_string = stream.'read'(n_chars)
+	len = length input_string
+	print "got len "
+	print len
+	print ':  "'
+	print input_string
+	print "\"\n"
+.end
+CODE
+got len 1:  "f"
+got len 2:  "oo"
+got len 1:  "
+"
+got len 0:  ""
+OUTPUT
+
+pir_stdin_output_is(<<'INPUT', <<'CODE', <<'OUTPUT', 'readline from stdin');
+one
+two
+three
+INPUT
+.sub test :main
+	.local pmc stdin
+	stdin = getstdin
+	read_str(stdin)
+	read_str(stdin)
+	read_str(stdin)
+	read_str(stdin)
+.end
+.sub read_str
+	.param pmc stream
+	.local string input_string
+	.local int len
+	input_string = stream.'readline'()
+	len = length input_string
+	print "got len "
+	print len
+	print ':  "'
+	print input_string
+	print "\"\n"
+.end
+CODE
+got len 4:  "one
+"
+got len 4:  "two
+"
+got len 6:  "three
+"
+got len 0:  ""
+OUTPUT
+
+pir_stdin_output_is(<<'INPUT', <<'CODE', <<'OUTPUT', 'readall from stdin');
+one
+two
+three
+INPUT
+.sub test :main
+	.local pmc stdin
+	stdin = getstdin
+	read_str(stdin)
+	read_str(stdin)
+.end
+.sub read_str
+	.param pmc stream
+	.local string input_string
+	.local int len
+	input_string = stream.'readall'()
+	len = length input_string
+	print "got len "
+	print len
+	print ':  "'
+	print input_string
+	print "\"\n"
+.end
+CODE
+got len 14:  "one
+two
+three
+"
+got len 0:  ""
+OUTPUT


More information about the parrot-commits mailing list