Change the fread primitive to fread-unsafe, matching the new primitive in the VM, and update the implementation of c-reader to implement stream-read-unsafe and stream-read in terms of fread-unsafe
\ float>fixnum { float } { fixnum } define-primitive \ bignum>fixnum make-foldable
\ fpu-state { } { } define-primitive
\ fputc { object alien } { } define-primitive
-\ fread { integer alien } { object } define-primitive
+\ fread-unsafe { integer c-ptr alien } { integer } define-primitive
\ fseek { integer integer alien } { } define-primitive
\ ftell { alien } { integer } define-primitive
\ fwrite { c-ptr integer alien } { } define-primitive
{ "fflush" "io.streams.c" "primitive_fflush" (( alien -- )) }
{ "fgetc" "io.streams.c" "primitive_fgetc" (( alien -- ch/f )) }
{ "fputc" "io.streams.c" "primitive_fputc" (( ch alien -- )) }
- { "fread" "io.streams.c" "primitive_fread" (( n alien -- str/f )) }
+ { "fread-unsafe" "io.streams.c" "primitive_fread" (( n buf alien -- count )) }
{ "fseek" "io.streams.c" "primitive_fseek" (( alien offset whence -- )) }
{ "ftell" "io.streams.c" "primitive_ftell" (( alien -- n )) }
{ "fwrite" "io.streams.c" "primitive_fwrite" (( data length alien -- )) }
fflush
fclose
fgetc
- fread
+ fread-unsafe
}
"The three standard file handles:"
{ $subsections
HELP: fgetc ( alien -- ch/f )
{ $values { "alien" "a C FILE* handle" } { "ch/f" "a character or " { $link f } } }
-{ $description "Reads a single character from a C FILE* handle, and outputs " { $link f } " on end of file." }
+{ $description "Reads a single byte from a C FILE* handle, and outputs " { $link f } " on end of file." }
{ $errors "Throws an error if the input operation failed." } ;
-HELP: fread ( n alien -- str/f )
-{ $values { "n" "a positive integer" } { "alien" "a C FILE* handle" } { "str/f" { $maybe string } } }
-{ $description "Reads a sequence of characters from a C FILE* handle, and outputs " { $link f } " on end of file." }
+HELP: fputc ( alien -- ch/f )
+{ $values { "alien" "a C FILE* handle" } { "ch/f" "a character or " { $link f } } }
+{ $description "Reads a single byte from a C FILE* handle, and outputs " { $link f } " on end of file." }
+{ $errors "Throws an error if the input operation failed." } ;
+
+HELP: fread-unsafe ( n buf alien -- str/f )
+{ $values { "n" "a positive integer" } { "buf" c-ptr } { "alien" "a C FILE* handle" } { "count" integer } }
+{ $description "Reads " { $snippet "n" } " bytes from a C FILE* handle into the memory referenced by " { $snippet "buf" } ", and outputs the number of characters read. Zero is output on end of file." }
+{ $warning "This word does not check whether " { $snippet "buf" } " is large enough to accommodate the requested number of bytes. Memory corruption will occur if this is not the case." }
{ $errors "Throws an error if the input operation failed." } ;
HELP: stdin-handle
{
{ seek-absolute [ 0 ] }
{ seek-relative [ 1 ] }
- { seek-end [ 2 ] }
+ { seek-end [ 2 ] }
[ bad-seek-type ]
} case
] [ handle>> ] bi* fseek ;
M: c-reader stream-element-type drop +byte+ ;
-M: c-reader stream-read dup check-disposed handle>> fread ;
+M: c-reader stream-read-unsafe dup check-disposed handle>> fread-unsafe ;
+M: c-reader stream-read
+ [ dup <byte-array> ] dip
+ [ stream-read-unsafe ] curry keep
+ over 0 = [ 2drop f ] [ resize-byte-array ] if ;
+M: c-reader stream-read-partial-unsafe stream-read-unsafe ;
M: c-reader stream-read-partial stream-read ;
M: c-reader stream-read1 dup check-disposed handle>> fgetc ;