File: copy.ha

package info (click to toggle)
hare 0.26.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 7,352 kB
  • sloc: asm: 1,374; makefile: 123; sh: 117; lisp: 101
file content (50 lines) | stat: -rw-r--r-- 1,214 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// SPDX-License-Identifier: MPL-2.0
// (c) Hare authors <https://harelang.org>

use errors;

// Copies data from one handle into another. If reading from the source file
// returns zero (underread), the copy is terminated and the amount of data
// copied is returned. Note that this function will never return if the source
// handle is infinite.
export fn copy(dest: handle, src: handle) (size | error) = {
	match (dest) {
	case let fd: file =>
		if (src is file) {
			match (fd_copy(fd, src as file)) {
			case let err: error =>
				if (!(err is errors::unsupported)) {
					return err;
				};
				// Use fallback
			case let z: size =>
				return z;
			};
		};
		return copy_fallback(dest, src);
	case let dest: *stream =>
		match (dest.copier) {
		case null =>
			return copy_fallback(dest, src);
		case let c: *copier =>
			match (c(dest, src)) {
			case errors::unsupported =>
				return copy_fallback(dest, src);
			case let err: error =>
				return err;
			case let s: size =>
				return s;
			};
		};
	};
};

fn copy_fallback(dest: handle, src: handle) (size | error) = {
	let w = 0z;
	let buf: [4096]u8 = [0...];

	for (let n => read(src, buf[..])?) {
		w += writeall(dest, buf[..n])?;
	};
	return w;
};