τau / io /

io.tau

source
/Users/niconex/Documents/tau/stdlib/io/io.tau
1# io - moving bytes between streams.2#3# There are no interfaces in tau, so a reader is simply any object with a4# Read(n) that returns up to n bytes, and an empty bytes value when there is5# nothing left. A writer is any object with a Write(data) returning how many6# bytes went out. Files, network connections and buffers all have that shape,7# so they work here without knowing about each other.89bufsize = 327681011# IsReader reports whether r can be read from.12IsReader = fn(r) { type(r) == "object" && type(r.Read) == "closure" }1314# IsWriter reports whether w can be written to.15IsWriter = fn(w) { type(w) == "object" && type(w.Write) == "closure" }1617# ReadAll returns everything left in r.18ReadAll = fn(r) {19	if !IsReader(r) {20		return error("io: ReadAll wants a reader, got {type(r)}")21	}2223	out = bytes(0)24	for {25		if failed(chunk = r.Read(bufsize)) {26			return chunk27		}28		if len(chunk) == 0 {29			return out30		}31		out = out + chunk32	}33}3435# ReadFull returns exactly n bytes, or fewer if the stream ends first.36ReadFull = fn(r, n) {37	if !IsReader(r) {38		return error("io: ReadFull wants a reader, got {type(r)}")39	}4041	out = bytes(0)42	for len(out) < n {43		if failed(chunk = r.Read(n - len(out))) {44			return chunk45		}46		if len(chunk) == 0 {47			return out48		}49		out = out + chunk50	}5152	return out53}5455# Copy moves everything from src to dst and returns how many bytes it moved.56Copy = fn(dst, src) {57	if !IsWriter(dst) {58		return error("io: Copy wants a writer, got {type(dst)}")59	}60	if !IsReader(src) {61		return error("io: Copy wants a reader, got {type(src)}")62	}6364	total = 065	for {66		if failed(chunk = src.Read(bufsize)) {67			return chunk68		}69		if len(chunk) == 0 {70			return total71		}72		if failed(n = dst.Write(chunk)) {73			return n74		}75		total = total + n76	}77}7879# CopyN moves at most n bytes from src to dst.80CopyN = fn(dst, src, n) {81	if failed(data = ReadFull(src, n)) {82		return data83	}84	return dst.Write(data)85}8687# WriteString writes a string to a writer.88WriteString = fn(w, s) {89	if !IsWriter(w) {90		return error("io: WriteString wants a writer, got {type(w)}")91	}92	return w.Write(s)93}