int fp_utf8;
Size_t got = 0;
Size_t wanted;
+ bool charstart = NULL;
+ STRLEN skip;
+ STRLEN charskip;
gv = (GV*)*++MARK;
if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD)
DIE(aTHX_ "Negative length");
wanted = length;
+ charstart = TRUE;
+ charskip = 0;
+
#ifdef HAS_SOCKET
if (PL_op->op_type == OP_RECV) {
char namebuf[MAXPATHLEN];
/* Look at utf8 we got back and count the characters */
char *bend = buffer + count;
while (buffer < bend) {
- STRLEN skip = UTF8SKIP(buffer);
- if (buffer+skip > bend) {
+ if (charstart) {
+ skip = UTF8SKIP(buffer);
+ charskip = 0;
+ }
+ if (buffer - charskip + skip > bend) {
/* partial character - try for rest of it */
length = skip - (bend-buffer);
offset = bend - SvPVX(bufsv);
+ charstart = FALSE;
+ charskip += count;
goto more_bytes;
}
else {
got++;
buffer += skip;
+ charstart = TRUE;
+ charskip = 0;
}
}
/* If we have not 'got' the number of _characters_ we 'wanted' get some more
provided amount read (count) was what was requested (length)
*/
if (got < wanted && count == length) {
- length = (wanted-got);
+ length = wanted - got;
offset = bend - SvPVX(bufsv);
goto more_bytes;
}
no utf8; # needed for use utf8 not griping about the raw octets
$| = 1;
-my $total_tests = 25;
-if (ord('A') == 193) { $total_tests = 24; } # EBCDIC platforms do not warn on UTF-8
-print "1..$total_tests\n";
+print "1..26\n";
open(F,"+>:utf8",'a');
print F chr(0x100).'£';
print "ok 24\n";
# Now we have a deformed file.
-open F, "<:utf8", "a" or die $!;
-$x = <F>; chomp $x;
-{ local $SIG{__WARN__} = sub { print "ok 25\n"; };
-eval { sprintf "%vd\n", $x; }
+
+if (ord('A') == 193) {
+ print "ok 25 # Skip: EBCDIC\n"; # EBCDIC doesn't complain
+} else {
+ open F, "<:utf8", "a" or die $!;
+ $x = <F>; chomp $x;
+ local $SIG{__WARN__} = sub { print "ok 25\n" };
+ eval { sprintf "%vd\n", $x };
}
close F;
unlink('a');
+open F, ">a";
+@a = map { chr(1 << ($_ << 2)) } 0..5; # 0x1, 0x10, .., 0x100000
+print F @a;
+close F;
+open F, "<:utf8", "a";
+$a = 0;
+for (@a) {
+ unless (read(F, $b, 1) == 1 &&
+ length($b) == 1 &&
+ ord($b) == ord($_) &&
+ tell(F) == ($a += bytes::length($b))) {
+ print '# ord($_) == ', ord($_), "\n";
+ print '# ord($b) == ', ord($b), "\n";
+ print '# length($b) == ', length($b), "\n";
+ print '# tell(F) == ', tell(F), "\n";
+ print "not ";
+ last;
+ }
+}
+print "ok 26\n";
+
+END { 1 while unlink "a" }