1 /** 2 * Copyright: Copyright Jason White, 2016 3 * License: MIT 4 * Authors: Jason White 5 */ 6 module button.deps; 7 8 import button.resource; 9 10 /** 11 * Format for dependencies received from a task over a pipe. 12 */ 13 align(4) struct Dependency 14 { 15 /** 16 * Status of the resource. 17 * 18 * Can be: 19 * 0: Status is unknown. 20 * 1: Resource does not exist. 21 * 2: The resource is a file. 22 * 3: The resource is a directory. 23 */ 24 uint status; 25 26 /** 27 * SHA-256 checksum of the contents of the resource. If unknown or not 28 * computed, this should be set to 0. In such a case, the parent build 29 * system will compute the value when needed. 30 * 31 * For files, this is the checksum of the file contents. For directories, 32 * this is the checksum of the paths in the sorted directory listing. 33 */ 34 ubyte[32] checksum; 35 36 /** 37 * Length of the name. 38 */ 39 uint length; 40 41 /** 42 * Name of the resource that can be used to lookup the data. Length is given 43 * by the length member. 44 * 45 * This is usually a file or directory path. The path does not need to be 46 * normalized. The path is assumed to be relative to the associated task's 47 * working directory. 48 */ 49 char[0] name; 50 } 51 52 unittest 53 { 54 static assert(Dependency.sizeof == 40); 55 } 56 57 /** 58 * Range of resources received from a child process. 59 */ 60 struct Deps 61 { 62 private 63 { 64 immutable(void)[] buf; 65 66 Resource _current; 67 bool _empty; 68 } 69 70 this(immutable(void)[] buf) 71 { 72 this.buf = buf; 73 popFront(); 74 } 75 76 Resource front() inout 77 { 78 return _current; 79 } 80 81 bool empty() const pure nothrow 82 { 83 return _empty; 84 } 85 86 void popFront() 87 { 88 import std.datetime : SysTime; 89 90 if (buf.length == 0) 91 { 92 _empty = true; 93 return; 94 } 95 96 if (buf.length < Dependency.sizeof) 97 throw new Exception("Received partial dependency buffer"); 98 99 auto dep = *cast(Dependency*)buf[0 .. Dependency.sizeof]; 100 101 immutable totalSize = Dependency.sizeof + dep.length; 102 103 string name = cast(string)buf[Dependency.sizeof .. totalSize]; 104 105 _current = Resource( 106 name, 107 cast(Resource.Status)dep.status, 108 dep.checksum 109 ); 110 111 buf = buf[totalSize .. $]; 112 } 113 } 114 115 /** 116 * Convenience function for returning a range of resources. 117 */ 118 Deps deps(immutable(void)[] buf) 119 { 120 return Deps(buf); 121 }