Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add io stream primitives #1626

Merged
merged 7 commits into from
Nov 15, 2024
Merged

Conversation

konimarti
Copy link
Contributor

Add io stream primitives for the InStream and OutStream interfaces:

  • MultiReader
  • MultiWriter
  • TeeReader

Inspired by Golang's io package.

Implement a MultiReader (InStream) which sequentially read from the
provided readers (InStreams). Return IoError.EOF when all of the readers
are read.
Implement a MultiWriter (OutStream). The MultiWriter duplicates its
writes to all the provided writers (OutStream).
Implement a TeeReader (InStream) which reads from a wrapped reader
(InStream) and writes data to the provided writer (OutStream).
@konimarti
Copy link
Contributor Author

Ugh, sorry. All tests failed. After a cursory look it's not obvious to me why it failed. I'll have to look into this.

lib/std/io/io.c3 Outdated
@@ -42,6 +42,7 @@ fault IoError
UNKNOWN_ERROR,
UNSUPPORTED_OPERATION,
WOULD_BLOCK,
SHORT_WRITE,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between this one an "INCOMPLETE_WRITE"?

Copy link
Contributor Author

@konimarti konimarti Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have overlooked INCOMPLETE_WRITE. That expresses the intent of short write error. I'll adjust this and hope that the build error goes away.

fn MultiReader* MultiReader.new_init(&self, InStream... readers, Allocator allocator = allocator::heap())
{
usz n = readers.len;
InStream *ptr = allocator::new_array(allocator, InStream, n);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

allocator::new_array already returns a slice, so you can do:

InStream[] copy = allocator::new_array(allocator, InStream, readers.len);
copy[..] = readers[..];
*self = { .readers = copy, .allocator = allocator };
return self;

fn void MultiReader.free(&self)
{
if (!self.allocator) return;
if (void* ptr = self.readers.ptr) allocator::free(self.allocator, ptr);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This:

if (void* ptr = self.readers.ptr) allocator::free(self.allocator, ptr);

Can be replaced by:

allocator::free(self.allocator, self.readers);

fn MultiWriter* MultiWriter.new_init(&self, OutStream... writers, Allocator allocator = allocator::heap())
{
usz n = writers.len;
OutStream *ptr = allocator::new_array(allocator, OutStream, n);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same note as for the Reader

foreach (w : self.writers)
{
n = w.write(bytes)!;
if (n != bytes.len) return IoError.SHORT_WRITE?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INCOMPLETE_WRITE maybe?

fn void MultiWriter.free(&self)
{
if (!self.allocator) return;
if (void* ptr = self.writers.ptr) allocator::free(self.allocator, ptr);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the note on MultiReader.free

@param [&inout] r "Stream r to read from."
@param [&inout] w "Stream w to write to what it reads from r."
*>
fn TeeReader tee_reader(InStream r, OutStream w) => { r, w };
Copy link
Collaborator

@lerno lerno Nov 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could possibly be a macro or set to @inline

@lerno
Copy link
Collaborator

lerno commented Nov 15, 2024

Probably the added IO fault added the line number by one in a bunch of places and the test scripts are sensitive to that. I can fix it if you want. Did you need the "SHORT_WRITE" when there was INCOMPLETE_WRITE? If you remove SHORT_WRITE then it will probably just work for now.

@lerno lerno merged commit f3304ac into c3lang:master Nov 15, 2024
43 checks passed
@lerno
Copy link
Collaborator

lerno commented Nov 15, 2024

Thank you!

@konimarti konimarti deleted the add-io-stream-primitives branch November 15, 2024 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants