BufferedWriter
Owns a fixed-capacity byte cache and its concrete Writer source. Construction allocates; subsequent cache operations do not grow storage. External synchronization is required. Movement transfers the source and cache, leaving the old adapter closed. Destruction never performs hidden I/O.
Module std.io
import std.io;Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.
BufferedWriter
pub final class BufferedWriter<S> where S: Writer, MovableOwns a fixed-capacity byte cache and its concrete Writer source. Construction allocates; subsequent cache operations do not grow storage. External synchronization is required. Movement transfers the source and cache, leaving the old adapter closed. Destruction never performs hidden I/O. S: Movable structural Writer implementation.
A provider may report failure after accepting bytes. This workflow proves that the buffer retains only the tail and retries without duplicate output.
Example
module example.buffered_streams;
from std.io import BufferedReader, BufferedWriter, IoError;
from std.prelude import Result;
struct Source {
pub Written: usize;
pub ReadCount: usize;
pub FailNext: bool;
pub init() { this.Written = 0; this.ReadCount = 0; this.FailNext = true; }
pub fn Write(Input: readonly byte[]) -> Result<usize, IoError> {
if this.FailNext { this.FailNext = false; return .Err { Error = .Failure { Reason = .Interrupted, Transferred = 0 } }; }
if Input.Length == 0 { return .Ok { Value = 0 }; }
this.Written += 1; return .Ok { Value = 1 };
}
pub fn Flush() -> Result<void, IoError> { return .Ok; }
pub fn Read(Output: mut byte[]) -> Result<usize, IoError> {
if this.ReadCount != 0 || Output.Length == 0 { return .Ok { Value = 0 }; }
Output[0] = 0x61_byte; this.ReadCount += 1; return .Ok { Value = 1 };
}
}
fn Main() -> i32 {
var Writer = {
// Keep writable result storage through the explicit noncopy payload transfer.
var WriterCreation = BufferedWriter<Source>.TryCreate(Source(), 2);
switch WriterCreation {
case .Ok { Value = Value: mut BufferedWriter<Source>& } => break move(Value);
case .Err => return 1;
}
};
let Input: byte[2] = [0x61_byte, 0x62_byte];
if Writer.Write(Input) is .Err { Error = _ } { return 2; }
if Writer.BufferedLength != 2 || Writer.Capacity != 2 || Writer.IsClosed { return 3; }
switch Writer.Flush() { case .Err { Error = Failure } => { switch Failure { case .Failure { Reason = Reason, Transferred = Count } if (Reason is .Interrupted) => { if Count != 0 { return 4; } } default => return 5; } } default => return 5; }
if Writer.BufferedLength != 2 { return 6; }
var Finished = switch Writer.TryFinish() { case .Ok { Value = Value } => break Value; case .Err => return 7; };
if Finished.Written != 2 || !Writer.IsClosed { return 8; }
var Reader = {
// Keep writable result storage through the explicit noncopy payload transfer.
var ReaderCreation = BufferedReader<Source>.TryCreate(Source(), 2);
switch ReaderCreation {
case .Ok { Value = Value: mut BufferedReader<Source>& } => break move(Value);
case .Err => return 9;
}
};
var Moved = move(Reader);
if !Reader.IsClosed { return 10; }
var Output: byte[1] = [0_byte];
switch Moved.Read(Output) { case .Ok { Value = Count } => { if Count != 1 || Output[0] != 0x61_byte { return 11; } } case .Err => return 12; }
switch Moved.Read(Output) { case .Ok { Value = Count } => { if Count != 0 { return 13; } } case .Err => return 14; }
var Original = Moved.DiscardBufferedBytesAndTakeSource();
if !Moved.IsClosed || Original.ReadCount != 1 { return 15; }
switch BufferedWriter<Source>.TryCreate(Source(), 0) {
case .Err { Error = Error } => { if !Error.Source.FailNext { return 16; } switch Error.Reason { case .Failure { Reason = Reason } if (Reason is .InvalidInput) => {} default => return 17; } }
case .Ok => return 18;
}
return 0;
}Example
module example.buffered_partial_write;
from std.io import BufferedWriter, IoError;
from std.prelude import Result;
struct CountedSink {
pub Written: usize;
pub Failed: bool;
pub init() { this.Written = 0; this.Failed = false; }
pub fn Write(Input: readonly byte[]) -> Result<usize, IoError> {
if Input.Length == 0 { return .Ok { Value = 0 }; }
// Model an actual byte commit followed by a provider cleanup failure.
this.Written += 1;
if !this.Failed { this.Failed = true; return .Err { Error = .Failure { Reason = .AccessDenied, Transferred = 1 } }; }
return .Ok { Value = 1 };
}
pub fn Flush() -> Result<void, IoError> { return .Ok; }
}
fn Main() -> i32 {
var Writer = {
// Scoped writable carriers end immediately after explicit payload transfer.
var WriterCreation = BufferedWriter<CountedSink>.TryCreate(CountedSink(), 2);
switch WriterCreation {
case .Ok { Value = Value: mut BufferedWriter<CountedSink>& } => break move(Value);
case .Err => return 1;
}
};
let Input: byte[2] = [0x41_byte, 0x42_byte];
switch Writer.Write(Input) { case .Ok { Value = Count } => { if Count != 2 { return 2; } } case .Err => return 3; }
switch Writer.Flush() {
case .Err { Error = PatternPayload5001 } => {
switch PatternPayload5001 {
case .Failure { Reason = PatternPayload5002, Transferred = Count } if (PatternPayload5002 is .AccessDenied) => { if Count != 1 { return 4; } }
default => return 5;
}
}
default => return 5;
}
if Writer.BufferedLength != 1 { return 6; }
var Finished = switch Writer.TryFinish() { case .Ok { Value = Value } => break Value; case .Err => return 7; };
if Finished.Written != 2 || !Writer.IsClosed { return 8; }
// The committed first byte was removed from the cache and never replayed.
return 0;
}BufferedWriter.init
pub init(Source: readonly Self&) = delete;Rejects implicit source/cache copying. Source: Existing adapter.
BufferedWriter.operator
pub fn operator =(Source: readonly Self&) -> void = delete;Rejects replacement that could silently discard pending bytes. Source: Existing adapter. Return: No runtime result; this assignment is deleted and cannot be invoked.
BufferedWriter.operator
pub fn operator =(Source: mut Self&&) -> void = delete;Requires explicit finishing/extraction before replacing an adapter. Source: Existing adapter. Return: No runtime result; this assignment is deleted and cannot be invoked.
BufferedWriter.Capacity
pub Capacity: usize;Observes initialized cache capacity in bytes.
BufferedWriter.IsClosed
pub IsClosed: bool;Observes extraction/movement closure without I/O.
BufferedWriter.TryCreate
pub static fn TryCreate(mut Source: S, Capacity: usize) -> Result<Self, BufferedStreamCreationError<S>>Allocates initialized cache slots and transfers a concrete source. Source: Owned source; returned in the error on failure. Capacity: Positive cache capacity in bytes; default is 8192. Return: Adapter or error retaining the source; no stream I/O occurs. Warning: May allocate.
BufferedWriter.TryCreate
pub static fn TryCreate(mut Source: S) -> Result<Self, BufferedStreamCreationError<S>>Supplies the omitted arguments to TryCreate. Note: Defaults: Capacity = DefaultBufferCapacity. Source: Same input, ownership and lifetime contract as the full operation. Return: The full synchronous operation's owned success value or typed failure.
BufferedWriter.init
pub init(Source: mut Self&&)Transfers pending bytes without flushing. Source: Adapter left closed.
BufferedWriter.BufferedLength
pub BufferedLength: usize;Counts accepted bytes not yet submitted to the source.
BufferedWriter.Write
pub fn Write(Input: readonly byte[]) -> Result<usize, IoError>Accepts input into owned cache, draining full cache when necessary. Input: Borrowed bytes copied during this call. Return: Accepted input count or failure counting only this call's accepted prefix. Warning: May block in source writes; never implicitly calls source Flush.
BufferedWriter.Flush
pub fn Flush() -> Result<void, IoError>Submits pending bytes and then flushes downstream layers. Return: Success or failure counting bytes submitted from this cache in this call. Warning: May block; never promises durable storage. Unwritten tail survives failure.
BufferedWriter.TryFinish
pub fn TryFinish() -> Result<S, IoError>Flushes successfully before transferring the source. Return: Owned source, or failure leaving this adapter available for retry. Warning: May block. Destruction alone discards pending bytes without flushing.