hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

copy.ha (1389B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use errors;
      5 
      6 // Copies data from one handle into another. If reading from the source file
      7 // returns zero (underread), the copy is terminated and the amount of data
      8 // copied is returned. Note that this function will never return if the source
      9 // handle is infinite.
     10 export fn copy(dest: handle, src: handle) (size | error) = {
     11 	match (dest) {
     12 	case let fd: file =>
     13 		if (src is file) {
     14 			match (fd_copy(fd, src as file)) {
     15 			case let err: error =>
     16 				if (!(err is errors::unsupported)) {
     17 					return err;
     18 				};
     19 				// Use fallback
     20 			case let z: size =>
     21 				return z;
     22 			};
     23 		};
     24 		return copy_fallback(dest, src);
     25 	case let st: *stream =>
     26 		if (!(src is *stream)) {
     27 			return copy_fallback(dest, src);
     28 		};
     29 		return copy_streams(st, src as *stream);
     30 	};
     31 };
     32 
     33 fn copy_streams(dest: *stream, src: *stream) (size | error) = {
     34 	match (dest.copier) {
     35 	case null => void;
     36 	case let c: *copier =>
     37 		match (c(dest, src)) {
     38 		case let err: error =>
     39 			match (err) {
     40 			case errors::unsupported => void;
     41 			case =>
     42 				return err;
     43 			};
     44 		case let s: size =>
     45 			return s;
     46 		};
     47 	};
     48 	return copy_fallback(dest, src);
     49 };
     50 
     51 fn copy_fallback(dest: handle, src: handle) (size | error) = {
     52 	let w = 0z;
     53 	let buf: [4096]u8 = [0...];
     54 
     55 	for (let n => read(src, buf[..])?) {
     56 		w += writeall(dest, buf[..n])?;
     57 	};
     58 	return w;
     59 };