You got the wrong userdata. Basically you are passing pointer to your own Writer interface, to the underlying writer which expects pointer to its own Writer interface. Should be
const n = try self.inner.vtable.drain(self.inner, data, splat);
Otherwise looking good. Took me a while to spot the issue.
Thanks @psznm , @xeubie and @lalinsky for all the good examples and advices. Iâll mark this as solution, because its working code; so anyone who is looking to solve a similar task finds it. But of course, I would not have worked it out (this fast or maybe ever?) without help of the named users!!
I took the inspirations and tipps from this thread and implemented wrapping Reader and Writer for the http requests of the S3 lib z3. I hope this is might help somebody who has a similar task to solve. And of course thanks again to anybody who answered in this thread!
Did this work out well for you? I found myself in need of something similiar, I also implemented it by calling vtable of underlying reader/writer. Specifically net.Stream.Reader and net.Stream.Writer. And found the counts I was getting very suspicious.
I found that Reader.readVec will hide bytes from you (those that it stores into buffer internally), and its stream also calls that. I found that finding the actual bytes read can only be done by actually copying the underlying implementation, or by doing counts relying on precise knowledge of underlying implementation. So with reader this works best if the underlying reader has no buffer.
For writer I found similiar thing, if I want to have a buffer on the wrapping writer (some things require it) and drain correctly, I need to pass the buffer to the underlying writer. Then it will also not report the data drained from buffer so I need to account for that when counting.
I see. That explains things. I had to jump through some additional hoops to get correct behavior when wrapping Io.Reader and Io.Writer from net.Stream.Reader and net.Stream.Writer
EDIT: if anybody comes here looking for answers (I think this should work correctly for any underlying reader/write as long as the underlying reader/writer does not have to have a buffer):