/* Reads the file from the current position to the end into a string. */ static MVMString * slurp(MVMThreadContext *tc, MVMOSHandle *h) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; uv_fs_t req; ensure_decode_stream(tc, data); /* Typically we're slurping an entire file, so just request the bytes * until the end; repeat to ensure we get 'em all. */ if (uv_fs_fstat(tc->loop, &req, data->fd, NULL) < 0) { MVM_exception_throw_adhoc(tc, "slurp from filehandle failed: %s", uv_strerror(req.result)); } while (read_to_buffer(tc, data, req.statbuf.st_size) > 0) ; return MVM_string_decodestream_get_all(tc, data->ds); }
/* Reads a single line from the file handle. May serve it from a buffer, if we * already read enough data. */ static MVMString * read_line(MVMThreadContext *tc, MVMOSHandle *h) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; ensure_decode_stream(tc, data); /* Pull data until we can read a line. */ do { MVMString *line = MVM_string_decodestream_get_until_sep(tc, data->ds, data->sep); if (line != NULL) return line; } while (read_to_buffer(tc, data, CHUNK_SIZE) > 0); /* Reached end of file, or last (non-termianted) line. */ return MVM_string_decodestream_get_all(tc, data->ds); }
/* Gets the specified number of characters from the file. */ static MVMString * read_chars(MVMThreadContext *tc, MVMOSHandle *h, MVMint64 chars) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; ensure_decode_stream(tc, data); /* Pull data until we can read the chars we want. */ do { MVMString *result = MVM_string_decodestream_get_chars(tc, data->ds, chars); if (result != NULL) return result; } while (read_to_buffer(tc, data, CHUNK_SIZE) > 0); /* Reached end of file, so just take what we have. */ return MVM_string_decodestream_get_all(tc, data->ds); }
/* Reads the specified number of bytes into a the supplied buffer, returing * the number actually read. */ static MVMint64 read_bytes(MVMThreadContext *tc, MVMOSHandle *h, char **buf, MVMint64 bytes) { MVMIOFileData *data = (MVMIOFileData *)h->body.data; ensure_decode_stream(tc, data); /* Keep requesting bytes until we have enough in the buffer or we hit * end of file. */ while (!MVM_string_decodestream_have_bytes(tc, data->ds, bytes)) { if (read_to_buffer(tc, data, bytes) <= 0) break; } /* Read as many as we can, up to the limit. */ return MVM_string_decodestream_bytes_to_buf(tc, data->ds, buf, bytes); }
/* Gets the specified number of characters from the stream. */ MVMString * MVM_io_syncstream_read_chars(MVMThreadContext *tc, MVMOSHandle *h, MVMint64 chars) { MVMIOSyncStreamData *data = (MVMIOSyncStreamData *)h->body.data; MVMString *result; ensure_decode_stream(tc, data); /* Do we already have the chars available? */ result = MVM_string_decodestream_get_chars(tc, data->ds, chars); if (result) { return result; } else { /* No; read and try again. */ read_to_buffer(tc, data, CHUNK_SIZE); result = MVM_string_decodestream_get_chars(tc, data->ds, chars); if (result != NULL) return result; } /* Fetched all we immediately can, so just take what we have. */ return MVM_string_decodestream_get_all(tc, data->ds); }