[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