// Ary/Vector of u8s - a resizable array of bytes. struct aryu8 { u32 !len = 0; u8[] !buf; new aryu8 = { -> buf = new u8[1]; }; // Grow as needed val _grow = { u32 len2 -> if( len+len2 <= buf# ) return self; u32 newlen = ary.capacity(buf#,len+len2); if( !newlen ) libc._exit(1); // Length exceeds the array representation. u8[] !buf2 = new u8[newlen]; ary.copy(buf2,0,buf,0,len); buf = buf2; self; }; val clear = { -> len = 0; self; }; // Add a character to aryu8 val add = { u8 c -> _grow(1).buf[len++] = c; self; }; // Add all of a plain array to the aryu8 val addAry = { u8[~] xs -> u32 n=xs#; _grow(n); ary.copy(buf,len,xs,0,n); len += n; self; }; // Remove x bytes from the tail. val undo = { u32 x -> len = len >= x ? len-x : 0; self; }; // Print ASCII number into aryu8 val num = { i64 x -> text.integer(self,x,0,0,-1); self; }; // Write all bytes to fd; return len, or -1 with errno set on failure. val write = { i32 fd -> io.writeOff(fd,buf,0,len); }; }; // Parse one integer, ignore trailing data; returns 0 with an empty string. // If you want a more robust parsing, use the `scan` class val atoi = { u8[~] str -> u32 x = 0; while( x < str# && str[x] <= ' ' ) x++; if( x == str# ) return 0; bool neg = false; if( str[x]=='-' ) { neg=true; x++; } i64 n = 0; while( x < str# && '0' <= str[x] <= '9' ) n = n*10 + str[x++]-'0'; return neg ? -n : n; }; // Zero-terminate a string for libc, reserving one array element for the zero. { u8[~] -> u8[] } str0 = { u8[~] str -> if( str# == 4294967295 ) libc._exit(1); u8[] !strz = new u8[str#+1]; u32 len=str#; ary.copy(strz,0,str,0,len); strz[str#] = '\0'; strz; };