| author | |
| committer | |
| log | 06b44a0afa849556f613fcc5939db99fec38883f |
| tree | 2ba6b36cc75c0480a7ccdd7ba5ec8344e1d7dee5 |
| parent | d603121dc355fee44b86a7fdf3666dce6e3ab677 |
- flatten std.crypto.hash.Sha1 and give it a writable interface that
optimizes splats
- flatten std.hash.crc and give it a writable interface that optimizes
splats
- remove old writer impls from std.crypto
- add fs.File.Writer.moveToReader
- add fs.File.Writer.seekTo
- add std.io.Reader.Hashed and std.io.Writer.Hashed which are
passthrough streams. Instead of passing through to null writer, use
the writable interface implemented directly on hashers which doesn't
have to account for passing through the data.
- add std.io.BufferedWriter.writeSplatAll28 files changed, 1190 insertions(+), 916 deletions(-)
lib/std/compress/flate.zig+5| ... | @@ -1,5 +1,10 @@ | ... | @@ -1,5 +1,10 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | 2 | ||
| 3 | /// When decompressing, the output buffer is used as the history window, so | ||
| 4 | /// less than this may result in failure to decompress streams that were | ||
| 5 | /// compressed with a larger window. | ||
| 6 | pub const max_window_len = 1 << 16; | ||
| 7 | |||
| 3 | /// Deflate is a lossless data compression file format that uses a combination | 8 | /// Deflate is a lossless data compression file format that uses a combination |
| 4 | /// of LZ77 and Huffman coding. | 9 | /// of LZ77 and Huffman coding. |
| 5 | pub const deflate = @import("flate/deflate.zig"); | 10 | pub const deflate = @import("flate/deflate.zig"); |
lib/std/compress/flate/inflate.zig+4| ... | @@ -403,6 +403,10 @@ pub fn Inflate(comptime container: Container, comptime Lookahead: type) type { | ... | @@ -403,6 +403,10 @@ pub fn Inflate(comptime container: Container, comptime Lookahead: type) type { |
| 403 | }, | 403 | }, |
| 404 | }; | 404 | }; |
| 405 | } | 405 | } |
| 406 | |||
| 407 | pub fn readable(self: *Self, buffer: []u8) std.io.BufferedReader { | ||
| 408 | return reader(self).buffered(buffer); | ||
| 409 | } | ||
| 406 | }; | 410 | }; |
| 407 | } | 411 | } |
| 408 | 412 |
lib/std/compress/zlib.zig+5| ... | @@ -2,6 +2,11 @@ const std = @import("../std.zig"); | ... | @@ -2,6 +2,11 @@ const std = @import("../std.zig"); |
| 2 | const deflate = @import("flate/deflate.zig"); | 2 | const deflate = @import("flate/deflate.zig"); |
| 3 | const inflate = @import("flate/inflate.zig"); | 3 | const inflate = @import("flate/inflate.zig"); |
| 4 | 4 | ||
| 5 | /// When decompressing, the output buffer is used as the history window, so | ||
| 6 | /// less than this may result in failure to decompress streams that were | ||
| 7 | /// compressed with a larger window. | ||
| 8 | pub const max_window_len = std.compress.flate.max_window_len; | ||
| 9 | |||
| 5 | /// Decompress compressed data from reader and write plain data to the writer. | 10 | /// Decompress compressed data from reader and write plain data to the writer. |
| 6 | pub fn decompress(reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter) !void { | 11 | pub fn decompress(reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter) !void { |
| 7 | try inflate.decompress(.zlib, reader, writer); | 12 | try inflate.decompress(.zlib, reader, writer); |
lib/std/crypto.zig+3-3| ... | @@ -1,5 +1,7 @@ | ... | @@ -1,5 +1,7 @@ |
| 1 | //! Cryptography. | 1 | //! Cryptography. |
| 2 | 2 | ||
| 3 | const std = @import("std.zig"); | ||
| 4 | const assert = std.debug.assert; | ||
| 3 | const root = @import("root"); | 5 | const root = @import("root"); |
| 4 | 6 | ||
| 5 | pub const timing_safe = @import("crypto/timing_safe.zig"); | 7 | pub const timing_safe = @import("crypto/timing_safe.zig"); |
| ... | @@ -119,7 +121,7 @@ pub const hash = struct { | ... | @@ -119,7 +121,7 @@ pub const hash = struct { |
| 119 | pub const blake2 = @import("crypto/blake2.zig"); | 121 | pub const blake2 = @import("crypto/blake2.zig"); |
| 120 | pub const Blake3 = @import("crypto/blake3.zig").Blake3; | 122 | pub const Blake3 = @import("crypto/blake3.zig").Blake3; |
| 121 | pub const Md5 = @import("crypto/md5.zig").Md5; | 123 | pub const Md5 = @import("crypto/md5.zig").Md5; |
| 122 | pub const Sha1 = @import("crypto/sha1.zig").Sha1; | 124 | pub const Sha1 = @import("crypto/Sha1.zig"); |
| 123 | pub const sha2 = @import("crypto/sha2.zig"); | 125 | pub const sha2 = @import("crypto/sha2.zig"); |
| 124 | pub const sha3 = @import("crypto/sha3.zig"); | 126 | pub const sha3 = @import("crypto/sha3.zig"); |
| 125 | pub const composition = @import("crypto/hash_composition.zig"); | 127 | pub const composition = @import("crypto/hash_composition.zig"); |
| ... | @@ -217,8 +219,6 @@ pub const random = @import("crypto/tlcsprng.zig").interface; | ... | @@ -217,8 +219,6 @@ pub const random = @import("crypto/tlcsprng.zig").interface; |
| 217 | /// Encoding and decoding | 219 | /// Encoding and decoding |
| 218 | pub const codecs = @import("crypto/codecs.zig"); | 220 | pub const codecs = @import("crypto/codecs.zig"); |
| 219 | 221 | ||
| 220 | const std = @import("std.zig"); | ||
| 221 | |||
| 222 | pub const errors = @import("crypto/errors.zig"); | 222 | pub const errors = @import("crypto/errors.zig"); |
| 223 | 223 | ||
| 224 | pub const tls = @import("crypto/tls.zig"); | 224 | pub const tls = @import("crypto/tls.zig"); |
lib/std/crypto/Sha1.zig created+424| ... | @@ -0,0 +1,424 @@ | ||
| 1 | //! The SHA-1 function is now considered cryptographically broken. | ||
| 2 | //! Namely, it is feasible to find multiple inputs producing the same hash. | ||
| 3 | //! For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3. | ||
| 4 | |||
| 5 | const Sha1 = @This(); | ||
| 6 | const std = @import("../std.zig"); | ||
| 7 | const mem = std.mem; | ||
| 8 | const math = std.math; | ||
| 9 | const assert = std.debug.assert; | ||
| 10 | |||
| 11 | pub const block_length = 64; | ||
| 12 | pub const digest_length = 20; | ||
| 13 | pub const Options = struct {}; | ||
| 14 | |||
| 15 | s: [5]u32, | ||
| 16 | /// Streaming Cache | ||
| 17 | buf: [64]u8, | ||
| 18 | buf_end: u8, | ||
| 19 | total_len: u64, | ||
| 20 | |||
| 21 | pub fn init(options: Options) Sha1 { | ||
| 22 | _ = options; | ||
| 23 | return .{ | ||
| 24 | .s = [_]u32{ | ||
| 25 | 0x67452301, | ||
| 26 | 0xEFCDAB89, | ||
| 27 | 0x98BADCFE, | ||
| 28 | 0x10325476, | ||
| 29 | 0xC3D2E1F0, | ||
| 30 | }, | ||
| 31 | .buf = undefined, | ||
| 32 | .buf_end = 0, | ||
| 33 | .total_len = 0, | ||
| 34 | }; | ||
| 35 | } | ||
| 36 | |||
| 37 | pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { | ||
| 38 | var d = Sha1.init(options); | ||
| 39 | d.update(b); | ||
| 40 | d.final(out); | ||
| 41 | } | ||
| 42 | |||
| 43 | pub fn update(d: *Sha1, b: []const u8) void { | ||
| 44 | var off: usize = 0; | ||
| 45 | |||
| 46 | // Partial buffer exists from previous update. Copy into buffer then hash. | ||
| 47 | const unused_buf = d.buf[d.buf_end..]; | ||
| 48 | if (unused_buf.len < d.buf.len and b.len >= unused_buf.len) { | ||
| 49 | @memcpy(unused_buf, b[0..unused_buf.len]); | ||
| 50 | off += unused_buf.len; | ||
| 51 | round(&d.s, &d.buf); | ||
| 52 | d.buf_end = 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | // Full middle blocks. | ||
| 56 | while (off + 64 <= b.len) : (off += 64) { | ||
| 57 | round(&d.s, b[off..][0..64]); | ||
| 58 | } | ||
| 59 | |||
| 60 | // Copy any remainder for next pass. | ||
| 61 | const remainder = b[off..]; | ||
| 62 | @memcpy(d.buf[d.buf_end..][0..remainder.len], remainder); | ||
| 63 | d.buf_end = @intCast(d.buf_end + remainder.len); | ||
| 64 | d.total_len += b.len; | ||
| 65 | } | ||
| 66 | |||
| 67 | pub fn peek(d: Sha1) [digest_length]u8 { | ||
| 68 | var copy = d; | ||
| 69 | return copy.finalResult(); | ||
| 70 | } | ||
| 71 | |||
| 72 | pub fn final(d: *Sha1, out: *[digest_length]u8) void { | ||
| 73 | // The buffer here will never be completely full. | ||
| 74 | @memset(d.buf[d.buf_end..], 0); | ||
| 75 | |||
| 76 | // Append padding bits. | ||
| 77 | d.buf[d.buf_end] = 0x80; | ||
| 78 | d.buf_end += 1; | ||
| 79 | |||
| 80 | // > 448 mod 512 so need to add an extra round to wrap around. | ||
| 81 | if (64 - d.buf_end < 8) { | ||
| 82 | round(&d.s, d.buf[0..]); | ||
| 83 | @memset(d.buf[0..], 0); | ||
| 84 | } | ||
| 85 | |||
| 86 | // Append message length. | ||
| 87 | var i: usize = 1; | ||
| 88 | var len = d.total_len >> 5; | ||
| 89 | d.buf[63] = @as(u8, @intCast(d.total_len & 0x1f)) << 3; | ||
| 90 | while (i < 8) : (i += 1) { | ||
| 91 | d.buf[63 - i] = @as(u8, @intCast(len & 0xff)); | ||
| 92 | len >>= 8; | ||
| 93 | } | ||
| 94 | |||
| 95 | round(&d.s, d.buf[0..]); | ||
| 96 | |||
| 97 | for (d.s, 0..) |s, j| { | ||
| 98 | mem.writeInt(u32, out[4 * j ..][0..4], s, .big); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | pub fn finalResult(d: *Sha1) [digest_length]u8 { | ||
| 103 | var result: [digest_length]u8 = undefined; | ||
| 104 | d.final(&result); | ||
| 105 | return result; | ||
| 106 | } | ||
| 107 | |||
| 108 | pub fn round(d_s: *[5]u32, b: *const [64]u8) void { | ||
| 109 | var s: [16]u32 = undefined; | ||
| 110 | |||
| 111 | var v: [5]u32 = [_]u32{ | ||
| 112 | d_s[0], | ||
| 113 | d_s[1], | ||
| 114 | d_s[2], | ||
| 115 | d_s[3], | ||
| 116 | d_s[4], | ||
| 117 | }; | ||
| 118 | |||
| 119 | const round0a = comptime [_]RoundParam{ | ||
| 120 | .abcdei(0, 1, 2, 3, 4, 0), | ||
| 121 | .abcdei(4, 0, 1, 2, 3, 1), | ||
| 122 | .abcdei(3, 4, 0, 1, 2, 2), | ||
| 123 | .abcdei(2, 3, 4, 0, 1, 3), | ||
| 124 | .abcdei(1, 2, 3, 4, 0, 4), | ||
| 125 | .abcdei(0, 1, 2, 3, 4, 5), | ||
| 126 | .abcdei(4, 0, 1, 2, 3, 6), | ||
| 127 | .abcdei(3, 4, 0, 1, 2, 7), | ||
| 128 | .abcdei(2, 3, 4, 0, 1, 8), | ||
| 129 | .abcdei(1, 2, 3, 4, 0, 9), | ||
| 130 | .abcdei(0, 1, 2, 3, 4, 10), | ||
| 131 | .abcdei(4, 0, 1, 2, 3, 11), | ||
| 132 | .abcdei(3, 4, 0, 1, 2, 12), | ||
| 133 | .abcdei(2, 3, 4, 0, 1, 13), | ||
| 134 | .abcdei(1, 2, 3, 4, 0, 14), | ||
| 135 | .abcdei(0, 1, 2, 3, 4, 15), | ||
| 136 | }; | ||
| 137 | inline for (round0a) |r| { | ||
| 138 | s[r.i] = mem.readInt(u32, b[r.i * 4 ..][0..4], .big); | ||
| 139 | |||
| 140 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d])); | ||
| 141 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 142 | } | ||
| 143 | |||
| 144 | const round0b = comptime [_]RoundParam{ | ||
| 145 | .abcdei(4, 0, 1, 2, 3, 16), | ||
| 146 | .abcdei(3, 4, 0, 1, 2, 17), | ||
| 147 | .abcdei(2, 3, 4, 0, 1, 18), | ||
| 148 | .abcdei(1, 2, 3, 4, 0, 19), | ||
| 149 | }; | ||
| 150 | inline for (round0b) |r| { | ||
| 151 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 152 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 153 | |||
| 154 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d])); | ||
| 155 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 156 | } | ||
| 157 | |||
| 158 | const round1 = comptime [_]RoundParam{ | ||
| 159 | .abcdei(0, 1, 2, 3, 4, 20), | ||
| 160 | .abcdei(4, 0, 1, 2, 3, 21), | ||
| 161 | .abcdei(3, 4, 0, 1, 2, 22), | ||
| 162 | .abcdei(2, 3, 4, 0, 1, 23), | ||
| 163 | .abcdei(1, 2, 3, 4, 0, 24), | ||
| 164 | .abcdei(0, 1, 2, 3, 4, 25), | ||
| 165 | .abcdei(4, 0, 1, 2, 3, 26), | ||
| 166 | .abcdei(3, 4, 0, 1, 2, 27), | ||
| 167 | .abcdei(2, 3, 4, 0, 1, 28), | ||
| 168 | .abcdei(1, 2, 3, 4, 0, 29), | ||
| 169 | .abcdei(0, 1, 2, 3, 4, 30), | ||
| 170 | .abcdei(4, 0, 1, 2, 3, 31), | ||
| 171 | .abcdei(3, 4, 0, 1, 2, 32), | ||
| 172 | .abcdei(2, 3, 4, 0, 1, 33), | ||
| 173 | .abcdei(1, 2, 3, 4, 0, 34), | ||
| 174 | .abcdei(0, 1, 2, 3, 4, 35), | ||
| 175 | .abcdei(4, 0, 1, 2, 3, 36), | ||
| 176 | .abcdei(3, 4, 0, 1, 2, 37), | ||
| 177 | .abcdei(2, 3, 4, 0, 1, 38), | ||
| 178 | .abcdei(1, 2, 3, 4, 0, 39), | ||
| 179 | }; | ||
| 180 | inline for (round1) |r| { | ||
| 181 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 182 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 183 | |||
| 184 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x6ED9EBA1 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]); | ||
| 185 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 186 | } | ||
| 187 | |||
| 188 | const round2 = comptime [_]RoundParam{ | ||
| 189 | .abcdei(0, 1, 2, 3, 4, 40), | ||
| 190 | .abcdei(4, 0, 1, 2, 3, 41), | ||
| 191 | .abcdei(3, 4, 0, 1, 2, 42), | ||
| 192 | .abcdei(2, 3, 4, 0, 1, 43), | ||
| 193 | .abcdei(1, 2, 3, 4, 0, 44), | ||
| 194 | .abcdei(0, 1, 2, 3, 4, 45), | ||
| 195 | .abcdei(4, 0, 1, 2, 3, 46), | ||
| 196 | .abcdei(3, 4, 0, 1, 2, 47), | ||
| 197 | .abcdei(2, 3, 4, 0, 1, 48), | ||
| 198 | .abcdei(1, 2, 3, 4, 0, 49), | ||
| 199 | .abcdei(0, 1, 2, 3, 4, 50), | ||
| 200 | .abcdei(4, 0, 1, 2, 3, 51), | ||
| 201 | .abcdei(3, 4, 0, 1, 2, 52), | ||
| 202 | .abcdei(2, 3, 4, 0, 1, 53), | ||
| 203 | .abcdei(1, 2, 3, 4, 0, 54), | ||
| 204 | .abcdei(0, 1, 2, 3, 4, 55), | ||
| 205 | .abcdei(4, 0, 1, 2, 3, 56), | ||
| 206 | .abcdei(3, 4, 0, 1, 2, 57), | ||
| 207 | .abcdei(2, 3, 4, 0, 1, 58), | ||
| 208 | .abcdei(1, 2, 3, 4, 0, 59), | ||
| 209 | }; | ||
| 210 | inline for (round2) |r| { | ||
| 211 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 212 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 213 | |||
| 214 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x8F1BBCDC +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d])); | ||
| 215 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 216 | } | ||
| 217 | |||
| 218 | const round3 = comptime [_]RoundParam{ | ||
| 219 | .abcdei(0, 1, 2, 3, 4, 60), | ||
| 220 | .abcdei(4, 0, 1, 2, 3, 61), | ||
| 221 | .abcdei(3, 4, 0, 1, 2, 62), | ||
| 222 | .abcdei(2, 3, 4, 0, 1, 63), | ||
| 223 | .abcdei(1, 2, 3, 4, 0, 64), | ||
| 224 | .abcdei(0, 1, 2, 3, 4, 65), | ||
| 225 | .abcdei(4, 0, 1, 2, 3, 66), | ||
| 226 | .abcdei(3, 4, 0, 1, 2, 67), | ||
| 227 | .abcdei(2, 3, 4, 0, 1, 68), | ||
| 228 | .abcdei(1, 2, 3, 4, 0, 69), | ||
| 229 | .abcdei(0, 1, 2, 3, 4, 70), | ||
| 230 | .abcdei(4, 0, 1, 2, 3, 71), | ||
| 231 | .abcdei(3, 4, 0, 1, 2, 72), | ||
| 232 | .abcdei(2, 3, 4, 0, 1, 73), | ||
| 233 | .abcdei(1, 2, 3, 4, 0, 74), | ||
| 234 | .abcdei(0, 1, 2, 3, 4, 75), | ||
| 235 | .abcdei(4, 0, 1, 2, 3, 76), | ||
| 236 | .abcdei(3, 4, 0, 1, 2, 77), | ||
| 237 | .abcdei(2, 3, 4, 0, 1, 78), | ||
| 238 | .abcdei(1, 2, 3, 4, 0, 79), | ||
| 239 | }; | ||
| 240 | inline for (round3) |r| { | ||
| 241 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 242 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 243 | |||
| 244 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0xCA62C1D6 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]); | ||
| 245 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 246 | } | ||
| 247 | |||
| 248 | d_s[0] +%= v[0]; | ||
| 249 | d_s[1] +%= v[1]; | ||
| 250 | d_s[2] +%= v[2]; | ||
| 251 | d_s[3] +%= v[3]; | ||
| 252 | d_s[4] +%= v[4]; | ||
| 253 | } | ||
| 254 | |||
| 255 | pub fn writable(sha1: *Sha1, buffer: []u8) std.io.BufferedWriter { | ||
| 256 | return .{ | ||
| 257 | .unbuffered_writer = .{ | ||
| 258 | .context = sha1, | ||
| 259 | .vtable = &.{ | ||
| 260 | .writeSplat = writeSplat, | ||
| 261 | .writeFile = std.io.Writer.unimplementedWriteFile, | ||
| 262 | }, | ||
| 263 | }, | ||
| 264 | .buffer = buffer, | ||
| 265 | }; | ||
| 266 | } | ||
| 267 | |||
| 268 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | ||
| 269 | const sha1: *Sha1 = @ptrCast(@alignCast(context)); | ||
| 270 | const start_total = sha1.total_len; | ||
| 271 | if (sha1.buf_end == 0) { | ||
| 272 | try writeSplatAligned(sha1, data, splat); | ||
| 273 | const n: usize = @intCast(sha1.total_len - start_total); | ||
| 274 | if (n > 0) return n; | ||
| 275 | } | ||
| 276 | for (data[0 .. data.len - 1]) |slice| { | ||
| 277 | const copy_len = @min(slice.len, sha1.buf.len - sha1.buf_end); | ||
| 278 | @memcpy(sha1.buf[sha1.buf_end..][0..copy_len], slice[0..copy_len]); | ||
| 279 | sha1.total_len += copy_len; | ||
| 280 | if (sha1.buf.len - sha1.buf_end - copy_len == 0) { | ||
| 281 | round(&sha1.s, &sha1.buf); | ||
| 282 | sha1.buf_end = 0; | ||
| 283 | return @intCast(sha1.total_len - start_total); | ||
| 284 | } | ||
| 285 | sha1.buf_end = @intCast(sha1.buf_end + copy_len); | ||
| 286 | } | ||
| 287 | const slice = data[data.len - 1]; | ||
| 288 | for (0..splat) |_| { | ||
| 289 | const copy_len = @min(slice.len, sha1.buf.len - sha1.buf_end); | ||
| 290 | @memcpy(sha1.buf[sha1.buf_end..][0..copy_len], slice[0..copy_len]); | ||
| 291 | sha1.total_len += copy_len; | ||
| 292 | if (sha1.buf.len - sha1.buf_end - copy_len == 0) { | ||
| 293 | round(&sha1.s, &sha1.buf); | ||
| 294 | sha1.buf_end = 0; | ||
| 295 | return @intCast(sha1.total_len - start_total); | ||
| 296 | } | ||
| 297 | sha1.buf_end = @intCast(sha1.buf_end + copy_len); | ||
| 298 | } | ||
| 299 | return @intCast(sha1.total_len - start_total); | ||
| 300 | } | ||
| 301 | |||
| 302 | fn writeSplatAligned(sha1: *Sha1, data: []const []const u8, splat: usize) std.io.Writer.Error!void { | ||
| 303 | assert(sha1.buf_end == 0); | ||
| 304 | for (data[0 .. data.len - 1]) |slice| { | ||
| 305 | var off: usize = 0; | ||
| 306 | while (off < slice.len) { | ||
| 307 | if (off + 64 > slice.len) { | ||
| 308 | sha1.total_len += off; | ||
| 309 | return; | ||
| 310 | } | ||
| 311 | round(&sha1.s, slice[off..][0..64]); | ||
| 312 | off += 64; | ||
| 313 | } | ||
| 314 | sha1.total_len += off; | ||
| 315 | } | ||
| 316 | const last = data[data.len - 1]; | ||
| 317 | if (last.len * splat < 64) return; | ||
| 318 | if (last.len == 1) { | ||
| 319 | @memset(&sha1.buf, last[0]); | ||
| 320 | for (0..splat / 64) |_| round(&sha1.s, &sha1.buf); | ||
| 321 | sha1.total_len += (splat / 64) * 64; | ||
| 322 | return; | ||
| 323 | } | ||
| 324 | if (last.len >= 64) { | ||
| 325 | for (0..splat) |_| { | ||
| 326 | var off: usize = 0; | ||
| 327 | while (off < last.len) { | ||
| 328 | if (off + 64 > last.len) { | ||
| 329 | sha1.total_len += off; | ||
| 330 | return; | ||
| 331 | } | ||
| 332 | round(&sha1.s, last[off..][0..64]); | ||
| 333 | off += 64; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | sha1.total_len += last.len * splat; | ||
| 337 | return; | ||
| 338 | } | ||
| 339 | // Opportunity: if last.len is less than 64, we could fill up the buffer | ||
| 340 | // with the pattern repeated then do rounds. | ||
| 341 | } | ||
| 342 | |||
| 343 | const RoundParam = struct { | ||
| 344 | a: usize, | ||
| 345 | b: usize, | ||
| 346 | c: usize, | ||
| 347 | d: usize, | ||
| 348 | e: usize, | ||
| 349 | i: u32, | ||
| 350 | |||
| 351 | fn abcdei(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam { | ||
| 352 | return .{ | ||
| 353 | .a = a, | ||
| 354 | .b = b, | ||
| 355 | .c = c, | ||
| 356 | .d = d, | ||
| 357 | .e = e, | ||
| 358 | .i = i, | ||
| 359 | }; | ||
| 360 | } | ||
| 361 | }; | ||
| 362 | |||
| 363 | const htest = @import("test.zig"); | ||
| 364 | |||
| 365 | test "sha1 single" { | ||
| 366 | try htest.assertEqualHash(Sha1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", ""); | ||
| 367 | try htest.assertEqualHash(Sha1, "a9993e364706816aba3e25717850c26c9cd0d89d", "abc"); | ||
| 368 | try htest.assertEqualHash(Sha1, "a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); | ||
| 369 | } | ||
| 370 | |||
| 371 | test "sha1 streaming" { | ||
| 372 | var h = Sha1.init(.{}); | ||
| 373 | var out: [20]u8 = undefined; | ||
| 374 | |||
| 375 | h.final(&out); | ||
| 376 | try htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]); | ||
| 377 | |||
| 378 | h = Sha1.init(.{}); | ||
| 379 | h.update("abc"); | ||
| 380 | h.final(&out); | ||
| 381 | try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); | ||
| 382 | |||
| 383 | h = Sha1.init(.{}); | ||
| 384 | h.update("a"); | ||
| 385 | h.update("b"); | ||
| 386 | h.update("c"); | ||
| 387 | h.final(&out); | ||
| 388 | try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); | ||
| 389 | } | ||
| 390 | |||
| 391 | test "sha1 aligned final" { | ||
| 392 | var block = [_]u8{0} ** Sha1.block_length; | ||
| 393 | var out: [Sha1.digest_length]u8 = undefined; | ||
| 394 | |||
| 395 | var h = Sha1.init(.{}); | ||
| 396 | h.update(&block); | ||
| 397 | h.final(out[0..]); | ||
| 398 | } | ||
| 399 | |||
| 400 | test "splat" { | ||
| 401 | var vecs = [_][]const u8{ | ||
| 402 | "hello", | ||
| 403 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstuyyyyyyyyyyyyyyyyyyyyyyyyy", | ||
| 404 | "x", | ||
| 405 | }; | ||
| 406 | const splat_len = 512; | ||
| 407 | const update_result = r: { | ||
| 408 | var sha1: Sha1 = .init(.{}); | ||
| 409 | sha1.update(vecs[0]); | ||
| 410 | sha1.update(vecs[1]); | ||
| 411 | var buffer: [splat_len]u8 = undefined; | ||
| 412 | @memset(&buffer, vecs[2][0]); | ||
| 413 | sha1.update(&buffer); | ||
| 414 | break :r sha1.finalResult(); | ||
| 415 | }; | ||
| 416 | const stream_result = r: { | ||
| 417 | var sha1: Sha1 = .init(.{}); | ||
| 418 | var bw = sha1.writable(&.{}); | ||
| 419 | try bw.writeSplatAll(&vecs, splat_len); | ||
| 420 | try std.testing.expectEqual(vecs[0].len + vecs[1].len + vecs[2].len * splat_len, sha1.total_len); | ||
| 421 | break :r sha1.finalResult(); | ||
| 422 | }; | ||
| 423 | try std.testing.expectEqualSlices(u8, &update_result, &stream_result); | ||
| 424 | } | ||
lib/std/crypto/aegis.zig-12| ... | @@ -801,18 +801,6 @@ fn AegisMac(comptime T: type) type { | ... | @@ -801,18 +801,6 @@ fn AegisMac(comptime T: type) type { |
| 801 | ctx.update(msg); | 801 | ctx.update(msg); |
| 802 | ctx.final(out); | 802 | ctx.final(out); |
| 803 | } | 803 | } |
| 804 | |||
| 805 | pub const Error = error{}; | ||
| 806 | pub const Writer = std.io.Writer(*Mac, Error, write); | ||
| 807 | |||
| 808 | fn write(self: *Mac, bytes: []const u8) Error!usize { | ||
| 809 | self.update(bytes); | ||
| 810 | return bytes.len; | ||
| 811 | } | ||
| 812 | |||
| 813 | pub fn writer(self: *Mac) Writer { | ||
| 814 | return .{ .context = self }; | ||
| 815 | } | ||
| 816 | }; | 804 | }; |
| 817 | } | 805 | } |
| 818 | 806 |
lib/std/crypto/blake2.zig-12| ... | @@ -185,18 +185,6 @@ pub fn Blake2s(comptime out_bits: usize) type { | ... | @@ -185,18 +185,6 @@ pub fn Blake2s(comptime out_bits: usize) type { |
| 185 | r.* ^= v[i] ^ v[i + 8]; | 185 | r.* ^= v[i] ^ v[i + 8]; |
| 186 | } | 186 | } |
| 187 | } | 187 | } |
| 188 | |||
| 189 | pub const Error = error{}; | ||
| 190 | pub const Writer = std.io.Writer(*Self, Error, write); | ||
| 191 | |||
| 192 | fn write(self: *Self, bytes: []const u8) Error!usize { | ||
| 193 | self.update(bytes); | ||
| 194 | return bytes.len; | ||
| 195 | } | ||
| 196 | |||
| 197 | pub fn writer(self: *Self) Writer { | ||
| 198 | return .{ .context = self }; | ||
| 199 | } | ||
| 200 | }; | 188 | }; |
| 201 | } | 189 | } |
| 202 | 190 |
lib/std/crypto/blake3.zig-12| ... | @@ -474,18 +474,6 @@ pub const Blake3 = struct { | ... | @@ -474,18 +474,6 @@ pub const Blake3 = struct { |
| 474 | } | 474 | } |
| 475 | output.rootOutputBytes(out_slice); | 475 | output.rootOutputBytes(out_slice); |
| 476 | } | 476 | } |
| 477 | |||
| 478 | pub const Error = error{}; | ||
| 479 | pub const Writer = std.io.Writer(*Blake3, Error, write); | ||
| 480 | |||
| 481 | fn write(self: *Blake3, bytes: []const u8) Error!usize { | ||
| 482 | self.update(bytes); | ||
| 483 | return bytes.len; | ||
| 484 | } | ||
| 485 | |||
| 486 | pub fn writer(self: *Blake3) Writer { | ||
| 487 | return .{ .context = self }; | ||
| 488 | } | ||
| 489 | }; | 477 | }; |
| 490 | 478 | ||
| 491 | // Use named type declarations to workaround crash with anonymous structs (issue #4373). | 479 | // Use named type declarations to workaround crash with anonymous structs (issue #4373). |
lib/std/crypto/codecs/asn1.zig+8-15| ... | @@ -90,39 +90,32 @@ pub const Tag = struct { | ... | @@ -90,39 +90,32 @@ pub const Tag = struct { |
| 90 | }; | 90 | }; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | pub fn encode(self: Tag, writer: anytype) @TypeOf(writer).Error!void { | 93 | pub fn encode(self: Tag, writer: *std.io.BufferedWriter) std.io.Writer.Error!void { |
| 94 | var tag1 = FirstTag{ | 94 | var tag1: FirstTag = .{ |
| 95 | .number = undefined, | 95 | .number = undefined, |
| 96 | .constructed = self.constructed, | 96 | .constructed = self.constructed, |
| 97 | .class = self.class, | 97 | .class = self.class, |
| 98 | }; | 98 | }; |
| 99 | |||
| 100 | var buffer: [3]u8 = undefined; | ||
| 101 | var stream = std.io.fixedBufferStream(&buffer); | ||
| 102 | var writer2 = stream.writer(); | ||
| 103 | |||
| 104 | switch (@intFromEnum(self.number)) { | 99 | switch (@intFromEnum(self.number)) { |
| 105 | 0...std.math.maxInt(u5) => |n| { | 100 | 0...std.math.maxInt(u5) => |n| { |
| 106 | tag1.number = @intCast(n); | 101 | tag1.number = @intCast(n); |
| 107 | writer2.writeByte(@bitCast(tag1)) catch unreachable; | 102 | try writer.writeByte(@bitCast(tag1)); |
| 108 | }, | 103 | }, |
| 109 | std.math.maxInt(u5) + 1...std.math.maxInt(u7) => |n| { | 104 | std.math.maxInt(u5) + 1...std.math.maxInt(u7) => |n| { |
| 110 | tag1.number = 15; | 105 | tag1.number = 15; |
| 111 | const tag2 = NextTag{ .number = @intCast(n), .continues = false }; | 106 | const tag2 = NextTag{ .number = @intCast(n), .continues = false }; |
| 112 | writer2.writeByte(@bitCast(tag1)) catch unreachable; | 107 | try writer.writeByte(@bitCast(tag1)); |
| 113 | writer2.writeByte(@bitCast(tag2)) catch unreachable; | 108 | try writer.writeByte(@bitCast(tag2)); |
| 114 | }, | 109 | }, |
| 115 | else => |n| { | 110 | else => |n| { |
| 116 | tag1.number = 15; | 111 | tag1.number = 15; |
| 117 | const tag2 = NextTag{ .number = @intCast(n >> 7), .continues = true }; | 112 | const tag2 = NextTag{ .number = @intCast(n >> 7), .continues = true }; |
| 118 | const tag3 = NextTag{ .number = @truncate(n), .continues = false }; | 113 | const tag3 = NextTag{ .number = @truncate(n), .continues = false }; |
| 119 | writer2.writeByte(@bitCast(tag1)) catch unreachable; | 114 | try writer.writeByte(@bitCast(tag1)); |
| 120 | writer2.writeByte(@bitCast(tag2)) catch unreachable; | 115 | try writer.writeByte(@bitCast(tag2)); |
| 121 | writer2.writeByte(@bitCast(tag3)) catch unreachable; | 116 | try writer.writeByte(@bitCast(tag3)); |
| 122 | }, | 117 | }, |
| 123 | } | 118 | } |
| 124 | |||
| 125 | _ = try writer.write(stream.getWritten()); | ||
| 126 | } | 119 | } |
| 127 | 120 | ||
| 128 | const FirstTag = packed struct(u8) { number: u5, constructed: bool, class: Tag.Class }; | 121 | const FirstTag = packed struct(u8) { number: u5, constructed: bool, class: Tag.Class }; |
lib/std/crypto/codecs/asn1/Oid.zig+24-13| ... | @@ -4,9 +4,12 @@ | ... | @@ -4,9 +4,12 @@ |
| 4 | //! organizations, or policy documents. | 4 | //! organizations, or policy documents. |
| 5 | encoded: []const u8, | 5 | encoded: []const u8, |
| 6 | 6 | ||
| 7 | pub const InitError = std.fmt.ParseIntError || error{MissingPrefix} || std.io.FixedBufferStream(u8).WriteError; | 7 | pub const EncodeError = error{ |
| 8 | WriteFailed, | ||
| 9 | MissingPrefix, | ||
| 10 | }; | ||
| 8 | 11 | ||
| 9 | pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid { | 12 | pub fn encode(dot_notation: []const u8, out: *std.io.BufferedWriter) EncodeError!void { |
| 10 | var split = std.mem.splitScalar(u8, dot_notation, '.'); | 13 | var split = std.mem.splitScalar(u8, dot_notation, '.'); |
| 11 | const first_str = split.next() orelse return error.MissingPrefix; | 14 | const first_str = split.next() orelse return error.MissingPrefix; |
| 12 | const second_str = split.next() orelse return error.MissingPrefix; | 15 | const second_str = split.next() orelse return error.MissingPrefix; |
| ... | @@ -14,10 +17,7 @@ pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid { | ... | @@ -14,10 +17,7 @@ pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid { |
| 14 | const first = try std.fmt.parseInt(u8, first_str, 10); | 17 | const first = try std.fmt.parseInt(u8, first_str, 10); |
| 15 | const second = try std.fmt.parseInt(u8, second_str, 10); | 18 | const second = try std.fmt.parseInt(u8, second_str, 10); |
| 16 | 19 | ||
| 17 | var stream = std.io.fixedBufferStream(out); | 20 | try out.writeByte(first * 40 + second); |
| 18 | var writer = stream.writer(); | ||
| 19 | |||
| 20 | try writer.writeByte(first * 40 + second); | ||
| 21 | 21 | ||
| 22 | var i: usize = 1; | 22 | var i: usize = 1; |
| 23 | while (split.next()) |s| { | 23 | while (split.next()) |s| { |
| ... | @@ -28,16 +28,26 @@ pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid { | ... | @@ -28,16 +28,26 @@ pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid { |
| 28 | const place = std.math.pow(Arc, encoding_base, n_bytes - @as(Arc, @intCast(j))); | 28 | const place = std.math.pow(Arc, encoding_base, n_bytes - @as(Arc, @intCast(j))); |
| 29 | const digit: u8 = @intCast(@divFloor(parsed, place)); | 29 | const digit: u8 = @intCast(@divFloor(parsed, place)); |
| 30 | 30 | ||
| 31 | try writer.writeByte(digit | 0x80); | 31 | try out.writeByte(digit | 0x80); |
| 32 | parsed -= digit * place; | 32 | parsed -= digit * place; |
| 33 | 33 | ||
| 34 | i += 1; | 34 | i += 1; |
| 35 | } | 35 | } |
| 36 | try writer.writeByte(@intCast(parsed)); | 36 | try out.writeByte(@intCast(parsed)); |
| 37 | i += 1; | 37 | i += 1; |
| 38 | } | 38 | } |
| 39 | } | ||
| 39 | 40 | ||
| 40 | return .{ .encoded = stream.getWritten() }; | 41 | pub const InitError = std.fmt.ParseIntError || error{ MissingPrefix, BufferTooSmall }; |
| 42 | |||
| 43 | pub fn fromDot(dot_notation: []const u8, out: []u8) InitError!Oid { | ||
| 44 | var bw: std.io.BufferedWriter = undefined; | ||
| 45 | bw.initFixed(out); | ||
| 46 | encode(dot_notation, &bw) catch |err| switch (err) { | ||
| 47 | error.WriteFailed => return error.BufferTooSmall, | ||
| 48 | else => |e| return e, | ||
| 49 | }; | ||
| 50 | return .{ .encoded = bw.getWritten() }; | ||
| 41 | } | 51 | } |
| 42 | 52 | ||
| 43 | test fromDot { | 53 | test fromDot { |
| ... | @@ -48,7 +58,7 @@ test fromDot { | ... | @@ -48,7 +58,7 @@ test fromDot { |
| 48 | } | 58 | } |
| 49 | } | 59 | } |
| 50 | 60 | ||
| 51 | pub fn toDot(self: Oid, writer: anytype) @TypeOf(writer).Error!void { | 61 | pub fn toDot(self: Oid, writer: *std.io.BufferedWriter) std.io.Writer.Error!void { |
| 52 | const encoded = self.encoded; | 62 | const encoded = self.encoded; |
| 53 | const first = @divTrunc(encoded[0], 40); | 63 | const first = @divTrunc(encoded[0], 40); |
| 54 | const second = encoded[0] - first * 40; | 64 | const second = encoded[0] - first * 40; |
| ... | @@ -80,9 +90,10 @@ test toDot { | ... | @@ -80,9 +90,10 @@ test toDot { |
| 80 | var buf: [256]u8 = undefined; | 90 | var buf: [256]u8 = undefined; |
| 81 | 91 | ||
| 82 | for (test_cases) |t| { | 92 | for (test_cases) |t| { |
| 83 | var stream = std.io.fixedBufferStream(&buf); | 93 | var bw: std.io.BufferedWriter = undefined; |
| 84 | try toDot(Oid{ .encoded = t.encoded }, stream.writer()); | 94 | bw.initFixed(&buf); |
| 85 | try std.testing.expectEqualStrings(t.dot_notation, stream.getWritten()); | 95 | try toDot(Oid{ .encoded = t.encoded }, &bw); |
| 96 | try std.testing.expectEqualStrings(t.dot_notation, bw.getWritten()); | ||
| 86 | } | 97 | } |
| 87 | } | 98 | } |
| 88 | 99 |
lib/std/crypto/phc_encoding.zig+5-3| ... | @@ -196,9 +196,11 @@ pub fn serialize(params: anytype, str: []u8) Error![]const u8 { | ... | @@ -196,9 +196,11 @@ pub fn serialize(params: anytype, str: []u8) Error![]const u8 { |
| 196 | 196 | ||
| 197 | /// Compute the number of bytes required to serialize `params` | 197 | /// Compute the number of bytes required to serialize `params` |
| 198 | pub fn calcSize(params: anytype) usize { | 198 | pub fn calcSize(params: anytype) usize { |
| 199 | var buf = io.countingWriter(io.null_writer); | 199 | var null_writer: std.io.Writer.Null = .{}; |
| 200 | serializeTo(params, buf.writer()) catch unreachable; | 200 | var trash: [128]u8 = undefined; |
| 201 | return @as(usize, @intCast(buf.bytes_written)); | 201 | var bw = null_writer.writable(&trash); |
| 202 | serializeTo(params, &bw) catch unreachable; | ||
| 203 | return bw.count; | ||
| 202 | } | 204 | } |
| 203 | 205 | ||
| 204 | fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void { | 206 | fn serializeTo(params: anytype, out: *std.io.BufferedWriter) !void { |
lib/std/crypto/sha1.zig deleted-319| ... | @@ -1,319 +0,0 @@ | ||
| 1 | const std = @import("../std.zig"); | ||
| 2 | const mem = std.mem; | ||
| 3 | const math = std.math; | ||
| 4 | |||
| 5 | const RoundParam = struct { | ||
| 6 | a: usize, | ||
| 7 | b: usize, | ||
| 8 | c: usize, | ||
| 9 | d: usize, | ||
| 10 | e: usize, | ||
| 11 | i: u32, | ||
| 12 | }; | ||
| 13 | |||
| 14 | fn roundParam(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam { | ||
| 15 | return RoundParam{ | ||
| 16 | .a = a, | ||
| 17 | .b = b, | ||
| 18 | .c = c, | ||
| 19 | .d = d, | ||
| 20 | .e = e, | ||
| 21 | .i = i, | ||
| 22 | }; | ||
| 23 | } | ||
| 24 | |||
| 25 | /// The SHA-1 function is now considered cryptographically broken. | ||
| 26 | /// Namely, it is feasible to find multiple inputs producing the same hash. | ||
| 27 | /// For a fast-performing, cryptographically secure hash function, see SHA512/256, BLAKE2 or BLAKE3. | ||
| 28 | pub const Sha1 = struct { | ||
| 29 | const Self = @This(); | ||
| 30 | pub const block_length = 64; | ||
| 31 | pub const digest_length = 20; | ||
| 32 | pub const Options = struct {}; | ||
| 33 | |||
| 34 | s: [5]u32, | ||
| 35 | // Streaming Cache | ||
| 36 | buf: [64]u8 = undefined, | ||
| 37 | buf_len: u8 = 0, | ||
| 38 | total_len: u64 = 0, | ||
| 39 | |||
| 40 | pub fn init(options: Options) Self { | ||
| 41 | _ = options; | ||
| 42 | return Self{ | ||
| 43 | .s = [_]u32{ | ||
| 44 | 0x67452301, | ||
| 45 | 0xEFCDAB89, | ||
| 46 | 0x98BADCFE, | ||
| 47 | 0x10325476, | ||
| 48 | 0xC3D2E1F0, | ||
| 49 | }, | ||
| 50 | }; | ||
| 51 | } | ||
| 52 | |||
| 53 | pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { | ||
| 54 | var d = Sha1.init(options); | ||
| 55 | d.update(b); | ||
| 56 | d.final(out); | ||
| 57 | } | ||
| 58 | |||
| 59 | pub fn update(d: *Self, b: []const u8) void { | ||
| 60 | var off: usize = 0; | ||
| 61 | |||
| 62 | // Partial buffer exists from previous update. Copy into buffer then hash. | ||
| 63 | if (d.buf_len != 0 and d.buf_len + b.len >= 64) { | ||
| 64 | off += 64 - d.buf_len; | ||
| 65 | @memcpy(d.buf[d.buf_len..][0..off], b[0..off]); | ||
| 66 | |||
| 67 | d.round(d.buf[0..]); | ||
| 68 | d.buf_len = 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | // Full middle blocks. | ||
| 72 | while (off + 64 <= b.len) : (off += 64) { | ||
| 73 | d.round(b[off..][0..64]); | ||
| 74 | } | ||
| 75 | |||
| 76 | // Copy any remainder for next pass. | ||
| 77 | @memcpy(d.buf[d.buf_len..][0 .. b.len - off], b[off..]); | ||
| 78 | d.buf_len += @as(u8, @intCast(b[off..].len)); | ||
| 79 | |||
| 80 | d.total_len += b.len; | ||
| 81 | } | ||
| 82 | |||
| 83 | pub fn peek(d: Self) [digest_length]u8 { | ||
| 84 | var copy = d; | ||
| 85 | return copy.finalResult(); | ||
| 86 | } | ||
| 87 | |||
| 88 | pub fn final(d: *Self, out: *[digest_length]u8) void { | ||
| 89 | // The buffer here will never be completely full. | ||
| 90 | @memset(d.buf[d.buf_len..], 0); | ||
| 91 | |||
| 92 | // Append padding bits. | ||
| 93 | d.buf[d.buf_len] = 0x80; | ||
| 94 | d.buf_len += 1; | ||
| 95 | |||
| 96 | // > 448 mod 512 so need to add an extra round to wrap around. | ||
| 97 | if (64 - d.buf_len < 8) { | ||
| 98 | d.round(d.buf[0..]); | ||
| 99 | @memset(d.buf[0..], 0); | ||
| 100 | } | ||
| 101 | |||
| 102 | // Append message length. | ||
| 103 | var i: usize = 1; | ||
| 104 | var len = d.total_len >> 5; | ||
| 105 | d.buf[63] = @as(u8, @intCast(d.total_len & 0x1f)) << 3; | ||
| 106 | while (i < 8) : (i += 1) { | ||
| 107 | d.buf[63 - i] = @as(u8, @intCast(len & 0xff)); | ||
| 108 | len >>= 8; | ||
| 109 | } | ||
| 110 | |||
| 111 | d.round(d.buf[0..]); | ||
| 112 | |||
| 113 | for (d.s, 0..) |s, j| { | ||
| 114 | mem.writeInt(u32, out[4 * j ..][0..4], s, .big); | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 118 | pub fn finalResult(d: *Self) [digest_length]u8 { | ||
| 119 | var result: [digest_length]u8 = undefined; | ||
| 120 | d.final(&result); | ||
| 121 | return result; | ||
| 122 | } | ||
| 123 | |||
| 124 | fn round(d: *Self, b: *const [64]u8) void { | ||
| 125 | var s: [16]u32 = undefined; | ||
| 126 | |||
| 127 | var v: [5]u32 = [_]u32{ | ||
| 128 | d.s[0], | ||
| 129 | d.s[1], | ||
| 130 | d.s[2], | ||
| 131 | d.s[3], | ||
| 132 | d.s[4], | ||
| 133 | }; | ||
| 134 | |||
| 135 | const round0a = comptime [_]RoundParam{ | ||
| 136 | roundParam(0, 1, 2, 3, 4, 0), | ||
| 137 | roundParam(4, 0, 1, 2, 3, 1), | ||
| 138 | roundParam(3, 4, 0, 1, 2, 2), | ||
| 139 | roundParam(2, 3, 4, 0, 1, 3), | ||
| 140 | roundParam(1, 2, 3, 4, 0, 4), | ||
| 141 | roundParam(0, 1, 2, 3, 4, 5), | ||
| 142 | roundParam(4, 0, 1, 2, 3, 6), | ||
| 143 | roundParam(3, 4, 0, 1, 2, 7), | ||
| 144 | roundParam(2, 3, 4, 0, 1, 8), | ||
| 145 | roundParam(1, 2, 3, 4, 0, 9), | ||
| 146 | roundParam(0, 1, 2, 3, 4, 10), | ||
| 147 | roundParam(4, 0, 1, 2, 3, 11), | ||
| 148 | roundParam(3, 4, 0, 1, 2, 12), | ||
| 149 | roundParam(2, 3, 4, 0, 1, 13), | ||
| 150 | roundParam(1, 2, 3, 4, 0, 14), | ||
| 151 | roundParam(0, 1, 2, 3, 4, 15), | ||
| 152 | }; | ||
| 153 | inline for (round0a) |r| { | ||
| 154 | s[r.i] = mem.readInt(u32, b[r.i * 4 ..][0..4], .big); | ||
| 155 | |||
| 156 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d])); | ||
| 157 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 158 | } | ||
| 159 | |||
| 160 | const round0b = comptime [_]RoundParam{ | ||
| 161 | roundParam(4, 0, 1, 2, 3, 16), | ||
| 162 | roundParam(3, 4, 0, 1, 2, 17), | ||
| 163 | roundParam(2, 3, 4, 0, 1, 18), | ||
| 164 | roundParam(1, 2, 3, 4, 0, 19), | ||
| 165 | }; | ||
| 166 | inline for (round0b) |r| { | ||
| 167 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 168 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 169 | |||
| 170 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d])); | ||
| 171 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 172 | } | ||
| 173 | |||
| 174 | const round1 = comptime [_]RoundParam{ | ||
| 175 | roundParam(0, 1, 2, 3, 4, 20), | ||
| 176 | roundParam(4, 0, 1, 2, 3, 21), | ||
| 177 | roundParam(3, 4, 0, 1, 2, 22), | ||
| 178 | roundParam(2, 3, 4, 0, 1, 23), | ||
| 179 | roundParam(1, 2, 3, 4, 0, 24), | ||
| 180 | roundParam(0, 1, 2, 3, 4, 25), | ||
| 181 | roundParam(4, 0, 1, 2, 3, 26), | ||
| 182 | roundParam(3, 4, 0, 1, 2, 27), | ||
| 183 | roundParam(2, 3, 4, 0, 1, 28), | ||
| 184 | roundParam(1, 2, 3, 4, 0, 29), | ||
| 185 | roundParam(0, 1, 2, 3, 4, 30), | ||
| 186 | roundParam(4, 0, 1, 2, 3, 31), | ||
| 187 | roundParam(3, 4, 0, 1, 2, 32), | ||
| 188 | roundParam(2, 3, 4, 0, 1, 33), | ||
| 189 | roundParam(1, 2, 3, 4, 0, 34), | ||
| 190 | roundParam(0, 1, 2, 3, 4, 35), | ||
| 191 | roundParam(4, 0, 1, 2, 3, 36), | ||
| 192 | roundParam(3, 4, 0, 1, 2, 37), | ||
| 193 | roundParam(2, 3, 4, 0, 1, 38), | ||
| 194 | roundParam(1, 2, 3, 4, 0, 39), | ||
| 195 | }; | ||
| 196 | inline for (round1) |r| { | ||
| 197 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 198 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 199 | |||
| 200 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x6ED9EBA1 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]); | ||
| 201 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 202 | } | ||
| 203 | |||
| 204 | const round2 = comptime [_]RoundParam{ | ||
| 205 | roundParam(0, 1, 2, 3, 4, 40), | ||
| 206 | roundParam(4, 0, 1, 2, 3, 41), | ||
| 207 | roundParam(3, 4, 0, 1, 2, 42), | ||
| 208 | roundParam(2, 3, 4, 0, 1, 43), | ||
| 209 | roundParam(1, 2, 3, 4, 0, 44), | ||
| 210 | roundParam(0, 1, 2, 3, 4, 45), | ||
| 211 | roundParam(4, 0, 1, 2, 3, 46), | ||
| 212 | roundParam(3, 4, 0, 1, 2, 47), | ||
| 213 | roundParam(2, 3, 4, 0, 1, 48), | ||
| 214 | roundParam(1, 2, 3, 4, 0, 49), | ||
| 215 | roundParam(0, 1, 2, 3, 4, 50), | ||
| 216 | roundParam(4, 0, 1, 2, 3, 51), | ||
| 217 | roundParam(3, 4, 0, 1, 2, 52), | ||
| 218 | roundParam(2, 3, 4, 0, 1, 53), | ||
| 219 | roundParam(1, 2, 3, 4, 0, 54), | ||
| 220 | roundParam(0, 1, 2, 3, 4, 55), | ||
| 221 | roundParam(4, 0, 1, 2, 3, 56), | ||
| 222 | roundParam(3, 4, 0, 1, 2, 57), | ||
| 223 | roundParam(2, 3, 4, 0, 1, 58), | ||
| 224 | roundParam(1, 2, 3, 4, 0, 59), | ||
| 225 | }; | ||
| 226 | inline for (round2) |r| { | ||
| 227 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 228 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 229 | |||
| 230 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x8F1BBCDC +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d])); | ||
| 231 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 232 | } | ||
| 233 | |||
| 234 | const round3 = comptime [_]RoundParam{ | ||
| 235 | roundParam(0, 1, 2, 3, 4, 60), | ||
| 236 | roundParam(4, 0, 1, 2, 3, 61), | ||
| 237 | roundParam(3, 4, 0, 1, 2, 62), | ||
| 238 | roundParam(2, 3, 4, 0, 1, 63), | ||
| 239 | roundParam(1, 2, 3, 4, 0, 64), | ||
| 240 | roundParam(0, 1, 2, 3, 4, 65), | ||
| 241 | roundParam(4, 0, 1, 2, 3, 66), | ||
| 242 | roundParam(3, 4, 0, 1, 2, 67), | ||
| 243 | roundParam(2, 3, 4, 0, 1, 68), | ||
| 244 | roundParam(1, 2, 3, 4, 0, 69), | ||
| 245 | roundParam(0, 1, 2, 3, 4, 70), | ||
| 246 | roundParam(4, 0, 1, 2, 3, 71), | ||
| 247 | roundParam(3, 4, 0, 1, 2, 72), | ||
| 248 | roundParam(2, 3, 4, 0, 1, 73), | ||
| 249 | roundParam(1, 2, 3, 4, 0, 74), | ||
| 250 | roundParam(0, 1, 2, 3, 4, 75), | ||
| 251 | roundParam(4, 0, 1, 2, 3, 76), | ||
| 252 | roundParam(3, 4, 0, 1, 2, 77), | ||
| 253 | roundParam(2, 3, 4, 0, 1, 78), | ||
| 254 | roundParam(1, 2, 3, 4, 0, 79), | ||
| 255 | }; | ||
| 256 | inline for (round3) |r| { | ||
| 257 | const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf]; | ||
| 258 | s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1)); | ||
| 259 | |||
| 260 | v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0xCA62C1D6 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]); | ||
| 261 | v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30)); | ||
| 262 | } | ||
| 263 | |||
| 264 | d.s[0] +%= v[0]; | ||
| 265 | d.s[1] +%= v[1]; | ||
| 266 | d.s[2] +%= v[2]; | ||
| 267 | d.s[3] +%= v[3]; | ||
| 268 | d.s[4] +%= v[4]; | ||
| 269 | } | ||
| 270 | |||
| 271 | pub const Error = error{}; | ||
| 272 | pub const Writer = std.io.Writer(*Self, Error, write); | ||
| 273 | |||
| 274 | fn write(self: *Self, bytes: []const u8) Error!usize { | ||
| 275 | self.update(bytes); | ||
| 276 | return bytes.len; | ||
| 277 | } | ||
| 278 | |||
| 279 | pub fn writer(self: *Self) Writer { | ||
| 280 | return .{ .context = self }; | ||
| 281 | } | ||
| 282 | }; | ||
| 283 | |||
| 284 | const htest = @import("test.zig"); | ||
| 285 | |||
| 286 | test "sha1 single" { | ||
| 287 | try htest.assertEqualHash(Sha1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", ""); | ||
| 288 | try htest.assertEqualHash(Sha1, "a9993e364706816aba3e25717850c26c9cd0d89d", "abc"); | ||
| 289 | try htest.assertEqualHash(Sha1, "a49b2446a02c645bf419f995b67091253a04a259", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"); | ||
| 290 | } | ||
| 291 | |||
| 292 | test "sha1 streaming" { | ||
| 293 | var h = Sha1.init(.{}); | ||
| 294 | var out: [20]u8 = undefined; | ||
| 295 | |||
| 296 | h.final(&out); | ||
| 297 | try htest.assertEqual("da39a3ee5e6b4b0d3255bfef95601890afd80709", out[0..]); | ||
| 298 | |||
| 299 | h = Sha1.init(.{}); | ||
| 300 | h.update("abc"); | ||
| 301 | h.final(&out); | ||
| 302 | try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); | ||
| 303 | |||
| 304 | h = Sha1.init(.{}); | ||
| 305 | h.update("a"); | ||
| 306 | h.update("b"); | ||
| 307 | h.update("c"); | ||
| 308 | h.final(&out); | ||
| 309 | try htest.assertEqual("a9993e364706816aba3e25717850c26c9cd0d89d", out[0..]); | ||
| 310 | } | ||
| 311 | |||
| 312 | test "sha1 aligned final" { | ||
| 313 | var block = [_]u8{0} ** Sha1.block_length; | ||
| 314 | var out: [Sha1.digest_length]u8 = undefined; | ||
| 315 | |||
| 316 | var h = Sha1.init(.{}); | ||
| 317 | h.update(&block); | ||
| 318 | h.final(out[0..]); | ||
| 319 | } | ||
lib/std/crypto/sha2.zig+27-13| ... | @@ -95,14 +95,19 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { | ... | @@ -95,14 +95,19 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { |
| 95 | pub const Options = struct {}; | 95 | pub const Options = struct {}; |
| 96 | 96 | ||
| 97 | s: [8]u32 align(16), | 97 | s: [8]u32 align(16), |
| 98 | // Streaming Cache | 98 | /// Streaming Cache |
| 99 | buf: [64]u8 = undefined, | 99 | buf: [64]u8, |
| 100 | buf_len: u8 = 0, | 100 | buf_len: u8, |
| 101 | total_len: u64 = 0, | 101 | total_len: u64, |
| 102 | 102 | ||
| 103 | pub fn init(options: Options) Self { | 103 | pub fn init(options: Options) Self { |
| 104 | _ = options; | 104 | _ = options; |
| 105 | return Self{ .s = iv }; | 105 | return .{ |
| 106 | .s = iv, | ||
| 107 | .buf = undefined, | ||
| 108 | .buf_len = 0, | ||
| 109 | .total_len = 0, | ||
| 110 | }; | ||
| 106 | } | 111 | } |
| 107 | 112 | ||
| 108 | pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { | 113 | pub fn hash(b: []const u8, out: *[digest_length]u8, options: Options) void { |
| ... | @@ -377,16 +382,25 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { | ... | @@ -377,16 +382,25 @@ fn Sha2x32(comptime iv: Iv32, digest_bits: comptime_int) type { |
| 377 | for (&d.s, v) |*dv, vv| dv.* +%= vv; | 382 | for (&d.s, v) |*dv, vv| dv.* +%= vv; |
| 378 | } | 383 | } |
| 379 | 384 | ||
| 380 | pub const Error = error{}; | 385 | pub fn writable(this: *@This(), buffer: []u8) std.io.BufferedWriter { |
| 381 | pub const Writer = std.io.Writer(*Self, Error, write); | 386 | return .{ |
| 382 | 387 | .unbuffered_writer = .{ | |
| 383 | fn write(self: *Self, bytes: []const u8) Error!usize { | 388 | .context = this, |
| 384 | self.update(bytes); | 389 | .vtable = &.{ |
| 385 | return bytes.len; | 390 | .writeSplat = writeSplat, |
| 391 | .writeFile = std.io.Writer.unimplementedWriteFile, | ||
| 392 | }, | ||
| 393 | }, | ||
| 394 | .buffer = buffer, | ||
| 395 | }; | ||
| 386 | } | 396 | } |
| 387 | 397 | ||
| 388 | pub fn writer(self: *Self) Writer { | 398 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { |
| 389 | return .{ .context = self }; | 399 | const this: *@This() = @ptrCast(@alignCast(context)); |
| 400 | const start_total = this.total_len; | ||
| 401 | for (data[0 .. data.len - 1]) |slice| this.update(slice); | ||
| 402 | for (0..splat) |_| this.update(data[data.len - 1]); | ||
| 403 | return @intCast(this.total_len - start_total); | ||
| 390 | } | 404 | } |
| 391 | }; | 405 | }; |
| 392 | } | 406 | } |
lib/std/crypto/sha3.zig-60| ... | @@ -80,18 +80,6 @@ pub fn Keccak(comptime f: u11, comptime output_bits: u11, comptime default_delim | ... | @@ -80,18 +80,6 @@ pub fn Keccak(comptime f: u11, comptime output_bits: u11, comptime default_delim |
| 80 | self.st.pad(); | 80 | self.st.pad(); |
| 81 | self.st.squeeze(out[0..]); | 81 | self.st.squeeze(out[0..]); |
| 82 | } | 82 | } |
| 83 | |||
| 84 | pub const Error = error{}; | ||
| 85 | pub const Writer = std.io.Writer(*Self, Error, write); | ||
| 86 | |||
| 87 | fn write(self: *Self, bytes: []const u8) Error!usize { | ||
| 88 | self.update(bytes); | ||
| 89 | return bytes.len; | ||
| 90 | } | ||
| 91 | |||
| 92 | pub fn writer(self: *Self) Writer { | ||
| 93 | return .{ .context = self }; | ||
| 94 | } | ||
| 95 | }; | 83 | }; |
| 96 | } | 84 | } |
| 97 | 85 | ||
| ... | @@ -191,18 +179,6 @@ fn ShakeLike(comptime security_level: u11, comptime default_delim: u8, comptime | ... | @@ -191,18 +179,6 @@ fn ShakeLike(comptime security_level: u11, comptime default_delim: u8, comptime |
| 191 | pub fn fillBlock(self: *Self) void { | 179 | pub fn fillBlock(self: *Self) void { |
| 192 | self.st.fillBlock(); | 180 | self.st.fillBlock(); |
| 193 | } | 181 | } |
| 194 | |||
| 195 | pub const Error = error{}; | ||
| 196 | pub const Writer = std.io.Writer(*Self, Error, write); | ||
| 197 | |||
| 198 | fn write(self: *Self, bytes: []const u8) Error!usize { | ||
| 199 | self.update(bytes); | ||
| 200 | return bytes.len; | ||
| 201 | } | ||
| 202 | |||
| 203 | pub fn writer(self: *Self) Writer { | ||
| 204 | return .{ .context = self }; | ||
| 205 | } | ||
| 206 | }; | 182 | }; |
| 207 | } | 183 | } |
| 208 | 184 | ||
| ... | @@ -284,18 +260,6 @@ fn CShakeLike(comptime security_level: u11, comptime default_delim: u8, comptime | ... | @@ -284,18 +260,6 @@ fn CShakeLike(comptime security_level: u11, comptime default_delim: u8, comptime |
| 284 | pub fn fillBlock(self: *Self) void { | 260 | pub fn fillBlock(self: *Self) void { |
| 285 | self.shaker.fillBlock(); | 261 | self.shaker.fillBlock(); |
| 286 | } | 262 | } |
| 287 | |||
| 288 | pub const Error = error{}; | ||
| 289 | pub const Writer = std.io.Writer(*Self, Error, write); | ||
| 290 | |||
| 291 | fn write(self: *Self, bytes: []const u8) Error!usize { | ||
| 292 | self.update(bytes); | ||
| 293 | return bytes.len; | ||
| 294 | } | ||
| 295 | |||
| 296 | pub fn writer(self: *Self) Writer { | ||
| 297 | return .{ .context = self }; | ||
| 298 | } | ||
| 299 | }; | 263 | }; |
| 300 | } | 264 | } |
| 301 | 265 | ||
| ... | @@ -390,18 +354,6 @@ fn KMacLike(comptime security_level: u11, comptime default_delim: u8, comptime r | ... | @@ -390,18 +354,6 @@ fn KMacLike(comptime security_level: u11, comptime default_delim: u8, comptime r |
| 390 | ctx.update(msg); | 354 | ctx.update(msg); |
| 391 | ctx.final(out); | 355 | ctx.final(out); |
| 392 | } | 356 | } |
| 393 | |||
| 394 | pub const Error = error{}; | ||
| 395 | pub const Writer = std.io.Writer(*Self, Error, write); | ||
| 396 | |||
| 397 | fn write(self: *Self, bytes: []const u8) Error!usize { | ||
| 398 | self.update(bytes); | ||
| 399 | return bytes.len; | ||
| 400 | } | ||
| 401 | |||
| 402 | pub fn writer(self: *Self) Writer { | ||
| 403 | return .{ .context = self }; | ||
| 404 | } | ||
| 405 | }; | 357 | }; |
| 406 | } | 358 | } |
| 407 | 359 | ||
| ... | @@ -482,18 +434,6 @@ fn TupleHashLike(comptime security_level: u11, comptime default_delim: u8, compt | ... | @@ -482,18 +434,6 @@ fn TupleHashLike(comptime security_level: u11, comptime default_delim: u8, compt |
| 482 | } | 434 | } |
| 483 | self.cshaker.squeeze(out); | 435 | self.cshaker.squeeze(out); |
| 484 | } | 436 | } |
| 485 | |||
| 486 | pub const Error = error{}; | ||
| 487 | pub const Writer = std.io.Writer(*Self, Error, write); | ||
| 488 | |||
| 489 | fn write(self: *Self, bytes: []const u8) Error!usize { | ||
| 490 | self.update(bytes); | ||
| 491 | return bytes.len; | ||
| 492 | } | ||
| 493 | |||
| 494 | pub fn writer(self: *Self) Writer { | ||
| 495 | return .{ .context = self }; | ||
| 496 | } | ||
| 497 | }; | 437 | }; |
| 498 | } | 438 | } |
| 499 | 439 |
lib/std/crypto/siphash.zig-42| ... | @@ -238,48 +238,6 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) | ... | @@ -238,48 +238,6 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) |
| 238 | pub fn toInt(msg: []const u8, key: *const [key_length]u8) T { | 238 | pub fn toInt(msg: []const u8, key: *const [key_length]u8) T { |
| 239 | return State.hash(msg, key); | 239 | return State.hash(msg, key); |
| 240 | } | 240 | } |
| 241 | |||
| 242 | pub fn writer(self: *Self) std.io.Writer { | ||
| 243 | return .{ | ||
| 244 | .context = self, | ||
| 245 | .vtable = &.{ | ||
| 246 | .writeSplat = &writeSplat, | ||
| 247 | .writeFile = &writeFile, | ||
| 248 | }, | ||
| 249 | }; | ||
| 250 | } | ||
| 251 | |||
| 252 | fn writeSplat(ctx: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | ||
| 253 | const self: *Self = @alignCast(@ptrCast(ctx)); | ||
| 254 | var len: usize = 0; | ||
| 255 | for (data[0 .. data.len - 1]) |slice| { | ||
| 256 | self.update(slice); | ||
| 257 | len += slice.len; | ||
| 258 | } | ||
| 259 | { | ||
| 260 | const slice = data[data.len - 1]; | ||
| 261 | for (0..splat) |_| self.update(slice); | ||
| 262 | len += slice.len * splat; | ||
| 263 | } | ||
| 264 | return len; | ||
| 265 | } | ||
| 266 | |||
| 267 | fn writeFile( | ||
| 268 | ctx: ?*anyopaque, | ||
| 269 | file: std.fs.File, | ||
| 270 | offset: std.io.Writer.Offset, | ||
| 271 | limit: std.io.Writer.Limit, | ||
| 272 | headers_and_trailers: []const []const u8, | ||
| 273 | headers_len: usize, | ||
| 274 | ) std.io.Writer.Error!usize { | ||
| 275 | _ = ctx; | ||
| 276 | _ = file; | ||
| 277 | _ = offset; | ||
| 278 | _ = limit; | ||
| 279 | _ = headers_and_trailers; | ||
| 280 | _ = headers_len; | ||
| 281 | @panic("TODO"); | ||
| 282 | } | ||
| 283 | }; | 241 | }; |
| 284 | } | 242 | } |
| 285 | 243 |
lib/std/debug/Dwarf.zig+1-1| ... | @@ -2176,7 +2176,7 @@ pub const ElfModule = struct { | ... | @@ -2176,7 +2176,7 @@ pub const ElfModule = struct { |
| 2176 | parent_mapped_mem: ?[]align(std.heap.page_size_min) const u8, | 2176 | parent_mapped_mem: ?[]align(std.heap.page_size_min) const u8, |
| 2177 | elf_filename: ?[]const u8, | 2177 | elf_filename: ?[]const u8, |
| 2178 | ) LoadError!Dwarf.ElfModule { | 2178 | ) LoadError!Dwarf.ElfModule { |
| 2179 | if (expected_crc) |crc| if (crc != std.hash.crc.Crc32.hash(mapped_mem)) return error.InvalidDebugInfo; | 2179 | if (expected_crc) |crc| if (crc != std.hash.Crc32.hash(mapped_mem)) return error.InvalidDebugInfo; |
| 2180 | 2180 | ||
| 2181 | const hdr: *const elf.Ehdr = @ptrCast(&mapped_mem[0]); | 2181 | const hdr: *const elf.Ehdr = @ptrCast(&mapped_mem[0]); |
| 2182 | if (!mem.eql(u8, hdr.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic; | 2182 | if (!mem.eql(u8, hdr.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic; |
lib/std/fs/File.zig+34| ... | @@ -934,6 +934,10 @@ pub const Reader = struct { | ... | @@ -934,6 +934,10 @@ pub const Reader = struct { |
| 934 | }; | 934 | }; |
| 935 | } | 935 | } |
| 936 | 936 | ||
| 937 | pub fn readable(r: *Reader, buffer: []u8) std.io.BufferedReader { | ||
| 938 | return interface(r).buffered(buffer); | ||
| 939 | } | ||
| 940 | |||
| 937 | pub fn getSize(r: *Reader) GetEndPosError!u64 { | 941 | pub fn getSize(r: *Reader) GetEndPosError!u64 { |
| 938 | return r.size orelse { | 942 | return r.size orelse { |
| 939 | if (r.size_err) |err| return err; | 943 | if (r.size_err) |err| return err; |
| ... | @@ -1228,6 +1232,7 @@ pub const Writer = struct { | ... | @@ -1228,6 +1232,7 @@ pub const Writer = struct { |
| 1228 | pos: u64 = 0, | 1232 | pos: u64 = 0, |
| 1229 | sendfile_err: ?SendfileError = null, | 1233 | sendfile_err: ?SendfileError = null, |
| 1230 | read_err: ?ReadError = null, | 1234 | read_err: ?ReadError = null, |
| 1235 | seek_err: ?SeekError = null, | ||
| 1231 | 1236 | ||
| 1232 | pub const Mode = Reader.Mode; | 1237 | pub const Mode = Reader.Mode; |
| 1233 | 1238 | ||
| ... | @@ -1250,6 +1255,20 @@ pub const Writer = struct { | ... | @@ -1250,6 +1255,20 @@ pub const Writer = struct { |
| 1250 | }; | 1255 | }; |
| 1251 | } | 1256 | } |
| 1252 | 1257 | ||
| 1258 | pub fn writable(w: *Writer, buffer: []u8) std.io.BufferedWriter { | ||
| 1259 | return interface(w).buffered(buffer); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | pub fn moveToReader(w: *Writer) Reader { | ||
| 1263 | defer w.* = undefined; | ||
| 1264 | return .{ | ||
| 1265 | .file = w.file, | ||
| 1266 | .mode = w.mode, | ||
| 1267 | .pos = w.pos, | ||
| 1268 | .seek_err = w.seek_err, | ||
| 1269 | }; | ||
| 1270 | } | ||
| 1271 | |||
| 1253 | pub fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | 1272 | pub fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { |
| 1254 | const w: *Writer = @ptrCast(@alignCast(context)); | 1273 | const w: *Writer = @ptrCast(@alignCast(context)); |
| 1255 | const handle = w.file.handle; | 1274 | const handle = w.file.handle; |
| ... | @@ -1347,6 +1366,21 @@ pub const Writer = struct { | ... | @@ -1347,6 +1366,21 @@ pub const Writer = struct { |
| 1347 | } | 1366 | } |
| 1348 | return error.Unimplemented; | 1367 | return error.Unimplemented; |
| 1349 | } | 1368 | } |
| 1369 | |||
| 1370 | pub fn seekTo(w: *Writer, offset: u64) SeekError!void { | ||
| 1371 | if (w.seek_err) |err| return err; | ||
| 1372 | switch (w.mode) { | ||
| 1373 | .positional, .positional_reading => { | ||
| 1374 | w.pos = offset; | ||
| 1375 | }, | ||
| 1376 | .streaming, .streaming_reading => { | ||
| 1377 | posix.lseek_SET(w.file.handle, offset) catch |err| { | ||
| 1378 | w.seek_err = err; | ||
| 1379 | return err; | ||
| 1380 | }; | ||
| 1381 | }, | ||
| 1382 | } | ||
| 1383 | } | ||
| 1350 | }; | 1384 | }; |
| 1351 | 1385 | ||
| 1352 | /// Defaults to positional reading; falls back to streaming. | 1386 | /// Defaults to positional reading; falls back to streaming. |
lib/std/hash.zig+1-2| ... | @@ -6,9 +6,8 @@ pub const autoHash = auto_hash.autoHash; | ... | @@ -6,9 +6,8 @@ pub const autoHash = auto_hash.autoHash; |
| 6 | pub const autoHashStrat = auto_hash.hash; | 6 | pub const autoHashStrat = auto_hash.hash; |
| 7 | pub const Strategy = auto_hash.HashStrategy; | 7 | pub const Strategy = auto_hash.HashStrategy; |
| 8 | 8 | ||
| 9 | // pub for polynomials + generic crc32 construction | ||
| 10 | pub const crc = @import("hash/crc.zig"); | 9 | pub const crc = @import("hash/crc.zig"); |
| 11 | pub const Crc32 = crc.Crc32; | 10 | pub const Crc32 = crc.Crc32IsoHdlc; |
| 12 | 11 | ||
| 13 | const fnv = @import("hash/fnv.zig"); | 12 | const fnv = @import("hash/fnv.zig"); |
| 14 | pub const Fnv1a_32 = fnv.Fnv1a_32; | 13 | pub const Fnv1a_32 = fnv.Fnv1a_32; |
lib/std/hash/crc.zig+237-125| ... | @@ -1,19 +1,127 @@ | ... | @@ -1,19 +1,127 @@ |
| 1 | //! This file is auto-generated by tools/update_crc_catalog.zig. | 1 | const std = @import("../std.zig"); |
| 2 | 2 | ||
| 3 | const impl = @import("crc/impl.zig"); | 3 | pub fn Generic(comptime W: type, comptime algorithm: Algorithm(W)) type { |
| 4 | 4 | return struct { | |
| 5 | pub const Crc = impl.Crc; | 5 | const Self = @This(); |
| 6 | pub const Polynomial = impl.Polynomial; | 6 | const I = if (@bitSizeOf(W) < 8) u8 else W; |
| 7 | pub const Crc32WithPoly = impl.Crc32WithPoly; | 7 | const lookup_table = blk: { |
| 8 | pub const Crc32SmallWithPoly = impl.Crc32SmallWithPoly; | 8 | @setEvalBranchQuota(2500); |
| 9 | 9 | ||
| 10 | pub const Crc32 = Crc32IsoHdlc; | 10 | const poly = if (algorithm.reflect_input) |
| 11 | @bitReverse(@as(I, algorithm.polynomial)) >> (@bitSizeOf(I) - @bitSizeOf(W)) | ||
| 12 | else | ||
| 13 | @as(I, algorithm.polynomial) << (@bitSizeOf(I) - @bitSizeOf(W)); | ||
| 14 | |||
| 15 | var table: [256]I = undefined; | ||
| 16 | for (&table, 0..) |*e, i| { | ||
| 17 | var crc: I = i; | ||
| 18 | if (algorithm.reflect_input) { | ||
| 19 | var j: usize = 0; | ||
| 20 | while (j < 8) : (j += 1) { | ||
| 21 | crc = (crc >> 1) ^ ((crc & 1) * poly); | ||
| 22 | } | ||
| 23 | } else { | ||
| 24 | crc <<= @bitSizeOf(I) - 8; | ||
| 25 | var j: usize = 0; | ||
| 26 | while (j < 8) : (j += 1) { | ||
| 27 | crc = (crc << 1) ^ (((crc >> (@bitSizeOf(I) - 1)) & 1) * poly); | ||
| 28 | } | ||
| 29 | } | ||
| 30 | e.* = crc; | ||
| 31 | } | ||
| 32 | break :blk table; | ||
| 33 | }; | ||
| 34 | |||
| 35 | crc: I, | ||
| 36 | |||
| 37 | pub fn init() Self { | ||
| 38 | const initial = if (algorithm.reflect_input) | ||
| 39 | @bitReverse(@as(I, algorithm.initial)) >> (@bitSizeOf(I) - @bitSizeOf(W)) | ||
| 40 | else | ||
| 41 | @as(I, algorithm.initial) << (@bitSizeOf(I) - @bitSizeOf(W)); | ||
| 42 | return .{ .crc = initial }; | ||
| 43 | } | ||
| 44 | |||
| 45 | inline fn tableEntry(index: I) I { | ||
| 46 | return lookup_table[@as(u8, @intCast(index & 0xFF))]; | ||
| 47 | } | ||
| 48 | |||
| 49 | pub fn updateByte(self: *Self, byte: u8) void { | ||
| 50 | if (@bitSizeOf(I) <= 8) { | ||
| 51 | self.crc = tableEntry(self.crc ^ byte); | ||
| 52 | } else if (algorithm.reflect_input) { | ||
| 53 | const table_index = self.crc ^ byte; | ||
| 54 | self.crc = tableEntry(table_index) ^ (self.crc >> 8); | ||
| 55 | } else { | ||
| 56 | const table_index = (self.crc >> (@bitSizeOf(I) - 8)) ^ byte; | ||
| 57 | self.crc = tableEntry(table_index) ^ (self.crc << 8); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | pub fn update(self: *Self, bytes: []const u8) void { | ||
| 62 | for (bytes) |byte| updateByte(self, byte); | ||
| 63 | } | ||
| 64 | |||
| 65 | pub fn final(self: Self) W { | ||
| 66 | var c = self.crc; | ||
| 67 | if (algorithm.reflect_input != algorithm.reflect_output) { | ||
| 68 | c = @bitReverse(c); | ||
| 69 | } | ||
| 70 | if (!algorithm.reflect_output) { | ||
| 71 | c >>= @bitSizeOf(I) - @bitSizeOf(W); | ||
| 72 | } | ||
| 73 | return @intCast(c ^ algorithm.xor_output); | ||
| 74 | } | ||
| 75 | |||
| 76 | pub fn hash(bytes: []const u8) W { | ||
| 77 | var c = Self.init(); | ||
| 78 | c.update(bytes); | ||
| 79 | return c.final(); | ||
| 80 | } | ||
| 81 | |||
| 82 | pub fn writable(self: *Self, buffer: []u8) std.io.BufferedWriter { | ||
| 83 | return .{ | ||
| 84 | .unbuffered_writer = .{ | ||
| 85 | .context = self, | ||
| 86 | .vtable = &.{ | ||
| 87 | .writeSplat = writeSplat, | ||
| 88 | .writeFile = std.io.Writer.unimplementedWriteFile, | ||
| 89 | }, | ||
| 90 | }, | ||
| 91 | .buffer = buffer, | ||
| 92 | }; | ||
| 93 | } | ||
| 94 | |||
| 95 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) std.io.Writer.Error!usize { | ||
| 96 | const self: *Self = @ptrCast(@alignCast(context)); | ||
| 97 | var n: usize = 0; | ||
| 98 | for (data[0 .. data.len - 1]) |slice| { | ||
| 99 | self.update(slice); | ||
| 100 | n += slice.len; | ||
| 101 | } | ||
| 102 | const last = data[data.len - 1]; | ||
| 103 | if (last.len == 1) { | ||
| 104 | for (0..splat) |_| self.updateByte(last[0]); | ||
| 105 | return n + splat; | ||
| 106 | } else { | ||
| 107 | for (0..splat) |_| self.update(last); | ||
| 108 | return n + last.len * splat; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | }; | ||
| 112 | } | ||
| 11 | 113 | ||
| 12 | test { | 114 | pub fn Algorithm(comptime W: type) type { |
| 13 | _ = @import("crc/test.zig"); | 115 | return struct { |
| 116 | polynomial: W, | ||
| 117 | initial: W, | ||
| 118 | reflect_input: bool, | ||
| 119 | reflect_output: bool, | ||
| 120 | xor_output: W, | ||
| 121 | }; | ||
| 14 | } | 122 | } |
| 15 | 123 | ||
| 16 | pub const Crc3Gsm = Crc(u3, .{ | 124 | pub const Crc3Gsm = Generic(u3, .{ |
| 17 | .polynomial = 0x3, | 125 | .polynomial = 0x3, |
| 18 | .initial = 0x0, | 126 | .initial = 0x0, |
| 19 | .reflect_input = false, | 127 | .reflect_input = false, |
| ... | @@ -21,7 +129,7 @@ pub const Crc3Gsm = Crc(u3, .{ | ... | @@ -21,7 +129,7 @@ pub const Crc3Gsm = Crc(u3, .{ |
| 21 | .xor_output = 0x7, | 129 | .xor_output = 0x7, |
| 22 | }); | 130 | }); |
| 23 | 131 | ||
| 24 | pub const Crc3Rohc = Crc(u3, .{ | 132 | pub const Crc3Rohc = Generic(u3, .{ |
| 25 | .polynomial = 0x3, | 133 | .polynomial = 0x3, |
| 26 | .initial = 0x7, | 134 | .initial = 0x7, |
| 27 | .reflect_input = true, | 135 | .reflect_input = true, |
| ... | @@ -29,7 +137,7 @@ pub const Crc3Rohc = Crc(u3, .{ | ... | @@ -29,7 +137,7 @@ pub const Crc3Rohc = Crc(u3, .{ |
| 29 | .xor_output = 0x0, | 137 | .xor_output = 0x0, |
| 30 | }); | 138 | }); |
| 31 | 139 | ||
| 32 | pub const Crc4G704 = Crc(u4, .{ | 140 | pub const Crc4G704 = Generic(u4, .{ |
| 33 | .polynomial = 0x3, | 141 | .polynomial = 0x3, |
| 34 | .initial = 0x0, | 142 | .initial = 0x0, |
| 35 | .reflect_input = true, | 143 | .reflect_input = true, |
| ... | @@ -37,7 +145,7 @@ pub const Crc4G704 = Crc(u4, .{ | ... | @@ -37,7 +145,7 @@ pub const Crc4G704 = Crc(u4, .{ |
| 37 | .xor_output = 0x0, | 145 | .xor_output = 0x0, |
| 38 | }); | 146 | }); |
| 39 | 147 | ||
| 40 | pub const Crc4Interlaken = Crc(u4, .{ | 148 | pub const Crc4Interlaken = Generic(u4, .{ |
| 41 | .polynomial = 0x3, | 149 | .polynomial = 0x3, |
| 42 | .initial = 0xf, | 150 | .initial = 0xf, |
| 43 | .reflect_input = false, | 151 | .reflect_input = false, |
| ... | @@ -45,7 +153,7 @@ pub const Crc4Interlaken = Crc(u4, .{ | ... | @@ -45,7 +153,7 @@ pub const Crc4Interlaken = Crc(u4, .{ |
| 45 | .xor_output = 0xf, | 153 | .xor_output = 0xf, |
| 46 | }); | 154 | }); |
| 47 | 155 | ||
| 48 | pub const Crc5EpcC1g2 = Crc(u5, .{ | 156 | pub const Crc5EpcC1g2 = Generic(u5, .{ |
| 49 | .polynomial = 0x09, | 157 | .polynomial = 0x09, |
| 50 | .initial = 0x09, | 158 | .initial = 0x09, |
| 51 | .reflect_input = false, | 159 | .reflect_input = false, |
| ... | @@ -53,7 +161,7 @@ pub const Crc5EpcC1g2 = Crc(u5, .{ | ... | @@ -53,7 +161,7 @@ pub const Crc5EpcC1g2 = Crc(u5, .{ |
| 53 | .xor_output = 0x00, | 161 | .xor_output = 0x00, |
| 54 | }); | 162 | }); |
| 55 | 163 | ||
| 56 | pub const Crc5G704 = Crc(u5, .{ | 164 | pub const Crc5G704 = Generic(u5, .{ |
| 57 | .polynomial = 0x15, | 165 | .polynomial = 0x15, |
| 58 | .initial = 0x00, | 166 | .initial = 0x00, |
| 59 | .reflect_input = true, | 167 | .reflect_input = true, |
| ... | @@ -61,7 +169,7 @@ pub const Crc5G704 = Crc(u5, .{ | ... | @@ -61,7 +169,7 @@ pub const Crc5G704 = Crc(u5, .{ |
| 61 | .xor_output = 0x00, | 169 | .xor_output = 0x00, |
| 62 | }); | 170 | }); |
| 63 | 171 | ||
| 64 | pub const Crc5Usb = Crc(u5, .{ | 172 | pub const Crc5Usb = Generic(u5, .{ |
| 65 | .polynomial = 0x05, | 173 | .polynomial = 0x05, |
| 66 | .initial = 0x1f, | 174 | .initial = 0x1f, |
| 67 | .reflect_input = true, | 175 | .reflect_input = true, |
| ... | @@ -69,7 +177,7 @@ pub const Crc5Usb = Crc(u5, .{ | ... | @@ -69,7 +177,7 @@ pub const Crc5Usb = Crc(u5, .{ |
| 69 | .xor_output = 0x1f, | 177 | .xor_output = 0x1f, |
| 70 | }); | 178 | }); |
| 71 | 179 | ||
| 72 | pub const Crc6Cdma2000A = Crc(u6, .{ | 180 | pub const Crc6Cdma2000A = Generic(u6, .{ |
| 73 | .polynomial = 0x27, | 181 | .polynomial = 0x27, |
| 74 | .initial = 0x3f, | 182 | .initial = 0x3f, |
| 75 | .reflect_input = false, | 183 | .reflect_input = false, |
| ... | @@ -77,7 +185,7 @@ pub const Crc6Cdma2000A = Crc(u6, .{ | ... | @@ -77,7 +185,7 @@ pub const Crc6Cdma2000A = Crc(u6, .{ |
| 77 | .xor_output = 0x00, | 185 | .xor_output = 0x00, |
| 78 | }); | 186 | }); |
| 79 | 187 | ||
| 80 | pub const Crc6Cdma2000B = Crc(u6, .{ | 188 | pub const Crc6Cdma2000B = Generic(u6, .{ |
| 81 | .polynomial = 0x07, | 189 | .polynomial = 0x07, |
| 82 | .initial = 0x3f, | 190 | .initial = 0x3f, |
| 83 | .reflect_input = false, | 191 | .reflect_input = false, |
| ... | @@ -85,7 +193,7 @@ pub const Crc6Cdma2000B = Crc(u6, .{ | ... | @@ -85,7 +193,7 @@ pub const Crc6Cdma2000B = Crc(u6, .{ |
| 85 | .xor_output = 0x00, | 193 | .xor_output = 0x00, |
| 86 | }); | 194 | }); |
| 87 | 195 | ||
| 88 | pub const Crc6Darc = Crc(u6, .{ | 196 | pub const Crc6Darc = Generic(u6, .{ |
| 89 | .polynomial = 0x19, | 197 | .polynomial = 0x19, |
| 90 | .initial = 0x00, | 198 | .initial = 0x00, |
| 91 | .reflect_input = true, | 199 | .reflect_input = true, |
| ... | @@ -93,7 +201,7 @@ pub const Crc6Darc = Crc(u6, .{ | ... | @@ -93,7 +201,7 @@ pub const Crc6Darc = Crc(u6, .{ |
| 93 | .xor_output = 0x00, | 201 | .xor_output = 0x00, |
| 94 | }); | 202 | }); |
| 95 | 203 | ||
| 96 | pub const Crc6G704 = Crc(u6, .{ | 204 | pub const Crc6G704 = Generic(u6, .{ |
| 97 | .polynomial = 0x03, | 205 | .polynomial = 0x03, |
| 98 | .initial = 0x00, | 206 | .initial = 0x00, |
| 99 | .reflect_input = true, | 207 | .reflect_input = true, |
| ... | @@ -101,7 +209,7 @@ pub const Crc6G704 = Crc(u6, .{ | ... | @@ -101,7 +209,7 @@ pub const Crc6G704 = Crc(u6, .{ |
| 101 | .xor_output = 0x00, | 209 | .xor_output = 0x00, |
| 102 | }); | 210 | }); |
| 103 | 211 | ||
| 104 | pub const Crc6Gsm = Crc(u6, .{ | 212 | pub const Crc6Gsm = Generic(u6, .{ |
| 105 | .polynomial = 0x2f, | 213 | .polynomial = 0x2f, |
| 106 | .initial = 0x00, | 214 | .initial = 0x00, |
| 107 | .reflect_input = false, | 215 | .reflect_input = false, |
| ... | @@ -109,7 +217,7 @@ pub const Crc6Gsm = Crc(u6, .{ | ... | @@ -109,7 +217,7 @@ pub const Crc6Gsm = Crc(u6, .{ |
| 109 | .xor_output = 0x3f, | 217 | .xor_output = 0x3f, |
| 110 | }); | 218 | }); |
| 111 | 219 | ||
| 112 | pub const Crc7Mmc = Crc(u7, .{ | 220 | pub const Crc7Mmc = Generic(u7, .{ |
| 113 | .polynomial = 0x09, | 221 | .polynomial = 0x09, |
| 114 | .initial = 0x00, | 222 | .initial = 0x00, |
| 115 | .reflect_input = false, | 223 | .reflect_input = false, |
| ... | @@ -117,7 +225,7 @@ pub const Crc7Mmc = Crc(u7, .{ | ... | @@ -117,7 +225,7 @@ pub const Crc7Mmc = Crc(u7, .{ |
| 117 | .xor_output = 0x00, | 225 | .xor_output = 0x00, |
| 118 | }); | 226 | }); |
| 119 | 227 | ||
| 120 | pub const Crc7Rohc = Crc(u7, .{ | 228 | pub const Crc7Rohc = Generic(u7, .{ |
| 121 | .polynomial = 0x4f, | 229 | .polynomial = 0x4f, |
| 122 | .initial = 0x7f, | 230 | .initial = 0x7f, |
| 123 | .reflect_input = true, | 231 | .reflect_input = true, |
| ... | @@ -125,7 +233,7 @@ pub const Crc7Rohc = Crc(u7, .{ | ... | @@ -125,7 +233,7 @@ pub const Crc7Rohc = Crc(u7, .{ |
| 125 | .xor_output = 0x00, | 233 | .xor_output = 0x00, |
| 126 | }); | 234 | }); |
| 127 | 235 | ||
| 128 | pub const Crc7Umts = Crc(u7, .{ | 236 | pub const Crc7Umts = Generic(u7, .{ |
| 129 | .polynomial = 0x45, | 237 | .polynomial = 0x45, |
| 130 | .initial = 0x00, | 238 | .initial = 0x00, |
| 131 | .reflect_input = false, | 239 | .reflect_input = false, |
| ... | @@ -133,7 +241,7 @@ pub const Crc7Umts = Crc(u7, .{ | ... | @@ -133,7 +241,7 @@ pub const Crc7Umts = Crc(u7, .{ |
| 133 | .xor_output = 0x00, | 241 | .xor_output = 0x00, |
| 134 | }); | 242 | }); |
| 135 | 243 | ||
| 136 | pub const Crc8Autosar = Crc(u8, .{ | 244 | pub const Crc8Autosar = Generic(u8, .{ |
| 137 | .polynomial = 0x2f, | 245 | .polynomial = 0x2f, |
| 138 | .initial = 0xff, | 246 | .initial = 0xff, |
| 139 | .reflect_input = false, | 247 | .reflect_input = false, |
| ... | @@ -141,7 +249,7 @@ pub const Crc8Autosar = Crc(u8, .{ | ... | @@ -141,7 +249,7 @@ pub const Crc8Autosar = Crc(u8, .{ |
| 141 | .xor_output = 0xff, | 249 | .xor_output = 0xff, |
| 142 | }); | 250 | }); |
| 143 | 251 | ||
| 144 | pub const Crc8Bluetooth = Crc(u8, .{ | 252 | pub const Crc8Bluetooth = Generic(u8, .{ |
| 145 | .polynomial = 0xa7, | 253 | .polynomial = 0xa7, |
| 146 | .initial = 0x00, | 254 | .initial = 0x00, |
| 147 | .reflect_input = true, | 255 | .reflect_input = true, |
| ... | @@ -149,7 +257,7 @@ pub const Crc8Bluetooth = Crc(u8, .{ | ... | @@ -149,7 +257,7 @@ pub const Crc8Bluetooth = Crc(u8, .{ |
| 149 | .xor_output = 0x00, | 257 | .xor_output = 0x00, |
| 150 | }); | 258 | }); |
| 151 | 259 | ||
| 152 | pub const Crc8Cdma2000 = Crc(u8, .{ | 260 | pub const Crc8Cdma2000 = Generic(u8, .{ |
| 153 | .polynomial = 0x9b, | 261 | .polynomial = 0x9b, |
| 154 | .initial = 0xff, | 262 | .initial = 0xff, |
| 155 | .reflect_input = false, | 263 | .reflect_input = false, |
| ... | @@ -157,7 +265,7 @@ pub const Crc8Cdma2000 = Crc(u8, .{ | ... | @@ -157,7 +265,7 @@ pub const Crc8Cdma2000 = Crc(u8, .{ |
| 157 | .xor_output = 0x00, | 265 | .xor_output = 0x00, |
| 158 | }); | 266 | }); |
| 159 | 267 | ||
| 160 | pub const Crc8Darc = Crc(u8, .{ | 268 | pub const Crc8Darc = Generic(u8, .{ |
| 161 | .polynomial = 0x39, | 269 | .polynomial = 0x39, |
| 162 | .initial = 0x00, | 270 | .initial = 0x00, |
| 163 | .reflect_input = true, | 271 | .reflect_input = true, |
| ... | @@ -165,7 +273,7 @@ pub const Crc8Darc = Crc(u8, .{ | ... | @@ -165,7 +273,7 @@ pub const Crc8Darc = Crc(u8, .{ |
| 165 | .xor_output = 0x00, | 273 | .xor_output = 0x00, |
| 166 | }); | 274 | }); |
| 167 | 275 | ||
| 168 | pub const Crc8DvbS2 = Crc(u8, .{ | 276 | pub const Crc8DvbS2 = Generic(u8, .{ |
| 169 | .polynomial = 0xd5, | 277 | .polynomial = 0xd5, |
| 170 | .initial = 0x00, | 278 | .initial = 0x00, |
| 171 | .reflect_input = false, | 279 | .reflect_input = false, |
| ... | @@ -173,7 +281,7 @@ pub const Crc8DvbS2 = Crc(u8, .{ | ... | @@ -173,7 +281,7 @@ pub const Crc8DvbS2 = Crc(u8, .{ |
| 173 | .xor_output = 0x00, | 281 | .xor_output = 0x00, |
| 174 | }); | 282 | }); |
| 175 | 283 | ||
| 176 | pub const Crc8GsmA = Crc(u8, .{ | 284 | pub const Crc8GsmA = Generic(u8, .{ |
| 177 | .polynomial = 0x1d, | 285 | .polynomial = 0x1d, |
| 178 | .initial = 0x00, | 286 | .initial = 0x00, |
| 179 | .reflect_input = false, | 287 | .reflect_input = false, |
| ... | @@ -181,7 +289,7 @@ pub const Crc8GsmA = Crc(u8, .{ | ... | @@ -181,7 +289,7 @@ pub const Crc8GsmA = Crc(u8, .{ |
| 181 | .xor_output = 0x00, | 289 | .xor_output = 0x00, |
| 182 | }); | 290 | }); |
| 183 | 291 | ||
| 184 | pub const Crc8GsmB = Crc(u8, .{ | 292 | pub const Crc8GsmB = Generic(u8, .{ |
| 185 | .polynomial = 0x49, | 293 | .polynomial = 0x49, |
| 186 | .initial = 0x00, | 294 | .initial = 0x00, |
| 187 | .reflect_input = false, | 295 | .reflect_input = false, |
| ... | @@ -189,7 +297,7 @@ pub const Crc8GsmB = Crc(u8, .{ | ... | @@ -189,7 +297,7 @@ pub const Crc8GsmB = Crc(u8, .{ |
| 189 | .xor_output = 0xff, | 297 | .xor_output = 0xff, |
| 190 | }); | 298 | }); |
| 191 | 299 | ||
| 192 | pub const Crc8Hitag = Crc(u8, .{ | 300 | pub const Crc8Hitag = Generic(u8, .{ |
| 193 | .polynomial = 0x1d, | 301 | .polynomial = 0x1d, |
| 194 | .initial = 0xff, | 302 | .initial = 0xff, |
| 195 | .reflect_input = false, | 303 | .reflect_input = false, |
| ... | @@ -197,7 +305,7 @@ pub const Crc8Hitag = Crc(u8, .{ | ... | @@ -197,7 +305,7 @@ pub const Crc8Hitag = Crc(u8, .{ |
| 197 | .xor_output = 0x00, | 305 | .xor_output = 0x00, |
| 198 | }); | 306 | }); |
| 199 | 307 | ||
| 200 | pub const Crc8I4321 = Crc(u8, .{ | 308 | pub const Crc8I4321 = Generic(u8, .{ |
| 201 | .polynomial = 0x07, | 309 | .polynomial = 0x07, |
| 202 | .initial = 0x00, | 310 | .initial = 0x00, |
| 203 | .reflect_input = false, | 311 | .reflect_input = false, |
| ... | @@ -205,7 +313,7 @@ pub const Crc8I4321 = Crc(u8, .{ | ... | @@ -205,7 +313,7 @@ pub const Crc8I4321 = Crc(u8, .{ |
| 205 | .xor_output = 0x55, | 313 | .xor_output = 0x55, |
| 206 | }); | 314 | }); |
| 207 | 315 | ||
| 208 | pub const Crc8ICode = Crc(u8, .{ | 316 | pub const Crc8ICode = Generic(u8, .{ |
| 209 | .polynomial = 0x1d, | 317 | .polynomial = 0x1d, |
| 210 | .initial = 0xfd, | 318 | .initial = 0xfd, |
| 211 | .reflect_input = false, | 319 | .reflect_input = false, |
| ... | @@ -213,7 +321,7 @@ pub const Crc8ICode = Crc(u8, .{ | ... | @@ -213,7 +321,7 @@ pub const Crc8ICode = Crc(u8, .{ |
| 213 | .xor_output = 0x00, | 321 | .xor_output = 0x00, |
| 214 | }); | 322 | }); |
| 215 | 323 | ||
| 216 | pub const Crc8Lte = Crc(u8, .{ | 324 | pub const Crc8Lte = Generic(u8, .{ |
| 217 | .polynomial = 0x9b, | 325 | .polynomial = 0x9b, |
| 218 | .initial = 0x00, | 326 | .initial = 0x00, |
| 219 | .reflect_input = false, | 327 | .reflect_input = false, |
| ... | @@ -221,7 +329,7 @@ pub const Crc8Lte = Crc(u8, .{ | ... | @@ -221,7 +329,7 @@ pub const Crc8Lte = Crc(u8, .{ |
| 221 | .xor_output = 0x00, | 329 | .xor_output = 0x00, |
| 222 | }); | 330 | }); |
| 223 | 331 | ||
| 224 | pub const Crc8MaximDow = Crc(u8, .{ | 332 | pub const Crc8MaximDow = Generic(u8, .{ |
| 225 | .polynomial = 0x31, | 333 | .polynomial = 0x31, |
| 226 | .initial = 0x00, | 334 | .initial = 0x00, |
| 227 | .reflect_input = true, | 335 | .reflect_input = true, |
| ... | @@ -229,7 +337,7 @@ pub const Crc8MaximDow = Crc(u8, .{ | ... | @@ -229,7 +337,7 @@ pub const Crc8MaximDow = Crc(u8, .{ |
| 229 | .xor_output = 0x00, | 337 | .xor_output = 0x00, |
| 230 | }); | 338 | }); |
| 231 | 339 | ||
| 232 | pub const Crc8MifareMad = Crc(u8, .{ | 340 | pub const Crc8MifareMad = Generic(u8, .{ |
| 233 | .polynomial = 0x1d, | 341 | .polynomial = 0x1d, |
| 234 | .initial = 0xc7, | 342 | .initial = 0xc7, |
| 235 | .reflect_input = false, | 343 | .reflect_input = false, |
| ... | @@ -237,7 +345,7 @@ pub const Crc8MifareMad = Crc(u8, .{ | ... | @@ -237,7 +345,7 @@ pub const Crc8MifareMad = Crc(u8, .{ |
| 237 | .xor_output = 0x00, | 345 | .xor_output = 0x00, |
| 238 | }); | 346 | }); |
| 239 | 347 | ||
| 240 | pub const Crc8Nrsc5 = Crc(u8, .{ | 348 | pub const Crc8Nrsc5 = Generic(u8, .{ |
| 241 | .polynomial = 0x31, | 349 | .polynomial = 0x31, |
| 242 | .initial = 0xff, | 350 | .initial = 0xff, |
| 243 | .reflect_input = false, | 351 | .reflect_input = false, |
| ... | @@ -245,7 +353,7 @@ pub const Crc8Nrsc5 = Crc(u8, .{ | ... | @@ -245,7 +353,7 @@ pub const Crc8Nrsc5 = Crc(u8, .{ |
| 245 | .xor_output = 0x00, | 353 | .xor_output = 0x00, |
| 246 | }); | 354 | }); |
| 247 | 355 | ||
| 248 | pub const Crc8Opensafety = Crc(u8, .{ | 356 | pub const Crc8Opensafety = Generic(u8, .{ |
| 249 | .polynomial = 0x2f, | 357 | .polynomial = 0x2f, |
| 250 | .initial = 0x00, | 358 | .initial = 0x00, |
| 251 | .reflect_input = false, | 359 | .reflect_input = false, |
| ... | @@ -253,7 +361,7 @@ pub const Crc8Opensafety = Crc(u8, .{ | ... | @@ -253,7 +361,7 @@ pub const Crc8Opensafety = Crc(u8, .{ |
| 253 | .xor_output = 0x00, | 361 | .xor_output = 0x00, |
| 254 | }); | 362 | }); |
| 255 | 363 | ||
| 256 | pub const Crc8Rohc = Crc(u8, .{ | 364 | pub const Crc8Rohc = Generic(u8, .{ |
| 257 | .polynomial = 0x07, | 365 | .polynomial = 0x07, |
| 258 | .initial = 0xff, | 366 | .initial = 0xff, |
| 259 | .reflect_input = true, | 367 | .reflect_input = true, |
| ... | @@ -261,7 +369,7 @@ pub const Crc8Rohc = Crc(u8, .{ | ... | @@ -261,7 +369,7 @@ pub const Crc8Rohc = Crc(u8, .{ |
| 261 | .xor_output = 0x00, | 369 | .xor_output = 0x00, |
| 262 | }); | 370 | }); |
| 263 | 371 | ||
| 264 | pub const Crc8SaeJ1850 = Crc(u8, .{ | 372 | pub const Crc8SaeJ1850 = Generic(u8, .{ |
| 265 | .polynomial = 0x1d, | 373 | .polynomial = 0x1d, |
| 266 | .initial = 0xff, | 374 | .initial = 0xff, |
| 267 | .reflect_input = false, | 375 | .reflect_input = false, |
| ... | @@ -269,7 +377,7 @@ pub const Crc8SaeJ1850 = Crc(u8, .{ | ... | @@ -269,7 +377,7 @@ pub const Crc8SaeJ1850 = Crc(u8, .{ |
| 269 | .xor_output = 0xff, | 377 | .xor_output = 0xff, |
| 270 | }); | 378 | }); |
| 271 | 379 | ||
| 272 | pub const Crc8Smbus = Crc(u8, .{ | 380 | pub const Crc8Smbus = Generic(u8, .{ |
| 273 | .polynomial = 0x07, | 381 | .polynomial = 0x07, |
| 274 | .initial = 0x00, | 382 | .initial = 0x00, |
| 275 | .reflect_input = false, | 383 | .reflect_input = false, |
| ... | @@ -277,7 +385,7 @@ pub const Crc8Smbus = Crc(u8, .{ | ... | @@ -277,7 +385,7 @@ pub const Crc8Smbus = Crc(u8, .{ |
| 277 | .xor_output = 0x00, | 385 | .xor_output = 0x00, |
| 278 | }); | 386 | }); |
| 279 | 387 | ||
| 280 | pub const Crc8Tech3250 = Crc(u8, .{ | 388 | pub const Crc8Tech3250 = Generic(u8, .{ |
| 281 | .polynomial = 0x1d, | 389 | .polynomial = 0x1d, |
| 282 | .initial = 0xff, | 390 | .initial = 0xff, |
| 283 | .reflect_input = true, | 391 | .reflect_input = true, |
| ... | @@ -285,7 +393,7 @@ pub const Crc8Tech3250 = Crc(u8, .{ | ... | @@ -285,7 +393,7 @@ pub const Crc8Tech3250 = Crc(u8, .{ |
| 285 | .xor_output = 0x00, | 393 | .xor_output = 0x00, |
| 286 | }); | 394 | }); |
| 287 | 395 | ||
| 288 | pub const Crc8Wcdma = Crc(u8, .{ | 396 | pub const Crc8Wcdma = Generic(u8, .{ |
| 289 | .polynomial = 0x9b, | 397 | .polynomial = 0x9b, |
| 290 | .initial = 0x00, | 398 | .initial = 0x00, |
| 291 | .reflect_input = true, | 399 | .reflect_input = true, |
| ... | @@ -293,7 +401,7 @@ pub const Crc8Wcdma = Crc(u8, .{ | ... | @@ -293,7 +401,7 @@ pub const Crc8Wcdma = Crc(u8, .{ |
| 293 | .xor_output = 0x00, | 401 | .xor_output = 0x00, |
| 294 | }); | 402 | }); |
| 295 | 403 | ||
| 296 | pub const Crc10Atm = Crc(u10, .{ | 404 | pub const Crc10Atm = Generic(u10, .{ |
| 297 | .polynomial = 0x233, | 405 | .polynomial = 0x233, |
| 298 | .initial = 0x000, | 406 | .initial = 0x000, |
| 299 | .reflect_input = false, | 407 | .reflect_input = false, |
| ... | @@ -301,7 +409,7 @@ pub const Crc10Atm = Crc(u10, .{ | ... | @@ -301,7 +409,7 @@ pub const Crc10Atm = Crc(u10, .{ |
| 301 | .xor_output = 0x000, | 409 | .xor_output = 0x000, |
| 302 | }); | 410 | }); |
| 303 | 411 | ||
| 304 | pub const Crc10Cdma2000 = Crc(u10, .{ | 412 | pub const Crc10Cdma2000 = Generic(u10, .{ |
| 305 | .polynomial = 0x3d9, | 413 | .polynomial = 0x3d9, |
| 306 | .initial = 0x3ff, | 414 | .initial = 0x3ff, |
| 307 | .reflect_input = false, | 415 | .reflect_input = false, |
| ... | @@ -309,7 +417,7 @@ pub const Crc10Cdma2000 = Crc(u10, .{ | ... | @@ -309,7 +417,7 @@ pub const Crc10Cdma2000 = Crc(u10, .{ |
| 309 | .xor_output = 0x000, | 417 | .xor_output = 0x000, |
| 310 | }); | 418 | }); |
| 311 | 419 | ||
| 312 | pub const Crc10Gsm = Crc(u10, .{ | 420 | pub const Crc10Gsm = Generic(u10, .{ |
| 313 | .polynomial = 0x175, | 421 | .polynomial = 0x175, |
| 314 | .initial = 0x000, | 422 | .initial = 0x000, |
| 315 | .reflect_input = false, | 423 | .reflect_input = false, |
| ... | @@ -317,7 +425,7 @@ pub const Crc10Gsm = Crc(u10, .{ | ... | @@ -317,7 +425,7 @@ pub const Crc10Gsm = Crc(u10, .{ |
| 317 | .xor_output = 0x3ff, | 425 | .xor_output = 0x3ff, |
| 318 | }); | 426 | }); |
| 319 | 427 | ||
| 320 | pub const Crc11Flexray = Crc(u11, .{ | 428 | pub const Crc11Flexray = Generic(u11, .{ |
| 321 | .polynomial = 0x385, | 429 | .polynomial = 0x385, |
| 322 | .initial = 0x01a, | 430 | .initial = 0x01a, |
| 323 | .reflect_input = false, | 431 | .reflect_input = false, |
| ... | @@ -325,7 +433,7 @@ pub const Crc11Flexray = Crc(u11, .{ | ... | @@ -325,7 +433,7 @@ pub const Crc11Flexray = Crc(u11, .{ |
| 325 | .xor_output = 0x000, | 433 | .xor_output = 0x000, |
| 326 | }); | 434 | }); |
| 327 | 435 | ||
| 328 | pub const Crc11Umts = Crc(u11, .{ | 436 | pub const Crc11Umts = Generic(u11, .{ |
| 329 | .polynomial = 0x307, | 437 | .polynomial = 0x307, |
| 330 | .initial = 0x000, | 438 | .initial = 0x000, |
| 331 | .reflect_input = false, | 439 | .reflect_input = false, |
| ... | @@ -333,7 +441,7 @@ pub const Crc11Umts = Crc(u11, .{ | ... | @@ -333,7 +441,7 @@ pub const Crc11Umts = Crc(u11, .{ |
| 333 | .xor_output = 0x000, | 441 | .xor_output = 0x000, |
| 334 | }); | 442 | }); |
| 335 | 443 | ||
| 336 | pub const Crc12Cdma2000 = Crc(u12, .{ | 444 | pub const Crc12Cdma2000 = Generic(u12, .{ |
| 337 | .polynomial = 0xf13, | 445 | .polynomial = 0xf13, |
| 338 | .initial = 0xfff, | 446 | .initial = 0xfff, |
| 339 | .reflect_input = false, | 447 | .reflect_input = false, |
| ... | @@ -341,7 +449,7 @@ pub const Crc12Cdma2000 = Crc(u12, .{ | ... | @@ -341,7 +449,7 @@ pub const Crc12Cdma2000 = Crc(u12, .{ |
| 341 | .xor_output = 0x000, | 449 | .xor_output = 0x000, |
| 342 | }); | 450 | }); |
| 343 | 451 | ||
| 344 | pub const Crc12Dect = Crc(u12, .{ | 452 | pub const Crc12Dect = Generic(u12, .{ |
| 345 | .polynomial = 0x80f, | 453 | .polynomial = 0x80f, |
| 346 | .initial = 0x000, | 454 | .initial = 0x000, |
| 347 | .reflect_input = false, | 455 | .reflect_input = false, |
| ... | @@ -349,7 +457,7 @@ pub const Crc12Dect = Crc(u12, .{ | ... | @@ -349,7 +457,7 @@ pub const Crc12Dect = Crc(u12, .{ |
| 349 | .xor_output = 0x000, | 457 | .xor_output = 0x000, |
| 350 | }); | 458 | }); |
| 351 | 459 | ||
| 352 | pub const Crc12Gsm = Crc(u12, .{ | 460 | pub const Crc12Gsm = Generic(u12, .{ |
| 353 | .polynomial = 0xd31, | 461 | .polynomial = 0xd31, |
| 354 | .initial = 0x000, | 462 | .initial = 0x000, |
| 355 | .reflect_input = false, | 463 | .reflect_input = false, |
| ... | @@ -357,7 +465,7 @@ pub const Crc12Gsm = Crc(u12, .{ | ... | @@ -357,7 +465,7 @@ pub const Crc12Gsm = Crc(u12, .{ |
| 357 | .xor_output = 0xfff, | 465 | .xor_output = 0xfff, |
| 358 | }); | 466 | }); |
| 359 | 467 | ||
| 360 | pub const Crc12Umts = Crc(u12, .{ | 468 | pub const Crc12Umts = Generic(u12, .{ |
| 361 | .polynomial = 0x80f, | 469 | .polynomial = 0x80f, |
| 362 | .initial = 0x000, | 470 | .initial = 0x000, |
| 363 | .reflect_input = false, | 471 | .reflect_input = false, |
| ... | @@ -365,7 +473,7 @@ pub const Crc12Umts = Crc(u12, .{ | ... | @@ -365,7 +473,7 @@ pub const Crc12Umts = Crc(u12, .{ |
| 365 | .xor_output = 0x000, | 473 | .xor_output = 0x000, |
| 366 | }); | 474 | }); |
| 367 | 475 | ||
| 368 | pub const Crc13Bbc = Crc(u13, .{ | 476 | pub const Crc13Bbc = Generic(u13, .{ |
| 369 | .polynomial = 0x1cf5, | 477 | .polynomial = 0x1cf5, |
| 370 | .initial = 0x0000, | 478 | .initial = 0x0000, |
| 371 | .reflect_input = false, | 479 | .reflect_input = false, |
| ... | @@ -373,7 +481,7 @@ pub const Crc13Bbc = Crc(u13, .{ | ... | @@ -373,7 +481,7 @@ pub const Crc13Bbc = Crc(u13, .{ |
| 373 | .xor_output = 0x0000, | 481 | .xor_output = 0x0000, |
| 374 | }); | 482 | }); |
| 375 | 483 | ||
| 376 | pub const Crc14Darc = Crc(u14, .{ | 484 | pub const Crc14Darc = Generic(u14, .{ |
| 377 | .polynomial = 0x0805, | 485 | .polynomial = 0x0805, |
| 378 | .initial = 0x0000, | 486 | .initial = 0x0000, |
| 379 | .reflect_input = true, | 487 | .reflect_input = true, |
| ... | @@ -381,7 +489,7 @@ pub const Crc14Darc = Crc(u14, .{ | ... | @@ -381,7 +489,7 @@ pub const Crc14Darc = Crc(u14, .{ |
| 381 | .xor_output = 0x0000, | 489 | .xor_output = 0x0000, |
| 382 | }); | 490 | }); |
| 383 | 491 | ||
| 384 | pub const Crc14Gsm = Crc(u14, .{ | 492 | pub const Crc14Gsm = Generic(u14, .{ |
| 385 | .polynomial = 0x202d, | 493 | .polynomial = 0x202d, |
| 386 | .initial = 0x0000, | 494 | .initial = 0x0000, |
| 387 | .reflect_input = false, | 495 | .reflect_input = false, |
| ... | @@ -389,7 +497,7 @@ pub const Crc14Gsm = Crc(u14, .{ | ... | @@ -389,7 +497,7 @@ pub const Crc14Gsm = Crc(u14, .{ |
| 389 | .xor_output = 0x3fff, | 497 | .xor_output = 0x3fff, |
| 390 | }); | 498 | }); |
| 391 | 499 | ||
| 392 | pub const Crc15Can = Crc(u15, .{ | 500 | pub const Crc15Can = Generic(u15, .{ |
| 393 | .polynomial = 0x4599, | 501 | .polynomial = 0x4599, |
| 394 | .initial = 0x0000, | 502 | .initial = 0x0000, |
| 395 | .reflect_input = false, | 503 | .reflect_input = false, |
| ... | @@ -397,7 +505,7 @@ pub const Crc15Can = Crc(u15, .{ | ... | @@ -397,7 +505,7 @@ pub const Crc15Can = Crc(u15, .{ |
| 397 | .xor_output = 0x0000, | 505 | .xor_output = 0x0000, |
| 398 | }); | 506 | }); |
| 399 | 507 | ||
| 400 | pub const Crc15Mpt1327 = Crc(u15, .{ | 508 | pub const Crc15Mpt1327 = Generic(u15, .{ |
| 401 | .polynomial = 0x6815, | 509 | .polynomial = 0x6815, |
| 402 | .initial = 0x0000, | 510 | .initial = 0x0000, |
| 403 | .reflect_input = false, | 511 | .reflect_input = false, |
| ... | @@ -405,7 +513,7 @@ pub const Crc15Mpt1327 = Crc(u15, .{ | ... | @@ -405,7 +513,7 @@ pub const Crc15Mpt1327 = Crc(u15, .{ |
| 405 | .xor_output = 0x0001, | 513 | .xor_output = 0x0001, |
| 406 | }); | 514 | }); |
| 407 | 515 | ||
| 408 | pub const Crc16Arc = Crc(u16, .{ | 516 | pub const Crc16Arc = Generic(u16, .{ |
| 409 | .polynomial = 0x8005, | 517 | .polynomial = 0x8005, |
| 410 | .initial = 0x0000, | 518 | .initial = 0x0000, |
| 411 | .reflect_input = true, | 519 | .reflect_input = true, |
| ... | @@ -413,7 +521,7 @@ pub const Crc16Arc = Crc(u16, .{ | ... | @@ -413,7 +521,7 @@ pub const Crc16Arc = Crc(u16, .{ |
| 413 | .xor_output = 0x0000, | 521 | .xor_output = 0x0000, |
| 414 | }); | 522 | }); |
| 415 | 523 | ||
| 416 | pub const Crc16Cdma2000 = Crc(u16, .{ | 524 | pub const Crc16Cdma2000 = Generic(u16, .{ |
| 417 | .polynomial = 0xc867, | 525 | .polynomial = 0xc867, |
| 418 | .initial = 0xffff, | 526 | .initial = 0xffff, |
| 419 | .reflect_input = false, | 527 | .reflect_input = false, |
| ... | @@ -421,7 +529,7 @@ pub const Crc16Cdma2000 = Crc(u16, .{ | ... | @@ -421,7 +529,7 @@ pub const Crc16Cdma2000 = Crc(u16, .{ |
| 421 | .xor_output = 0x0000, | 529 | .xor_output = 0x0000, |
| 422 | }); | 530 | }); |
| 423 | 531 | ||
| 424 | pub const Crc16Cms = Crc(u16, .{ | 532 | pub const Crc16Cms = Generic(u16, .{ |
| 425 | .polynomial = 0x8005, | 533 | .polynomial = 0x8005, |
| 426 | .initial = 0xffff, | 534 | .initial = 0xffff, |
| 427 | .reflect_input = false, | 535 | .reflect_input = false, |
| ... | @@ -429,7 +537,7 @@ pub const Crc16Cms = Crc(u16, .{ | ... | @@ -429,7 +537,7 @@ pub const Crc16Cms = Crc(u16, .{ |
| 429 | .xor_output = 0x0000, | 537 | .xor_output = 0x0000, |
| 430 | }); | 538 | }); |
| 431 | 539 | ||
| 432 | pub const Crc16Dds110 = Crc(u16, .{ | 540 | pub const Crc16Dds110 = Generic(u16, .{ |
| 433 | .polynomial = 0x8005, | 541 | .polynomial = 0x8005, |
| 434 | .initial = 0x800d, | 542 | .initial = 0x800d, |
| 435 | .reflect_input = false, | 543 | .reflect_input = false, |
| ... | @@ -437,7 +545,7 @@ pub const Crc16Dds110 = Crc(u16, .{ | ... | @@ -437,7 +545,7 @@ pub const Crc16Dds110 = Crc(u16, .{ |
| 437 | .xor_output = 0x0000, | 545 | .xor_output = 0x0000, |
| 438 | }); | 546 | }); |
| 439 | 547 | ||
| 440 | pub const Crc16DectR = Crc(u16, .{ | 548 | pub const Crc16DectR = Generic(u16, .{ |
| 441 | .polynomial = 0x0589, | 549 | .polynomial = 0x0589, |
| 442 | .initial = 0x0000, | 550 | .initial = 0x0000, |
| 443 | .reflect_input = false, | 551 | .reflect_input = false, |
| ... | @@ -445,7 +553,7 @@ pub const Crc16DectR = Crc(u16, .{ | ... | @@ -445,7 +553,7 @@ pub const Crc16DectR = Crc(u16, .{ |
| 445 | .xor_output = 0x0001, | 553 | .xor_output = 0x0001, |
| 446 | }); | 554 | }); |
| 447 | 555 | ||
| 448 | pub const Crc16DectX = Crc(u16, .{ | 556 | pub const Crc16DectX = Generic(u16, .{ |
| 449 | .polynomial = 0x0589, | 557 | .polynomial = 0x0589, |
| 450 | .initial = 0x0000, | 558 | .initial = 0x0000, |
| 451 | .reflect_input = false, | 559 | .reflect_input = false, |
| ... | @@ -453,7 +561,7 @@ pub const Crc16DectX = Crc(u16, .{ | ... | @@ -453,7 +561,7 @@ pub const Crc16DectX = Crc(u16, .{ |
| 453 | .xor_output = 0x0000, | 561 | .xor_output = 0x0000, |
| 454 | }); | 562 | }); |
| 455 | 563 | ||
| 456 | pub const Crc16Dnp = Crc(u16, .{ | 564 | pub const Crc16Dnp = Generic(u16, .{ |
| 457 | .polynomial = 0x3d65, | 565 | .polynomial = 0x3d65, |
| 458 | .initial = 0x0000, | 566 | .initial = 0x0000, |
| 459 | .reflect_input = true, | 567 | .reflect_input = true, |
| ... | @@ -461,7 +569,7 @@ pub const Crc16Dnp = Crc(u16, .{ | ... | @@ -461,7 +569,7 @@ pub const Crc16Dnp = Crc(u16, .{ |
| 461 | .xor_output = 0xffff, | 569 | .xor_output = 0xffff, |
| 462 | }); | 570 | }); |
| 463 | 571 | ||
| 464 | pub const Crc16En13757 = Crc(u16, .{ | 572 | pub const Crc16En13757 = Generic(u16, .{ |
| 465 | .polynomial = 0x3d65, | 573 | .polynomial = 0x3d65, |
| 466 | .initial = 0x0000, | 574 | .initial = 0x0000, |
| 467 | .reflect_input = false, | 575 | .reflect_input = false, |
| ... | @@ -469,7 +577,7 @@ pub const Crc16En13757 = Crc(u16, .{ | ... | @@ -469,7 +577,7 @@ pub const Crc16En13757 = Crc(u16, .{ |
| 469 | .xor_output = 0xffff, | 577 | .xor_output = 0xffff, |
| 470 | }); | 578 | }); |
| 471 | 579 | ||
| 472 | pub const Crc16Genibus = Crc(u16, .{ | 580 | pub const Crc16Genibus = Generic(u16, .{ |
| 473 | .polynomial = 0x1021, | 581 | .polynomial = 0x1021, |
| 474 | .initial = 0xffff, | 582 | .initial = 0xffff, |
| 475 | .reflect_input = false, | 583 | .reflect_input = false, |
| ... | @@ -477,7 +585,7 @@ pub const Crc16Genibus = Crc(u16, .{ | ... | @@ -477,7 +585,7 @@ pub const Crc16Genibus = Crc(u16, .{ |
| 477 | .xor_output = 0xffff, | 585 | .xor_output = 0xffff, |
| 478 | }); | 586 | }); |
| 479 | 587 | ||
| 480 | pub const Crc16Gsm = Crc(u16, .{ | 588 | pub const Crc16Gsm = Generic(u16, .{ |
| 481 | .polynomial = 0x1021, | 589 | .polynomial = 0x1021, |
| 482 | .initial = 0x0000, | 590 | .initial = 0x0000, |
| 483 | .reflect_input = false, | 591 | .reflect_input = false, |
| ... | @@ -485,7 +593,7 @@ pub const Crc16Gsm = Crc(u16, .{ | ... | @@ -485,7 +593,7 @@ pub const Crc16Gsm = Crc(u16, .{ |
| 485 | .xor_output = 0xffff, | 593 | .xor_output = 0xffff, |
| 486 | }); | 594 | }); |
| 487 | 595 | ||
| 488 | pub const Crc16Ibm3740 = Crc(u16, .{ | 596 | pub const Crc16Ibm3740 = Generic(u16, .{ |
| 489 | .polynomial = 0x1021, | 597 | .polynomial = 0x1021, |
| 490 | .initial = 0xffff, | 598 | .initial = 0xffff, |
| 491 | .reflect_input = false, | 599 | .reflect_input = false, |
| ... | @@ -493,7 +601,7 @@ pub const Crc16Ibm3740 = Crc(u16, .{ | ... | @@ -493,7 +601,7 @@ pub const Crc16Ibm3740 = Crc(u16, .{ |
| 493 | .xor_output = 0x0000, | 601 | .xor_output = 0x0000, |
| 494 | }); | 602 | }); |
| 495 | 603 | ||
| 496 | pub const Crc16IbmSdlc = Crc(u16, .{ | 604 | pub const Crc16IbmSdlc = Generic(u16, .{ |
| 497 | .polynomial = 0x1021, | 605 | .polynomial = 0x1021, |
| 498 | .initial = 0xffff, | 606 | .initial = 0xffff, |
| 499 | .reflect_input = true, | 607 | .reflect_input = true, |
| ... | @@ -501,7 +609,7 @@ pub const Crc16IbmSdlc = Crc(u16, .{ | ... | @@ -501,7 +609,7 @@ pub const Crc16IbmSdlc = Crc(u16, .{ |
| 501 | .xor_output = 0xffff, | 609 | .xor_output = 0xffff, |
| 502 | }); | 610 | }); |
| 503 | 611 | ||
| 504 | pub const Crc16IsoIec144433A = Crc(u16, .{ | 612 | pub const Crc16IsoIec144433A = Generic(u16, .{ |
| 505 | .polynomial = 0x1021, | 613 | .polynomial = 0x1021, |
| 506 | .initial = 0xc6c6, | 614 | .initial = 0xc6c6, |
| 507 | .reflect_input = true, | 615 | .reflect_input = true, |
| ... | @@ -509,7 +617,7 @@ pub const Crc16IsoIec144433A = Crc(u16, .{ | ... | @@ -509,7 +617,7 @@ pub const Crc16IsoIec144433A = Crc(u16, .{ |
| 509 | .xor_output = 0x0000, | 617 | .xor_output = 0x0000, |
| 510 | }); | 618 | }); |
| 511 | 619 | ||
| 512 | pub const Crc16Kermit = Crc(u16, .{ | 620 | pub const Crc16Kermit = Generic(u16, .{ |
| 513 | .polynomial = 0x1021, | 621 | .polynomial = 0x1021, |
| 514 | .initial = 0x0000, | 622 | .initial = 0x0000, |
| 515 | .reflect_input = true, | 623 | .reflect_input = true, |
| ... | @@ -517,7 +625,7 @@ pub const Crc16Kermit = Crc(u16, .{ | ... | @@ -517,7 +625,7 @@ pub const Crc16Kermit = Crc(u16, .{ |
| 517 | .xor_output = 0x0000, | 625 | .xor_output = 0x0000, |
| 518 | }); | 626 | }); |
| 519 | 627 | ||
| 520 | pub const Crc16Lj1200 = Crc(u16, .{ | 628 | pub const Crc16Lj1200 = Generic(u16, .{ |
| 521 | .polynomial = 0x6f63, | 629 | .polynomial = 0x6f63, |
| 522 | .initial = 0x0000, | 630 | .initial = 0x0000, |
| 523 | .reflect_input = false, | 631 | .reflect_input = false, |
| ... | @@ -525,7 +633,7 @@ pub const Crc16Lj1200 = Crc(u16, .{ | ... | @@ -525,7 +633,7 @@ pub const Crc16Lj1200 = Crc(u16, .{ |
| 525 | .xor_output = 0x0000, | 633 | .xor_output = 0x0000, |
| 526 | }); | 634 | }); |
| 527 | 635 | ||
| 528 | pub const Crc16M17 = Crc(u16, .{ | 636 | pub const Crc16M17 = Generic(u16, .{ |
| 529 | .polynomial = 0x5935, | 637 | .polynomial = 0x5935, |
| 530 | .initial = 0xffff, | 638 | .initial = 0xffff, |
| 531 | .reflect_input = false, | 639 | .reflect_input = false, |
| ... | @@ -533,7 +641,7 @@ pub const Crc16M17 = Crc(u16, .{ | ... | @@ -533,7 +641,7 @@ pub const Crc16M17 = Crc(u16, .{ |
| 533 | .xor_output = 0x0000, | 641 | .xor_output = 0x0000, |
| 534 | }); | 642 | }); |
| 535 | 643 | ||
| 536 | pub const Crc16MaximDow = Crc(u16, .{ | 644 | pub const Crc16MaximDow = Generic(u16, .{ |
| 537 | .polynomial = 0x8005, | 645 | .polynomial = 0x8005, |
| 538 | .initial = 0x0000, | 646 | .initial = 0x0000, |
| 539 | .reflect_input = true, | 647 | .reflect_input = true, |
| ... | @@ -541,7 +649,7 @@ pub const Crc16MaximDow = Crc(u16, .{ | ... | @@ -541,7 +649,7 @@ pub const Crc16MaximDow = Crc(u16, .{ |
| 541 | .xor_output = 0xffff, | 649 | .xor_output = 0xffff, |
| 542 | }); | 650 | }); |
| 543 | 651 | ||
| 544 | pub const Crc16Mcrf4xx = Crc(u16, .{ | 652 | pub const Crc16Mcrf4xx = Generic(u16, .{ |
| 545 | .polynomial = 0x1021, | 653 | .polynomial = 0x1021, |
| 546 | .initial = 0xffff, | 654 | .initial = 0xffff, |
| 547 | .reflect_input = true, | 655 | .reflect_input = true, |
| ... | @@ -549,7 +657,7 @@ pub const Crc16Mcrf4xx = Crc(u16, .{ | ... | @@ -549,7 +657,7 @@ pub const Crc16Mcrf4xx = Crc(u16, .{ |
| 549 | .xor_output = 0x0000, | 657 | .xor_output = 0x0000, |
| 550 | }); | 658 | }); |
| 551 | 659 | ||
| 552 | pub const Crc16Modbus = Crc(u16, .{ | 660 | pub const Crc16Modbus = Generic(u16, .{ |
| 553 | .polynomial = 0x8005, | 661 | .polynomial = 0x8005, |
| 554 | .initial = 0xffff, | 662 | .initial = 0xffff, |
| 555 | .reflect_input = true, | 663 | .reflect_input = true, |
| ... | @@ -557,7 +665,7 @@ pub const Crc16Modbus = Crc(u16, .{ | ... | @@ -557,7 +665,7 @@ pub const Crc16Modbus = Crc(u16, .{ |
| 557 | .xor_output = 0x0000, | 665 | .xor_output = 0x0000, |
| 558 | }); | 666 | }); |
| 559 | 667 | ||
| 560 | pub const Crc16Nrsc5 = Crc(u16, .{ | 668 | pub const Crc16Nrsc5 = Generic(u16, .{ |
| 561 | .polynomial = 0x080b, | 669 | .polynomial = 0x080b, |
| 562 | .initial = 0xffff, | 670 | .initial = 0xffff, |
| 563 | .reflect_input = true, | 671 | .reflect_input = true, |
| ... | @@ -565,7 +673,7 @@ pub const Crc16Nrsc5 = Crc(u16, .{ | ... | @@ -565,7 +673,7 @@ pub const Crc16Nrsc5 = Crc(u16, .{ |
| 565 | .xor_output = 0x0000, | 673 | .xor_output = 0x0000, |
| 566 | }); | 674 | }); |
| 567 | 675 | ||
| 568 | pub const Crc16OpensafetyA = Crc(u16, .{ | 676 | pub const Crc16OpensafetyA = Generic(u16, .{ |
| 569 | .polynomial = 0x5935, | 677 | .polynomial = 0x5935, |
| 570 | .initial = 0x0000, | 678 | .initial = 0x0000, |
| 571 | .reflect_input = false, | 679 | .reflect_input = false, |
| ... | @@ -573,7 +681,7 @@ pub const Crc16OpensafetyA = Crc(u16, .{ | ... | @@ -573,7 +681,7 @@ pub const Crc16OpensafetyA = Crc(u16, .{ |
| 573 | .xor_output = 0x0000, | 681 | .xor_output = 0x0000, |
| 574 | }); | 682 | }); |
| 575 | 683 | ||
| 576 | pub const Crc16OpensafetyB = Crc(u16, .{ | 684 | pub const Crc16OpensafetyB = Generic(u16, .{ |
| 577 | .polynomial = 0x755b, | 685 | .polynomial = 0x755b, |
| 578 | .initial = 0x0000, | 686 | .initial = 0x0000, |
| 579 | .reflect_input = false, | 687 | .reflect_input = false, |
| ... | @@ -581,7 +689,7 @@ pub const Crc16OpensafetyB = Crc(u16, .{ | ... | @@ -581,7 +689,7 @@ pub const Crc16OpensafetyB = Crc(u16, .{ |
| 581 | .xor_output = 0x0000, | 689 | .xor_output = 0x0000, |
| 582 | }); | 690 | }); |
| 583 | 691 | ||
| 584 | pub const Crc16Profibus = Crc(u16, .{ | 692 | pub const Crc16Profibus = Generic(u16, .{ |
| 585 | .polynomial = 0x1dcf, | 693 | .polynomial = 0x1dcf, |
| 586 | .initial = 0xffff, | 694 | .initial = 0xffff, |
| 587 | .reflect_input = false, | 695 | .reflect_input = false, |
| ... | @@ -589,7 +697,7 @@ pub const Crc16Profibus = Crc(u16, .{ | ... | @@ -589,7 +697,7 @@ pub const Crc16Profibus = Crc(u16, .{ |
| 589 | .xor_output = 0xffff, | 697 | .xor_output = 0xffff, |
| 590 | }); | 698 | }); |
| 591 | 699 | ||
| 592 | pub const Crc16Riello = Crc(u16, .{ | 700 | pub const Crc16Riello = Generic(u16, .{ |
| 593 | .polynomial = 0x1021, | 701 | .polynomial = 0x1021, |
| 594 | .initial = 0xb2aa, | 702 | .initial = 0xb2aa, |
| 595 | .reflect_input = true, | 703 | .reflect_input = true, |
| ... | @@ -597,7 +705,7 @@ pub const Crc16Riello = Crc(u16, .{ | ... | @@ -597,7 +705,7 @@ pub const Crc16Riello = Crc(u16, .{ |
| 597 | .xor_output = 0x0000, | 705 | .xor_output = 0x0000, |
| 598 | }); | 706 | }); |
| 599 | 707 | ||
| 600 | pub const Crc16SpiFujitsu = Crc(u16, .{ | 708 | pub const Crc16SpiFujitsu = Generic(u16, .{ |
| 601 | .polynomial = 0x1021, | 709 | .polynomial = 0x1021, |
| 602 | .initial = 0x1d0f, | 710 | .initial = 0x1d0f, |
| 603 | .reflect_input = false, | 711 | .reflect_input = false, |
| ... | @@ -605,7 +713,7 @@ pub const Crc16SpiFujitsu = Crc(u16, .{ | ... | @@ -605,7 +713,7 @@ pub const Crc16SpiFujitsu = Crc(u16, .{ |
| 605 | .xor_output = 0x0000, | 713 | .xor_output = 0x0000, |
| 606 | }); | 714 | }); |
| 607 | 715 | ||
| 608 | pub const Crc16T10Dif = Crc(u16, .{ | 716 | pub const Crc16T10Dif = Generic(u16, .{ |
| 609 | .polynomial = 0x8bb7, | 717 | .polynomial = 0x8bb7, |
| 610 | .initial = 0x0000, | 718 | .initial = 0x0000, |
| 611 | .reflect_input = false, | 719 | .reflect_input = false, |
| ... | @@ -613,7 +721,7 @@ pub const Crc16T10Dif = Crc(u16, .{ | ... | @@ -613,7 +721,7 @@ pub const Crc16T10Dif = Crc(u16, .{ |
| 613 | .xor_output = 0x0000, | 721 | .xor_output = 0x0000, |
| 614 | }); | 722 | }); |
| 615 | 723 | ||
| 616 | pub const Crc16Teledisk = Crc(u16, .{ | 724 | pub const Crc16Teledisk = Generic(u16, .{ |
| 617 | .polynomial = 0xa097, | 725 | .polynomial = 0xa097, |
| 618 | .initial = 0x0000, | 726 | .initial = 0x0000, |
| 619 | .reflect_input = false, | 727 | .reflect_input = false, |
| ... | @@ -621,7 +729,7 @@ pub const Crc16Teledisk = Crc(u16, .{ | ... | @@ -621,7 +729,7 @@ pub const Crc16Teledisk = Crc(u16, .{ |
| 621 | .xor_output = 0x0000, | 729 | .xor_output = 0x0000, |
| 622 | }); | 730 | }); |
| 623 | 731 | ||
| 624 | pub const Crc16Tms37157 = Crc(u16, .{ | 732 | pub const Crc16Tms37157 = Generic(u16, .{ |
| 625 | .polynomial = 0x1021, | 733 | .polynomial = 0x1021, |
| 626 | .initial = 0x89ec, | 734 | .initial = 0x89ec, |
| 627 | .reflect_input = true, | 735 | .reflect_input = true, |
| ... | @@ -629,7 +737,7 @@ pub const Crc16Tms37157 = Crc(u16, .{ | ... | @@ -629,7 +737,7 @@ pub const Crc16Tms37157 = Crc(u16, .{ |
| 629 | .xor_output = 0x0000, | 737 | .xor_output = 0x0000, |
| 630 | }); | 738 | }); |
| 631 | 739 | ||
| 632 | pub const Crc16Umts = Crc(u16, .{ | 740 | pub const Crc16Umts = Generic(u16, .{ |
| 633 | .polynomial = 0x8005, | 741 | .polynomial = 0x8005, |
| 634 | .initial = 0x0000, | 742 | .initial = 0x0000, |
| 635 | .reflect_input = false, | 743 | .reflect_input = false, |
| ... | @@ -637,7 +745,7 @@ pub const Crc16Umts = Crc(u16, .{ | ... | @@ -637,7 +745,7 @@ pub const Crc16Umts = Crc(u16, .{ |
| 637 | .xor_output = 0x0000, | 745 | .xor_output = 0x0000, |
| 638 | }); | 746 | }); |
| 639 | 747 | ||
| 640 | pub const Crc16Usb = Crc(u16, .{ | 748 | pub const Crc16Usb = Generic(u16, .{ |
| 641 | .polynomial = 0x8005, | 749 | .polynomial = 0x8005, |
| 642 | .initial = 0xffff, | 750 | .initial = 0xffff, |
| 643 | .reflect_input = true, | 751 | .reflect_input = true, |
| ... | @@ -645,7 +753,7 @@ pub const Crc16Usb = Crc(u16, .{ | ... | @@ -645,7 +753,7 @@ pub const Crc16Usb = Crc(u16, .{ |
| 645 | .xor_output = 0xffff, | 753 | .xor_output = 0xffff, |
| 646 | }); | 754 | }); |
| 647 | 755 | ||
| 648 | pub const Crc16Xmodem = Crc(u16, .{ | 756 | pub const Crc16Xmodem = Generic(u16, .{ |
| 649 | .polynomial = 0x1021, | 757 | .polynomial = 0x1021, |
| 650 | .initial = 0x0000, | 758 | .initial = 0x0000, |
| 651 | .reflect_input = false, | 759 | .reflect_input = false, |
| ... | @@ -653,7 +761,7 @@ pub const Crc16Xmodem = Crc(u16, .{ | ... | @@ -653,7 +761,7 @@ pub const Crc16Xmodem = Crc(u16, .{ |
| 653 | .xor_output = 0x0000, | 761 | .xor_output = 0x0000, |
| 654 | }); | 762 | }); |
| 655 | 763 | ||
| 656 | pub const Crc17CanFd = Crc(u17, .{ | 764 | pub const Crc17CanFd = Generic(u17, .{ |
| 657 | .polynomial = 0x1685b, | 765 | .polynomial = 0x1685b, |
| 658 | .initial = 0x00000, | 766 | .initial = 0x00000, |
| 659 | .reflect_input = false, | 767 | .reflect_input = false, |
| ... | @@ -661,7 +769,7 @@ pub const Crc17CanFd = Crc(u17, .{ | ... | @@ -661,7 +769,7 @@ pub const Crc17CanFd = Crc(u17, .{ |
| 661 | .xor_output = 0x00000, | 769 | .xor_output = 0x00000, |
| 662 | }); | 770 | }); |
| 663 | 771 | ||
| 664 | pub const Crc21CanFd = Crc(u21, .{ | 772 | pub const Crc21CanFd = Generic(u21, .{ |
| 665 | .polynomial = 0x102899, | 773 | .polynomial = 0x102899, |
| 666 | .initial = 0x000000, | 774 | .initial = 0x000000, |
| 667 | .reflect_input = false, | 775 | .reflect_input = false, |
| ... | @@ -669,7 +777,7 @@ pub const Crc21CanFd = Crc(u21, .{ | ... | @@ -669,7 +777,7 @@ pub const Crc21CanFd = Crc(u21, .{ |
| 669 | .xor_output = 0x000000, | 777 | .xor_output = 0x000000, |
| 670 | }); | 778 | }); |
| 671 | 779 | ||
| 672 | pub const Crc24Ble = Crc(u24, .{ | 780 | pub const Crc24Ble = Generic(u24, .{ |
| 673 | .polynomial = 0x00065b, | 781 | .polynomial = 0x00065b, |
| 674 | .initial = 0x555555, | 782 | .initial = 0x555555, |
| 675 | .reflect_input = true, | 783 | .reflect_input = true, |
| ... | @@ -677,7 +785,7 @@ pub const Crc24Ble = Crc(u24, .{ | ... | @@ -677,7 +785,7 @@ pub const Crc24Ble = Crc(u24, .{ |
| 677 | .xor_output = 0x000000, | 785 | .xor_output = 0x000000, |
| 678 | }); | 786 | }); |
| 679 | 787 | ||
| 680 | pub const Crc24FlexrayA = Crc(u24, .{ | 788 | pub const Crc24FlexrayA = Generic(u24, .{ |
| 681 | .polynomial = 0x5d6dcb, | 789 | .polynomial = 0x5d6dcb, |
| 682 | .initial = 0xfedcba, | 790 | .initial = 0xfedcba, |
| 683 | .reflect_input = false, | 791 | .reflect_input = false, |
| ... | @@ -685,7 +793,7 @@ pub const Crc24FlexrayA = Crc(u24, .{ | ... | @@ -685,7 +793,7 @@ pub const Crc24FlexrayA = Crc(u24, .{ |
| 685 | .xor_output = 0x000000, | 793 | .xor_output = 0x000000, |
| 686 | }); | 794 | }); |
| 687 | 795 | ||
| 688 | pub const Crc24FlexrayB = Crc(u24, .{ | 796 | pub const Crc24FlexrayB = Generic(u24, .{ |
| 689 | .polynomial = 0x5d6dcb, | 797 | .polynomial = 0x5d6dcb, |
| 690 | .initial = 0xabcdef, | 798 | .initial = 0xabcdef, |
| 691 | .reflect_input = false, | 799 | .reflect_input = false, |
| ... | @@ -693,7 +801,7 @@ pub const Crc24FlexrayB = Crc(u24, .{ | ... | @@ -693,7 +801,7 @@ pub const Crc24FlexrayB = Crc(u24, .{ |
| 693 | .xor_output = 0x000000, | 801 | .xor_output = 0x000000, |
| 694 | }); | 802 | }); |
| 695 | 803 | ||
| 696 | pub const Crc24Interlaken = Crc(u24, .{ | 804 | pub const Crc24Interlaken = Generic(u24, .{ |
| 697 | .polynomial = 0x328b63, | 805 | .polynomial = 0x328b63, |
| 698 | .initial = 0xffffff, | 806 | .initial = 0xffffff, |
| 699 | .reflect_input = false, | 807 | .reflect_input = false, |
| ... | @@ -701,7 +809,7 @@ pub const Crc24Interlaken = Crc(u24, .{ | ... | @@ -701,7 +809,7 @@ pub const Crc24Interlaken = Crc(u24, .{ |
| 701 | .xor_output = 0xffffff, | 809 | .xor_output = 0xffffff, |
| 702 | }); | 810 | }); |
| 703 | 811 | ||
| 704 | pub const Crc24LteA = Crc(u24, .{ | 812 | pub const Crc24LteA = Generic(u24, .{ |
| 705 | .polynomial = 0x864cfb, | 813 | .polynomial = 0x864cfb, |
| 706 | .initial = 0x000000, | 814 | .initial = 0x000000, |
| 707 | .reflect_input = false, | 815 | .reflect_input = false, |
| ... | @@ -709,7 +817,7 @@ pub const Crc24LteA = Crc(u24, .{ | ... | @@ -709,7 +817,7 @@ pub const Crc24LteA = Crc(u24, .{ |
| 709 | .xor_output = 0x000000, | 817 | .xor_output = 0x000000, |
| 710 | }); | 818 | }); |
| 711 | 819 | ||
| 712 | pub const Crc24LteB = Crc(u24, .{ | 820 | pub const Crc24LteB = Generic(u24, .{ |
| 713 | .polynomial = 0x800063, | 821 | .polynomial = 0x800063, |
| 714 | .initial = 0x000000, | 822 | .initial = 0x000000, |
| 715 | .reflect_input = false, | 823 | .reflect_input = false, |
| ... | @@ -717,7 +825,7 @@ pub const Crc24LteB = Crc(u24, .{ | ... | @@ -717,7 +825,7 @@ pub const Crc24LteB = Crc(u24, .{ |
| 717 | .xor_output = 0x000000, | 825 | .xor_output = 0x000000, |
| 718 | }); | 826 | }); |
| 719 | 827 | ||
| 720 | pub const Crc24Openpgp = Crc(u24, .{ | 828 | pub const Crc24Openpgp = Generic(u24, .{ |
| 721 | .polynomial = 0x864cfb, | 829 | .polynomial = 0x864cfb, |
| 722 | .initial = 0xb704ce, | 830 | .initial = 0xb704ce, |
| 723 | .reflect_input = false, | 831 | .reflect_input = false, |
| ... | @@ -725,7 +833,7 @@ pub const Crc24Openpgp = Crc(u24, .{ | ... | @@ -725,7 +833,7 @@ pub const Crc24Openpgp = Crc(u24, .{ |
| 725 | .xor_output = 0x000000, | 833 | .xor_output = 0x000000, |
| 726 | }); | 834 | }); |
| 727 | 835 | ||
| 728 | pub const Crc24Os9 = Crc(u24, .{ | 836 | pub const Crc24Os9 = Generic(u24, .{ |
| 729 | .polynomial = 0x800063, | 837 | .polynomial = 0x800063, |
| 730 | .initial = 0xffffff, | 838 | .initial = 0xffffff, |
| 731 | .reflect_input = false, | 839 | .reflect_input = false, |
| ... | @@ -733,7 +841,7 @@ pub const Crc24Os9 = Crc(u24, .{ | ... | @@ -733,7 +841,7 @@ pub const Crc24Os9 = Crc(u24, .{ |
| 733 | .xor_output = 0xffffff, | 841 | .xor_output = 0xffffff, |
| 734 | }); | 842 | }); |
| 735 | 843 | ||
| 736 | pub const Crc30Cdma = Crc(u30, .{ | 844 | pub const Crc30Cdma = Generic(u30, .{ |
| 737 | .polynomial = 0x2030b9c7, | 845 | .polynomial = 0x2030b9c7, |
| 738 | .initial = 0x3fffffff, | 846 | .initial = 0x3fffffff, |
| 739 | .reflect_input = false, | 847 | .reflect_input = false, |
| ... | @@ -741,7 +849,7 @@ pub const Crc30Cdma = Crc(u30, .{ | ... | @@ -741,7 +849,7 @@ pub const Crc30Cdma = Crc(u30, .{ |
| 741 | .xor_output = 0x3fffffff, | 849 | .xor_output = 0x3fffffff, |
| 742 | }); | 850 | }); |
| 743 | 851 | ||
| 744 | pub const Crc31Philips = Crc(u31, .{ | 852 | pub const Crc31Philips = Generic(u31, .{ |
| 745 | .polynomial = 0x04c11db7, | 853 | .polynomial = 0x04c11db7, |
| 746 | .initial = 0x7fffffff, | 854 | .initial = 0x7fffffff, |
| 747 | .reflect_input = false, | 855 | .reflect_input = false, |
| ... | @@ -749,7 +857,7 @@ pub const Crc31Philips = Crc(u31, .{ | ... | @@ -749,7 +857,7 @@ pub const Crc31Philips = Crc(u31, .{ |
| 749 | .xor_output = 0x7fffffff, | 857 | .xor_output = 0x7fffffff, |
| 750 | }); | 858 | }); |
| 751 | 859 | ||
| 752 | pub const Crc32Aixm = Crc(u32, .{ | 860 | pub const Crc32Aixm = Generic(u32, .{ |
| 753 | .polynomial = 0x814141ab, | 861 | .polynomial = 0x814141ab, |
| 754 | .initial = 0x00000000, | 862 | .initial = 0x00000000, |
| 755 | .reflect_input = false, | 863 | .reflect_input = false, |
| ... | @@ -757,7 +865,7 @@ pub const Crc32Aixm = Crc(u32, .{ | ... | @@ -757,7 +865,7 @@ pub const Crc32Aixm = Crc(u32, .{ |
| 757 | .xor_output = 0x00000000, | 865 | .xor_output = 0x00000000, |
| 758 | }); | 866 | }); |
| 759 | 867 | ||
| 760 | pub const Crc32Autosar = Crc(u32, .{ | 868 | pub const Crc32Autosar = Generic(u32, .{ |
| 761 | .polynomial = 0xf4acfb13, | 869 | .polynomial = 0xf4acfb13, |
| 762 | .initial = 0xffffffff, | 870 | .initial = 0xffffffff, |
| 763 | .reflect_input = true, | 871 | .reflect_input = true, |
| ... | @@ -765,7 +873,7 @@ pub const Crc32Autosar = Crc(u32, .{ | ... | @@ -765,7 +873,7 @@ pub const Crc32Autosar = Crc(u32, .{ |
| 765 | .xor_output = 0xffffffff, | 873 | .xor_output = 0xffffffff, |
| 766 | }); | 874 | }); |
| 767 | 875 | ||
| 768 | pub const Crc32Base91D = Crc(u32, .{ | 876 | pub const Crc32Base91D = Generic(u32, .{ |
| 769 | .polynomial = 0xa833982b, | 877 | .polynomial = 0xa833982b, |
| 770 | .initial = 0xffffffff, | 878 | .initial = 0xffffffff, |
| 771 | .reflect_input = true, | 879 | .reflect_input = true, |
| ... | @@ -773,7 +881,7 @@ pub const Crc32Base91D = Crc(u32, .{ | ... | @@ -773,7 +881,7 @@ pub const Crc32Base91D = Crc(u32, .{ |
| 773 | .xor_output = 0xffffffff, | 881 | .xor_output = 0xffffffff, |
| 774 | }); | 882 | }); |
| 775 | 883 | ||
| 776 | pub const Crc32Bzip2 = Crc(u32, .{ | 884 | pub const Crc32Bzip2 = Generic(u32, .{ |
| 777 | .polynomial = 0x04c11db7, | 885 | .polynomial = 0x04c11db7, |
| 778 | .initial = 0xffffffff, | 886 | .initial = 0xffffffff, |
| 779 | .reflect_input = false, | 887 | .reflect_input = false, |
| ... | @@ -781,7 +889,7 @@ pub const Crc32Bzip2 = Crc(u32, .{ | ... | @@ -781,7 +889,7 @@ pub const Crc32Bzip2 = Crc(u32, .{ |
| 781 | .xor_output = 0xffffffff, | 889 | .xor_output = 0xffffffff, |
| 782 | }); | 890 | }); |
| 783 | 891 | ||
| 784 | pub const Crc32CdRomEdc = Crc(u32, .{ | 892 | pub const Crc32CdRomEdc = Generic(u32, .{ |
| 785 | .polynomial = 0x8001801b, | 893 | .polynomial = 0x8001801b, |
| 786 | .initial = 0x00000000, | 894 | .initial = 0x00000000, |
| 787 | .reflect_input = true, | 895 | .reflect_input = true, |
| ... | @@ -789,7 +897,7 @@ pub const Crc32CdRomEdc = Crc(u32, .{ | ... | @@ -789,7 +897,7 @@ pub const Crc32CdRomEdc = Crc(u32, .{ |
| 789 | .xor_output = 0x00000000, | 897 | .xor_output = 0x00000000, |
| 790 | }); | 898 | }); |
| 791 | 899 | ||
| 792 | pub const Crc32Cksum = Crc(u32, .{ | 900 | pub const Crc32Cksum = Generic(u32, .{ |
| 793 | .polynomial = 0x04c11db7, | 901 | .polynomial = 0x04c11db7, |
| 794 | .initial = 0x00000000, | 902 | .initial = 0x00000000, |
| 795 | .reflect_input = false, | 903 | .reflect_input = false, |
| ... | @@ -797,7 +905,7 @@ pub const Crc32Cksum = Crc(u32, .{ | ... | @@ -797,7 +905,7 @@ pub const Crc32Cksum = Crc(u32, .{ |
| 797 | .xor_output = 0xffffffff, | 905 | .xor_output = 0xffffffff, |
| 798 | }); | 906 | }); |
| 799 | 907 | ||
| 800 | pub const Crc32Iscsi = Crc(u32, .{ | 908 | pub const Crc32Iscsi = Generic(u32, .{ |
| 801 | .polynomial = 0x1edc6f41, | 909 | .polynomial = 0x1edc6f41, |
| 802 | .initial = 0xffffffff, | 910 | .initial = 0xffffffff, |
| 803 | .reflect_input = true, | 911 | .reflect_input = true, |
| ... | @@ -805,7 +913,7 @@ pub const Crc32Iscsi = Crc(u32, .{ | ... | @@ -805,7 +913,7 @@ pub const Crc32Iscsi = Crc(u32, .{ |
| 805 | .xor_output = 0xffffffff, | 913 | .xor_output = 0xffffffff, |
| 806 | }); | 914 | }); |
| 807 | 915 | ||
| 808 | pub const Crc32IsoHdlc = Crc(u32, .{ | 916 | pub const Crc32IsoHdlc = Generic(u32, .{ |
| 809 | .polynomial = 0x04c11db7, | 917 | .polynomial = 0x04c11db7, |
| 810 | .initial = 0xffffffff, | 918 | .initial = 0xffffffff, |
| 811 | .reflect_input = true, | 919 | .reflect_input = true, |
| ... | @@ -813,7 +921,7 @@ pub const Crc32IsoHdlc = Crc(u32, .{ | ... | @@ -813,7 +921,7 @@ pub const Crc32IsoHdlc = Crc(u32, .{ |
| 813 | .xor_output = 0xffffffff, | 921 | .xor_output = 0xffffffff, |
| 814 | }); | 922 | }); |
| 815 | 923 | ||
| 816 | pub const Crc32Jamcrc = Crc(u32, .{ | 924 | pub const Crc32Jamcrc = Generic(u32, .{ |
| 817 | .polynomial = 0x04c11db7, | 925 | .polynomial = 0x04c11db7, |
| 818 | .initial = 0xffffffff, | 926 | .initial = 0xffffffff, |
| 819 | .reflect_input = true, | 927 | .reflect_input = true, |
| ... | @@ -821,7 +929,7 @@ pub const Crc32Jamcrc = Crc(u32, .{ | ... | @@ -821,7 +929,7 @@ pub const Crc32Jamcrc = Crc(u32, .{ |
| 821 | .xor_output = 0x00000000, | 929 | .xor_output = 0x00000000, |
| 822 | }); | 930 | }); |
| 823 | 931 | ||
| 824 | pub const Crc32Koopman = Crc(u32, .{ | 932 | pub const Crc32Koopman = Generic(u32, .{ |
| 825 | .polynomial = 0x741b8cd7, | 933 | .polynomial = 0x741b8cd7, |
| 826 | .initial = 0xffffffff, | 934 | .initial = 0xffffffff, |
| 827 | .reflect_input = true, | 935 | .reflect_input = true, |
| ... | @@ -829,7 +937,7 @@ pub const Crc32Koopman = Crc(u32, .{ | ... | @@ -829,7 +937,7 @@ pub const Crc32Koopman = Crc(u32, .{ |
| 829 | .xor_output = 0xffffffff, | 937 | .xor_output = 0xffffffff, |
| 830 | }); | 938 | }); |
| 831 | 939 | ||
| 832 | pub const Crc32Mef = Crc(u32, .{ | 940 | pub const Crc32Mef = Generic(u32, .{ |
| 833 | .polynomial = 0x741b8cd7, | 941 | .polynomial = 0x741b8cd7, |
| 834 | .initial = 0xffffffff, | 942 | .initial = 0xffffffff, |
| 835 | .reflect_input = true, | 943 | .reflect_input = true, |
| ... | @@ -837,7 +945,7 @@ pub const Crc32Mef = Crc(u32, .{ | ... | @@ -837,7 +945,7 @@ pub const Crc32Mef = Crc(u32, .{ |
| 837 | .xor_output = 0x00000000, | 945 | .xor_output = 0x00000000, |
| 838 | }); | 946 | }); |
| 839 | 947 | ||
| 840 | pub const Crc32Mpeg2 = Crc(u32, .{ | 948 | pub const Crc32Mpeg2 = Generic(u32, .{ |
| 841 | .polynomial = 0x04c11db7, | 949 | .polynomial = 0x04c11db7, |
| 842 | .initial = 0xffffffff, | 950 | .initial = 0xffffffff, |
| 843 | .reflect_input = false, | 951 | .reflect_input = false, |
| ... | @@ -845,7 +953,7 @@ pub const Crc32Mpeg2 = Crc(u32, .{ | ... | @@ -845,7 +953,7 @@ pub const Crc32Mpeg2 = Crc(u32, .{ |
| 845 | .xor_output = 0x00000000, | 953 | .xor_output = 0x00000000, |
| 846 | }); | 954 | }); |
| 847 | 955 | ||
| 848 | pub const Crc32Xfer = Crc(u32, .{ | 956 | pub const Crc32Xfer = Generic(u32, .{ |
| 849 | .polynomial = 0x000000af, | 957 | .polynomial = 0x000000af, |
| 850 | .initial = 0x00000000, | 958 | .initial = 0x00000000, |
| 851 | .reflect_input = false, | 959 | .reflect_input = false, |
| ... | @@ -853,7 +961,7 @@ pub const Crc32Xfer = Crc(u32, .{ | ... | @@ -853,7 +961,7 @@ pub const Crc32Xfer = Crc(u32, .{ |
| 853 | .xor_output = 0x00000000, | 961 | .xor_output = 0x00000000, |
| 854 | }); | 962 | }); |
| 855 | 963 | ||
| 856 | pub const Crc40Gsm = Crc(u40, .{ | 964 | pub const Crc40Gsm = Generic(u40, .{ |
| 857 | .polynomial = 0x0004820009, | 965 | .polynomial = 0x0004820009, |
| 858 | .initial = 0x0000000000, | 966 | .initial = 0x0000000000, |
| 859 | .reflect_input = false, | 967 | .reflect_input = false, |
| ... | @@ -861,7 +969,7 @@ pub const Crc40Gsm = Crc(u40, .{ | ... | @@ -861,7 +969,7 @@ pub const Crc40Gsm = Crc(u40, .{ |
| 861 | .xor_output = 0xffffffffff, | 969 | .xor_output = 0xffffffffff, |
| 862 | }); | 970 | }); |
| 863 | 971 | ||
| 864 | pub const Crc64Ecma182 = Crc(u64, .{ | 972 | pub const Crc64Ecma182 = Generic(u64, .{ |
| 865 | .polynomial = 0x42f0e1eba9ea3693, | 973 | .polynomial = 0x42f0e1eba9ea3693, |
| 866 | .initial = 0x0000000000000000, | 974 | .initial = 0x0000000000000000, |
| 867 | .reflect_input = false, | 975 | .reflect_input = false, |
| ... | @@ -869,7 +977,7 @@ pub const Crc64Ecma182 = Crc(u64, .{ | ... | @@ -869,7 +977,7 @@ pub const Crc64Ecma182 = Crc(u64, .{ |
| 869 | .xor_output = 0x0000000000000000, | 977 | .xor_output = 0x0000000000000000, |
| 870 | }); | 978 | }); |
| 871 | 979 | ||
| 872 | pub const Crc64GoIso = Crc(u64, .{ | 980 | pub const Crc64GoIso = Generic(u64, .{ |
| 873 | .polynomial = 0x000000000000001b, | 981 | .polynomial = 0x000000000000001b, |
| 874 | .initial = 0xffffffffffffffff, | 982 | .initial = 0xffffffffffffffff, |
| 875 | .reflect_input = true, | 983 | .reflect_input = true, |
| ... | @@ -877,7 +985,7 @@ pub const Crc64GoIso = Crc(u64, .{ | ... | @@ -877,7 +985,7 @@ pub const Crc64GoIso = Crc(u64, .{ |
| 877 | .xor_output = 0xffffffffffffffff, | 985 | .xor_output = 0xffffffffffffffff, |
| 878 | }); | 986 | }); |
| 879 | 987 | ||
| 880 | pub const Crc64Ms = Crc(u64, .{ | 988 | pub const Crc64Ms = Generic(u64, .{ |
| 881 | .polynomial = 0x259c84cba6426349, | 989 | .polynomial = 0x259c84cba6426349, |
| 882 | .initial = 0xffffffffffffffff, | 990 | .initial = 0xffffffffffffffff, |
| 883 | .reflect_input = true, | 991 | .reflect_input = true, |
| ... | @@ -885,7 +993,7 @@ pub const Crc64Ms = Crc(u64, .{ | ... | @@ -885,7 +993,7 @@ pub const Crc64Ms = Crc(u64, .{ |
| 885 | .xor_output = 0x0000000000000000, | 993 | .xor_output = 0x0000000000000000, |
| 886 | }); | 994 | }); |
| 887 | 995 | ||
| 888 | pub const Crc64Redis = Crc(u64, .{ | 996 | pub const Crc64Redis = Generic(u64, .{ |
| 889 | .polynomial = 0xad93d23594c935a9, | 997 | .polynomial = 0xad93d23594c935a9, |
| 890 | .initial = 0x0000000000000000, | 998 | .initial = 0x0000000000000000, |
| 891 | .reflect_input = true, | 999 | .reflect_input = true, |
| ... | @@ -893,7 +1001,7 @@ pub const Crc64Redis = Crc(u64, .{ | ... | @@ -893,7 +1001,7 @@ pub const Crc64Redis = Crc(u64, .{ |
| 893 | .xor_output = 0x0000000000000000, | 1001 | .xor_output = 0x0000000000000000, |
| 894 | }); | 1002 | }); |
| 895 | 1003 | ||
| 896 | pub const Crc64We = Crc(u64, .{ | 1004 | pub const Crc64We = Generic(u64, .{ |
| 897 | .polynomial = 0x42f0e1eba9ea3693, | 1005 | .polynomial = 0x42f0e1eba9ea3693, |
| 898 | .initial = 0xffffffffffffffff, | 1006 | .initial = 0xffffffffffffffff, |
| 899 | .reflect_input = false, | 1007 | .reflect_input = false, |
| ... | @@ -901,7 +1009,7 @@ pub const Crc64We = Crc(u64, .{ | ... | @@ -901,7 +1009,7 @@ pub const Crc64We = Crc(u64, .{ |
| 901 | .xor_output = 0xffffffffffffffff, | 1009 | .xor_output = 0xffffffffffffffff, |
| 902 | }); | 1010 | }); |
| 903 | 1011 | ||
| 904 | pub const Crc64Xz = Crc(u64, .{ | 1012 | pub const Crc64Xz = Generic(u64, .{ |
| 905 | .polynomial = 0x42f0e1eba9ea3693, | 1013 | .polynomial = 0x42f0e1eba9ea3693, |
| 906 | .initial = 0xffffffffffffffff, | 1014 | .initial = 0xffffffffffffffff, |
| 907 | .reflect_input = true, | 1015 | .reflect_input = true, |
| ... | @@ -909,10 +1017,14 @@ pub const Crc64Xz = Crc(u64, .{ | ... | @@ -909,10 +1017,14 @@ pub const Crc64Xz = Crc(u64, .{ |
| 909 | .xor_output = 0xffffffffffffffff, | 1017 | .xor_output = 0xffffffffffffffff, |
| 910 | }); | 1018 | }); |
| 911 | 1019 | ||
| 912 | pub const Crc82Darc = Crc(u82, .{ | 1020 | pub const Crc82Darc = Generic(u82, .{ |
| 913 | .polynomial = 0x0308c0111011401440411, | 1021 | .polynomial = 0x0308c0111011401440411, |
| 914 | .initial = 0x000000000000000000000, | 1022 | .initial = 0x000000000000000000000, |
| 915 | .reflect_input = true, | 1023 | .reflect_input = true, |
| 916 | .reflect_output = true, | 1024 | .reflect_output = true, |
| 917 | .xor_output = 0x000000000000000000000, | 1025 | .xor_output = 0x000000000000000000000, |
| 918 | }); | 1026 | }); |
| 1027 | |||
| 1028 | test { | ||
| 1029 | _ = @import("crc/test.zig"); | ||
| 1030 | } |
lib/std/hash/crc/impl.zig deleted-112| ... | @@ -1,112 +0,0 @@ | ||
| 1 | // There is a generic CRC implementation "Crc()" which can be parameterized via | ||
| 2 | // the Algorithm struct for a plethora of uses. | ||
| 3 | // | ||
| 4 | // The primary interface for all of the standard CRC algorithms is the | ||
| 5 | // generated file "crc.zig", which uses the implementation code here to define | ||
| 6 | // many standard CRCs. | ||
| 7 | |||
| 8 | const std = @import("std"); | ||
| 9 | |||
| 10 | pub fn Algorithm(comptime W: type) type { | ||
| 11 | return struct { | ||
| 12 | polynomial: W, | ||
| 13 | initial: W, | ||
| 14 | reflect_input: bool, | ||
| 15 | reflect_output: bool, | ||
| 16 | xor_output: W, | ||
| 17 | }; | ||
| 18 | } | ||
| 19 | |||
| 20 | pub fn Crc(comptime W: type, comptime algorithm: Algorithm(W)) type { | ||
| 21 | return struct { | ||
| 22 | const Self = @This(); | ||
| 23 | const I = if (@bitSizeOf(W) < 8) u8 else W; | ||
| 24 | const lookup_table = blk: { | ||
| 25 | @setEvalBranchQuota(2500); | ||
| 26 | |||
| 27 | const poly = if (algorithm.reflect_input) | ||
| 28 | @bitReverse(@as(I, algorithm.polynomial)) >> (@bitSizeOf(I) - @bitSizeOf(W)) | ||
| 29 | else | ||
| 30 | @as(I, algorithm.polynomial) << (@bitSizeOf(I) - @bitSizeOf(W)); | ||
| 31 | |||
| 32 | var table: [256]I = undefined; | ||
| 33 | for (&table, 0..) |*e, i| { | ||
| 34 | var crc: I = i; | ||
| 35 | if (algorithm.reflect_input) { | ||
| 36 | var j: usize = 0; | ||
| 37 | while (j < 8) : (j += 1) { | ||
| 38 | crc = (crc >> 1) ^ ((crc & 1) * poly); | ||
| 39 | } | ||
| 40 | } else { | ||
| 41 | crc <<= @bitSizeOf(I) - 8; | ||
| 42 | var j: usize = 0; | ||
| 43 | while (j < 8) : (j += 1) { | ||
| 44 | crc = (crc << 1) ^ (((crc >> (@bitSizeOf(I) - 1)) & 1) * poly); | ||
| 45 | } | ||
| 46 | } | ||
| 47 | e.* = crc; | ||
| 48 | } | ||
| 49 | break :blk table; | ||
| 50 | }; | ||
| 51 | |||
| 52 | crc: I, | ||
| 53 | |||
| 54 | pub fn init() Self { | ||
| 55 | const initial = if (algorithm.reflect_input) | ||
| 56 | @bitReverse(@as(I, algorithm.initial)) >> (@bitSizeOf(I) - @bitSizeOf(W)) | ||
| 57 | else | ||
| 58 | @as(I, algorithm.initial) << (@bitSizeOf(I) - @bitSizeOf(W)); | ||
| 59 | return Self{ .crc = initial }; | ||
| 60 | } | ||
| 61 | |||
| 62 | inline fn tableEntry(index: I) I { | ||
| 63 | return lookup_table[@as(u8, @intCast(index & 0xFF))]; | ||
| 64 | } | ||
| 65 | |||
| 66 | pub fn update(self: *Self, bytes: []const u8) void { | ||
| 67 | var i: usize = 0; | ||
| 68 | if (@bitSizeOf(I) <= 8) { | ||
| 69 | while (i < bytes.len) : (i += 1) { | ||
| 70 | self.crc = tableEntry(self.crc ^ bytes[i]); | ||
| 71 | } | ||
| 72 | } else if (algorithm.reflect_input) { | ||
| 73 | while (i < bytes.len) : (i += 1) { | ||
| 74 | const table_index = self.crc ^ bytes[i]; | ||
| 75 | self.crc = tableEntry(table_index) ^ (self.crc >> 8); | ||
| 76 | } | ||
| 77 | } else { | ||
| 78 | while (i < bytes.len) : (i += 1) { | ||
| 79 | const table_index = (self.crc >> (@bitSizeOf(I) - 8)) ^ bytes[i]; | ||
| 80 | self.crc = tableEntry(table_index) ^ (self.crc << 8); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | pub fn final(self: Self) W { | ||
| 86 | var c = self.crc; | ||
| 87 | if (algorithm.reflect_input != algorithm.reflect_output) { | ||
| 88 | c = @bitReverse(c); | ||
| 89 | } | ||
| 90 | if (!algorithm.reflect_output) { | ||
| 91 | c >>= @bitSizeOf(I) - @bitSizeOf(W); | ||
| 92 | } | ||
| 93 | return @as(W, @intCast(c ^ algorithm.xor_output)); | ||
| 94 | } | ||
| 95 | |||
| 96 | pub fn hash(bytes: []const u8) W { | ||
| 97 | var c = Self.init(); | ||
| 98 | c.update(bytes); | ||
| 99 | return c.final(); | ||
| 100 | } | ||
| 101 | }; | ||
| 102 | } | ||
| 103 | |||
| 104 | pub const Polynomial = enum(u32) { | ||
| 105 | IEEE = @compileError("use Crc with algorithm .Crc32IsoHdlc"), | ||
| 106 | Castagnoli = @compileError("use Crc with algorithm .Crc32Iscsi"), | ||
| 107 | Koopman = @compileError("use Crc with algorithm .Crc32Koopman"), | ||
| 108 | _, | ||
| 109 | }; | ||
| 110 | |||
| 111 | pub const Crc32WithPoly = @compileError("use Crc instead"); | ||
| 112 | pub const Crc32SmallWithPoly = @compileError("use Crc instead"); | ||
lib/std/io/BufferedReader.zig+34-2| ... | @@ -35,6 +35,10 @@ pub fn bufferContents(br: *BufferedReader) []u8 { | ... | @@ -35,6 +35,10 @@ pub fn bufferContents(br: *BufferedReader) []u8 { |
| 35 | return br.buffer[br.seek..br.end]; | 35 | return br.buffer[br.seek..br.end]; |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | pub fn bufferedLen(br: *const BufferedReader) usize { | ||
| 39 | return br.end - br.seek; | ||
| 40 | } | ||
| 41 | |||
| 38 | /// Although `BufferedReader` can easily satisfy the `Reader` interface, it's | 42 | /// Although `BufferedReader` can easily satisfy the `Reader` interface, it's |
| 39 | /// generally more practical to pass a `BufferedReader` instance itself around, | 43 | /// generally more practical to pass a `BufferedReader` instance itself around, |
| 40 | /// since it will result in fewer calls across vtable boundaries. | 44 | /// since it will result in fewer calls across vtable boundaries. |
| ... | @@ -49,6 +53,10 @@ pub fn reader(br: *BufferedReader) Reader { | ... | @@ -49,6 +53,10 @@ pub fn reader(br: *BufferedReader) Reader { |
| 49 | }; | 53 | }; |
| 50 | } | 54 | } |
| 51 | 55 | ||
| 56 | pub fn hashed(br: *BufferedReader, hasher: anytype) Reader.Hashed(@TypeOf(hasher)) { | ||
| 57 | return .{ .in = br, .hasher = hasher }; | ||
| 58 | } | ||
| 59 | |||
| 52 | /// Equivalent semantics to `std.io.Reader.VTable.readVec`. | 60 | /// Equivalent semantics to `std.io.Reader.VTable.readVec`. |
| 53 | pub fn readVec(br: *BufferedReader, data: []const []u8) Reader.Error!usize { | 61 | pub fn readVec(br: *BufferedReader, data: []const []u8) Reader.Error!usize { |
| 54 | return readVecLimit(br, data, .unlimited); | 62 | return readVecLimit(br, data, .unlimited); |
| ... | @@ -401,6 +409,30 @@ pub fn readSliceShort(br: *BufferedReader, buffer: []u8) Reader.ShortError!usize | ... | @@ -401,6 +409,30 @@ pub fn readSliceShort(br: *BufferedReader, buffer: []u8) Reader.ShortError!usize |
| 401 | } | 409 | } |
| 402 | } | 410 | } |
| 403 | 411 | ||
| 412 | /// Fill `buffer` with the next `buffer.len` bytes from the stream, advancing | ||
| 413 | /// the seek position. | ||
| 414 | /// | ||
| 415 | /// Invalidates previously returned values from `peek`. | ||
| 416 | /// | ||
| 417 | /// If the provided buffer cannot be filled completely, `error.EndOfStream` is | ||
| 418 | /// returned instead. | ||
| 419 | /// | ||
| 420 | /// The function is inline to avoid the dead code in case `endian` is | ||
| 421 | /// comptime-known and matches host endianness. | ||
| 422 | /// | ||
| 423 | /// See also: | ||
| 424 | /// * `readSlice` | ||
| 425 | /// * `readSliceEndianAlloc` | ||
| 426 | pub inline fn readSliceEndian( | ||
| 427 | br: *BufferedReader, | ||
| 428 | comptime Elem: type, | ||
| 429 | buffer: []Elem, | ||
| 430 | endian: std.builtin.Endian, | ||
| 431 | ) Reader.Error!void { | ||
| 432 | try readSlice(br, @ptrCast(buffer)); | ||
| 433 | if (native_endian != endian) for (buffer) |*elem| std.mem.byteSwapAllFields(Elem, elem); | ||
| 434 | } | ||
| 435 | |||
| 404 | pub const ReadAllocError = Reader.Error || Allocator.Error; | 436 | pub const ReadAllocError = Reader.Error || Allocator.Error; |
| 405 | 437 | ||
| 406 | /// The function is inline to avoid the dead code in case `endian` is | 438 | /// The function is inline to avoid the dead code in case `endian` is |
| ... | @@ -408,14 +440,14 @@ pub const ReadAllocError = Reader.Error || Allocator.Error; | ... | @@ -408,14 +440,14 @@ pub const ReadAllocError = Reader.Error || Allocator.Error; |
| 408 | pub inline fn readSliceEndianAlloc( | 440 | pub inline fn readSliceEndianAlloc( |
| 409 | br: *BufferedReader, | 441 | br: *BufferedReader, |
| 410 | allocator: Allocator, | 442 | allocator: Allocator, |
| 411 | Elem: type, | 443 | comptime Elem: type, |
| 412 | len: usize, | 444 | len: usize, |
| 413 | endian: std.builtin.Endian, | 445 | endian: std.builtin.Endian, |
| 414 | ) ReadAllocError![]Elem { | 446 | ) ReadAllocError![]Elem { |
| 415 | const dest = try allocator.alloc(Elem, len); | 447 | const dest = try allocator.alloc(Elem, len); |
| 416 | errdefer allocator.free(dest); | 448 | errdefer allocator.free(dest); |
| 417 | try readSlice(br, @ptrCast(dest)); | 449 | try readSlice(br, @ptrCast(dest)); |
| 418 | if (native_endian != endian) std.mem.byteSwapAllFields(Elem, dest); | 450 | if (native_endian != endian) for (dest) |*elem| std.mem.byteSwapAllFields(Elem, elem); |
| 419 | return dest; | 451 | return dest; |
| 420 | } | 452 | } |
| 421 | 453 |
lib/std/io/BufferedWriter.zig+37-3| ... | @@ -58,6 +58,10 @@ pub fn initFixed(bw: *BufferedWriter, buffer: []u8) void { | ... | @@ -58,6 +58,10 @@ pub fn initFixed(bw: *BufferedWriter, buffer: []u8) void { |
| 58 | }; | 58 | }; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | pub fn hashed(bw: *BufferedWriter, hasher: anytype) Writer.Hashed(@TypeOf(hasher)) { | ||
| 62 | return .{ .out = bw, .hasher = hasher }; | ||
| 63 | } | ||
| 64 | |||
| 61 | /// This function is available when using `initFixed`. | 65 | /// This function is available when using `initFixed`. |
| 62 | pub fn getWritten(bw: *const BufferedWriter) []u8 { | 66 | pub fn getWritten(bw: *const BufferedWriter) []u8 { |
| 63 | assert(bw.unbuffered_writer.vtable == &fixed_vtable); | 67 | assert(bw.unbuffered_writer.vtable == &fixed_vtable); |
| ... | @@ -157,7 +161,7 @@ pub fn advance(bw: *BufferedWriter, n: usize) void { | ... | @@ -157,7 +161,7 @@ pub fn advance(bw: *BufferedWriter, n: usize) void { |
| 157 | } | 161 | } |
| 158 | 162 | ||
| 159 | /// The `data` parameter is mutable because this function needs to mutate the | 163 | /// The `data` parameter is mutable because this function needs to mutate the |
| 160 | /// fields in order to handle partial writes from `Writer.VTable.writeVec`. | 164 | /// fields in order to handle partial writes from `Writer.VTable.writeSplat`. |
| 161 | pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void { | 165 | pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void { |
| 162 | var index: usize = 0; | 166 | var index: usize = 0; |
| 163 | var truncate: usize = 0; | 167 | var truncate: usize = 0; |
| ... | @@ -175,6 +179,36 @@ pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void { | ... | @@ -175,6 +179,36 @@ pub fn writeVecAll(bw: *BufferedWriter, data: [][]const u8) Writer.Error!void { |
| 175 | } | 179 | } |
| 176 | } | 180 | } |
| 177 | 181 | ||
| 182 | /// The `data` parameter is mutable because this function needs to mutate the | ||
| 183 | /// fields in order to handle partial writes from `Writer.VTable.writeSplat`. | ||
| 184 | pub fn writeSplatAll(bw: *BufferedWriter, data: [][]const u8, splat: usize) Writer.Error!void { | ||
| 185 | var index: usize = 0; | ||
| 186 | var truncate: usize = 0; | ||
| 187 | var remaining_splat = splat; | ||
| 188 | while (index + 1 < data.len) { | ||
| 189 | { | ||
| 190 | const untruncated = data[index]; | ||
| 191 | data[index] = untruncated[truncate..]; | ||
| 192 | defer data[index] = untruncated; | ||
| 193 | truncate += try bw.writeSplat(data[index..], remaining_splat); | ||
| 194 | } | ||
| 195 | while (truncate >= data[index].len) { | ||
| 196 | if (index + 1 < data.len) { | ||
| 197 | truncate -= data[index].len; | ||
| 198 | index += 1; | ||
| 199 | } else { | ||
| 200 | const last = data[data.len - 1]; | ||
| 201 | remaining_splat -= @divExact(truncate, last.len); | ||
| 202 | while (remaining_splat > 0) { | ||
| 203 | const n = try bw.writeSplat(data[data.len - 1 ..][0..1], remaining_splat); | ||
| 204 | remaining_splat -= @divExact(n, last.len); | ||
| 205 | } | ||
| 206 | return; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 178 | /// If the number of bytes to write based on `data` and `splat` fits inside | 212 | /// If the number of bytes to write based on `data` and `splat` fits inside |
| 179 | /// `unusedCapacitySlice`, this function is guaranteed to not fail, not call | 213 | /// `unusedCapacitySlice`, this function is guaranteed to not fail, not call |
| 180 | /// into the underlying writer, and return the full number of bytes. | 214 | /// into the underlying writer, and return the full number of bytes. |
| ... | @@ -443,7 +477,7 @@ pub fn splatBytesAll(bw: *BufferedWriter, bytes: []const u8, splat: usize) Write | ... | @@ -443,7 +477,7 @@ pub fn splatBytesAll(bw: *BufferedWriter, bytes: []const u8, splat: usize) Write |
| 443 | 477 | ||
| 444 | /// Writes the same slice many times, allowing short writes. | 478 | /// Writes the same slice many times, allowing short writes. |
| 445 | /// | 479 | /// |
| 446 | /// Does maximum of one underlying `Writer.VTable.writeVec`. | 480 | /// Does maximum of one underlying `Writer.VTable.writeSplat`. |
| 447 | pub fn splatBytes(bw: *BufferedWriter, bytes: []const u8, n: usize) Writer.Error!usize { | 481 | pub fn splatBytes(bw: *BufferedWriter, bytes: []const u8, n: usize) Writer.Error!usize { |
| 448 | return passthruWriteSplat(bw, &.{bytes}, n); | 482 | return passthruWriteSplat(bw, &.{bytes}, n); |
| 449 | } | 483 | } |
| ... | @@ -621,7 +655,7 @@ pub const WriteFileOptions = struct { | ... | @@ -621,7 +655,7 @@ pub const WriteFileOptions = struct { |
| 621 | /// size here will save one syscall. | 655 | /// size here will save one syscall. |
| 622 | limit: Writer.Limit = .unlimited, | 656 | limit: Writer.Limit = .unlimited, |
| 623 | /// Headers and trailers must be passed together so that in case `len` is | 657 | /// Headers and trailers must be passed together so that in case `len` is |
| 624 | /// zero, they can be forwarded directly to `Writer.VTable.writeVec`. | 658 | /// zero, they can be forwarded directly to `Writer.VTable.writeSplat`. |
| 625 | /// | 659 | /// |
| 626 | /// The parameter is mutable because this function needs to mutate the | 660 | /// The parameter is mutable because this function needs to mutate the |
| 627 | /// fields in order to handle partial writes from `Writer.VTable.writeFile`. | 661 | /// fields in order to handle partial writes from `Writer.VTable.writeFile`. |
lib/std/io/Reader.zig+68| ... | @@ -331,3 +331,71 @@ test "readAlloc when the backing reader provides one byte at a time" { | ... | @@ -331,3 +331,71 @@ test "readAlloc when the backing reader provides one byte at a time" { |
| 331 | defer std.testing.allocator.free(res); | 331 | defer std.testing.allocator.free(res); |
| 332 | try std.testing.expectEqualStrings(str, res); | 332 | try std.testing.expectEqualStrings(str, res); |
| 333 | } | 333 | } |
| 334 | |||
| 335 | /// Provides a `Reader` implementation by passing data from an underlying | ||
| 336 | /// reader through `Hasher.update`. | ||
| 337 | /// | ||
| 338 | /// The underlying reader is best unbuffered. | ||
| 339 | /// | ||
| 340 | /// This implementation makes suboptimal buffering decisions due to being | ||
| 341 | /// generic. A better solution will involve creating a reader for each hash | ||
| 342 | /// function, where the discard buffer can be tailored to the hash | ||
| 343 | /// implementation details. | ||
| 344 | pub fn Hashed(comptime Hasher: type) type { | ||
| 345 | return struct { | ||
| 346 | in: *BufferedReader, | ||
| 347 | hasher: Hasher, | ||
| 348 | |||
| 349 | pub fn readable(this: *@This(), buffer: []u8) BufferedReader { | ||
| 350 | return .{ | ||
| 351 | .unbuffered_reader = .{ | ||
| 352 | .context = this, | ||
| 353 | .vtable = &.{ | ||
| 354 | .read = @This().read, | ||
| 355 | .readVec = @This().readVec, | ||
| 356 | .discard = @This().discard, | ||
| 357 | }, | ||
| 358 | }, | ||
| 359 | .buffer = buffer, | ||
| 360 | .end = 0, | ||
| 361 | .seek = 0, | ||
| 362 | }; | ||
| 363 | } | ||
| 364 | |||
| 365 | fn read(context: ?*anyopaque, bw: *BufferedWriter, limit: Limit) RwError!usize { | ||
| 366 | const this: *@This() = @alignCast(@ptrCast(context)); | ||
| 367 | const slice = limit.slice(try bw.writableSliceGreedy(1)); | ||
| 368 | const n = try this.in.readVec(&.{slice}); | ||
| 369 | this.hasher.update(slice[0..n]); | ||
| 370 | bw.advance(n); | ||
| 371 | return n; | ||
| 372 | } | ||
| 373 | |||
| 374 | fn discard(context: ?*anyopaque, limit: Limit) Error!usize { | ||
| 375 | const this: *@This() = @alignCast(@ptrCast(context)); | ||
| 376 | var bw = this.hasher.writable(&.{}); | ||
| 377 | const n = this.in.read(&bw, limit) catch |err| switch (err) { | ||
| 378 | error.WriteFailed => unreachable, | ||
| 379 | else => |e| return e, | ||
| 380 | }; | ||
| 381 | return n; | ||
| 382 | } | ||
| 383 | |||
| 384 | fn readVec(context: ?*anyopaque, data: []const []u8) Error!usize { | ||
| 385 | const this: *@This() = @alignCast(@ptrCast(context)); | ||
| 386 | const n = try this.in.readVec(data); | ||
| 387 | var remaining: usize = n; | ||
| 388 | for (data) |slice| { | ||
| 389 | if (remaining < slice.len) { | ||
| 390 | this.hasher.update(slice[0..remaining]); | ||
| 391 | return n; | ||
| 392 | } else { | ||
| 393 | remaining -= slice.len; | ||
| 394 | this.hasher.update(slice); | ||
| 395 | } | ||
| 396 | } | ||
| 397 | assert(remaining == 0); | ||
| 398 | return n; | ||
| 399 | } | ||
| 400 | }; | ||
| 401 | } |
lib/std/io/Writer.zig+84-4| ... | @@ -136,8 +136,8 @@ pub fn failingWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: | ... | @@ -136,8 +136,8 @@ pub fn failingWriteSplat(context: ?*anyopaque, data: []const []const u8, splat: |
| 136 | pub fn failingWriteFile( | 136 | pub fn failingWriteFile( |
| 137 | context: ?*anyopaque, | 137 | context: ?*anyopaque, |
| 138 | file: std.fs.File, | 138 | file: std.fs.File, |
| 139 | offset: std.io.Writer.Offset, | 139 | offset: Offset, |
| 140 | limit: std.io.Writer.Limit, | 140 | limit: Limit, |
| 141 | headers_and_trailers: []const []const u8, | 141 | headers_and_trailers: []const []const u8, |
| 142 | headers_len: usize, | 142 | headers_len: usize, |
| 143 | ) FileError!usize { | 143 | ) FileError!usize { |
| ... | @@ -158,11 +158,13 @@ pub const failing: Writer = .{ | ... | @@ -158,11 +158,13 @@ pub const failing: Writer = .{ |
| 158 | }, | 158 | }, |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | /// For use when the `Writer` implementation can cannot offer a more efficient | ||
| 162 | /// implementation than a basic read/write loop on the file. | ||
| 161 | pub fn unimplementedWriteFile( | 163 | pub fn unimplementedWriteFile( |
| 162 | context: ?*anyopaque, | 164 | context: ?*anyopaque, |
| 163 | file: std.fs.File, | 165 | file: std.fs.File, |
| 164 | offset: std.io.Writer.Offset, | 166 | offset: Offset, |
| 165 | limit: std.io.Writer.Limit, | 167 | limit: Limit, |
| 166 | headers_and_trailers: []const []const u8, | 168 | headers_and_trailers: []const []const u8, |
| 167 | headers_len: usize, | 169 | headers_len: usize, |
| 168 | ) FileError!usize { | 170 | ) FileError!usize { |
| ... | @@ -175,6 +177,84 @@ pub fn unimplementedWriteFile( | ... | @@ -175,6 +177,84 @@ pub fn unimplementedWriteFile( |
| 175 | return error.Unimplemented; | 177 | return error.Unimplemented; |
| 176 | } | 178 | } |
| 177 | 179 | ||
| 180 | /// Provides a `Writer` implementation based on calling `Hasher.update`, sending | ||
| 181 | /// all data also to an underlying `std.io.BufferedWriter`. | ||
| 182 | /// | ||
| 183 | /// When using this, the underlying writer is best unbuffered because all | ||
| 184 | /// writes are passed on directly to it. | ||
| 185 | /// | ||
| 186 | /// This implementation makes suboptimal buffering decisions due to being | ||
| 187 | /// generic. A better solution will involve creating a writer for each hash | ||
| 188 | /// function, where the splat buffer can be tailored to the hash implementation | ||
| 189 | /// details. | ||
| 190 | pub fn Hashed(comptime Hasher: type) type { | ||
| 191 | return struct { | ||
| 192 | out: *std.io.BufferedWriter, | ||
| 193 | hasher: Hasher, | ||
| 194 | |||
| 195 | pub fn writable(this: *@This(), buffer: []u8) std.io.BufferedWriter { | ||
| 196 | return .{ | ||
| 197 | .unbuffered_writer = .{ | ||
| 198 | .context = this, | ||
| 199 | .vtable = &.{ | ||
| 200 | .writeSplat = @This().writeSplat, | ||
| 201 | .writeFile = Writer.unimplementedWriteFile, | ||
| 202 | }, | ||
| 203 | }, | ||
| 204 | .buffer = buffer, | ||
| 205 | }; | ||
| 206 | } | ||
| 207 | |||
| 208 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { | ||
| 209 | const this: *@This() = @alignCast(@ptrCast(context)); | ||
| 210 | const n = try this.out.writeSplat(data, splat); | ||
| 211 | const short_data = data[0 .. data.len - @intFromBool(splat == 0)]; | ||
| 212 | var remaining: usize = n; | ||
| 213 | for (short_data) |slice| { | ||
| 214 | if (remaining < slice.len) { | ||
| 215 | this.hasher.update(slice[0..remaining]); | ||
| 216 | return n; | ||
| 217 | } else { | ||
| 218 | remaining -= slice.len; | ||
| 219 | this.hasher.update(slice); | ||
| 220 | } | ||
| 221 | } | ||
| 222 | const remaining_splat = switch (splat) { | ||
| 223 | 0, 1 => { | ||
| 224 | assert(remaining == 0); | ||
| 225 | return n; | ||
| 226 | }, | ||
| 227 | else => splat - 1, | ||
| 228 | }; | ||
| 229 | const last = data[data.len - 1]; | ||
| 230 | assert(remaining == remaining_splat * last.len); | ||
| 231 | switch (last.len) { | ||
| 232 | 0 => { | ||
| 233 | assert(remaining == 0); | ||
| 234 | return n; | ||
| 235 | }, | ||
| 236 | 1 => { | ||
| 237 | var buffer: [64]u8 = undefined; | ||
| 238 | @memset(&buffer, last[0]); | ||
| 239 | while (remaining > 0) { | ||
| 240 | const update_len = @min(remaining, buffer.len); | ||
| 241 | this.hasher.update(buffer[0..update_len]); | ||
| 242 | remaining -= update_len; | ||
| 243 | } | ||
| 244 | return n; | ||
| 245 | }, | ||
| 246 | else => {}, | ||
| 247 | } | ||
| 248 | while (remaining > 0) { | ||
| 249 | const update_len = @min(remaining, last.len); | ||
| 250 | this.hasher.update(last[0..update_len]); | ||
| 251 | remaining -= update_len; | ||
| 252 | } | ||
| 253 | return n; | ||
| 254 | } | ||
| 255 | }; | ||
| 256 | } | ||
| 257 | |||
| 178 | test { | 258 | test { |
| 179 | _ = Null; | 259 | _ = Null; |
| 180 | } | 260 | } |
lib/std/io/Writer/Null.zig+4| ... | @@ -19,6 +19,10 @@ pub fn writer(nw: *NullWriter) Writer { | ... | @@ -19,6 +19,10 @@ pub fn writer(nw: *NullWriter) Writer { |
| 19 | }; | 19 | }; |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | pub fn writable(nw: *NullWriter, buffer: []u8) std.io.BufferedWriter { | ||
| 23 | return writer(nw).buffered(buffer); | ||
| 24 | } | ||
| 25 | |||
| 22 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { | 26 | fn writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize) Writer.Error!usize { |
| 23 | _ = context; | 27 | _ = context; |
| 24 | const headers = data[0 .. data.len - 1]; | 28 | const headers = data[0 .. data.len - 1]; |
lib/std/mem.zig+3-1| ... | @@ -2196,7 +2196,9 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { | ... | @@ -2196,7 +2196,9 @@ pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { |
| 2196 | } | 2196 | } |
| 2197 | } | 2197 | } |
| 2198 | }, | 2198 | }, |
| 2199 | else => @compileError("byteSwapAllFields expects a struct or array as the first argument"), | 2199 | else => { |
| 2200 | ptr.* = @byteSwap(ptr.*); | ||
| 2201 | }, | ||
| 2200 | } | 2202 | } |
| 2201 | } | 2203 | } |
| 2202 | 2204 |
src/Package/Fetch/git.zig+179-158| ... | @@ -11,6 +11,7 @@ const Allocator = mem.Allocator; | ... | @@ -11,6 +11,7 @@ const Allocator = mem.Allocator; |
| 11 | const Sha1 = std.crypto.hash.Sha1; | 11 | const Sha1 = std.crypto.hash.Sha1; |
| 12 | const Sha256 = std.crypto.hash.sha2.Sha256; | 12 | const Sha256 = std.crypto.hash.sha2.Sha256; |
| 13 | const assert = std.debug.assert; | 13 | const assert = std.debug.assert; |
| 14 | const zlib = std.compress.zlib; | ||
| 14 | 15 | ||
| 15 | /// The ID of a Git object. | 16 | /// The ID of a Git object. |
| 16 | pub const Oid = union(Format) { | 17 | pub const Oid = union(Format) { |
| ... | @@ -52,7 +53,6 @@ pub const Oid = union(Format) { | ... | @@ -52,7 +53,6 @@ pub const Oid = union(Format) { |
| 52 | }; | 53 | }; |
| 53 | } | 54 | } |
| 54 | 55 | ||
| 55 | // Must be public for use from HashedReader and HashedWriter. | ||
| 56 | pub fn update(hasher: *Hasher, b: []const u8) void { | 56 | pub fn update(hasher: *Hasher, b: []const u8) void { |
| 57 | switch (hasher.*) { | 57 | switch (hasher.*) { |
| 58 | inline else => |*inner| inner.update(b), | 58 | inline else => |*inner| inner.update(b), |
| ... | @@ -64,6 +64,12 @@ pub const Oid = union(Format) { | ... | @@ -64,6 +64,12 @@ pub const Oid = union(Format) { |
| 64 | inline else => |*inner, tag| @unionInit(Oid, @tagName(tag), inner.finalResult()), | 64 | inline else => |*inner, tag| @unionInit(Oid, @tagName(tag), inner.finalResult()), |
| 65 | }; | 65 | }; |
| 66 | } | 66 | } |
| 67 | |||
| 68 | pub fn writable(hasher: *Hasher, buffer: []u8) std.io.BufferedWriter { | ||
| 69 | return switch (hasher.*) { | ||
| 70 | inline else => |*inner| inner.writable(buffer), | ||
| 71 | }; | ||
| 72 | } | ||
| 67 | }; | 73 | }; |
| 68 | 74 | ||
| 69 | pub fn fromBytes(oid_format: Format, bytes: []const u8) Oid { | 75 | pub fn fromBytes(oid_format: Format, bytes: []const u8) Oid { |
| ... | @@ -73,9 +79,18 @@ pub const Oid = union(Format) { | ... | @@ -73,9 +79,18 @@ pub const Oid = union(Format) { |
| 73 | }; | 79 | }; |
| 74 | } | 80 | } |
| 75 | 81 | ||
| 76 | pub fn readBytes(oid_format: Format, reader: anytype) @TypeOf(reader).NoEofError!Oid { | 82 | pub fn readBytes(oid_format: Format, reader: *std.io.BufferedReader) std.io.Reader.Error!Oid { |
| 77 | return switch (oid_format) { | 83 | return switch (oid_format) { |
| 78 | inline else => |tag| @unionInit(Oid, @tagName(tag), try reader.readBytesNoEof(tag.byteLength())), | 84 | .sha1 => { |
| 85 | var result: Oid = .{ .sha1 = undefined }; | ||
| 86 | try reader.readSlice(&result.sha1); | ||
| 87 | return result; | ||
| 88 | }, | ||
| 89 | .sha256 => { | ||
| 90 | var result: Oid = .{ .sha256 = undefined }; | ||
| 91 | try reader.readSlice(&result.sha256); | ||
| 92 | return result; | ||
| 93 | }, | ||
| 79 | }; | 94 | }; |
| 80 | } | 95 | } |
| 81 | 96 | ||
| ... | @@ -167,8 +182,15 @@ pub const Diagnostics = struct { | ... | @@ -167,8 +182,15 @@ pub const Diagnostics = struct { |
| 167 | pub const Repository = struct { | 182 | pub const Repository = struct { |
| 168 | odb: Odb, | 183 | odb: Odb, |
| 169 | 184 | ||
| 170 | pub fn init(allocator: Allocator, format: Oid.Format, pack_file: std.fs.File, index_file: std.fs.File) !Repository { | 185 | pub fn init( |
| 171 | return .{ .odb = try Odb.init(allocator, format, pack_file, index_file) }; | 186 | repo: *Repository, |
| 187 | allocator: Allocator, | ||
| 188 | format: Oid.Format, | ||
| 189 | pack_file: *std.fs.File.Reader, | ||
| 190 | index_file: *std.fs.File.Reader, | ||
| 191 | ) !void { | ||
| 192 | repo.* = .{ .odb = undefined }; | ||
| 193 | try repo.odb.init(allocator, format, pack_file, index_file); | ||
| 172 | } | 194 | } |
| 173 | 195 | ||
| 174 | pub fn deinit(repository: *Repository) void { | 196 | pub fn deinit(repository: *Repository) void { |
| ... | @@ -337,24 +359,32 @@ pub const Repository = struct { | ... | @@ -337,24 +359,32 @@ pub const Repository = struct { |
| 337 | /// [pack-format](https://git-scm.com/docs/pack-format). | 359 | /// [pack-format](https://git-scm.com/docs/pack-format). |
| 338 | const Odb = struct { | 360 | const Odb = struct { |
| 339 | format: Oid.Format, | 361 | format: Oid.Format, |
| 340 | pack_file: std.fs.File, | 362 | pack_file: *std.fs.File.Reader, |
| 341 | index_header: IndexHeader, | 363 | index_header: IndexHeader, |
| 342 | index_file: std.fs.File, | 364 | index_file: *std.fs.File.Reader, |
| 343 | cache: ObjectCache = .{}, | 365 | cache: ObjectCache = .{}, |
| 344 | allocator: Allocator, | 366 | allocator: Allocator, |
| 345 | 367 | ||
| 346 | /// Initializes the database from open pack and index files. | 368 | /// Initializes the database from open pack and index files. |
| 347 | fn init(allocator: Allocator, format: Oid.Format, pack_file: std.fs.File, index_file: std.fs.File) !Odb { | 369 | fn init( |
| 370 | odb: *Odb, | ||
| 371 | allocator: Allocator, | ||
| 372 | format: Oid.Format, | ||
| 373 | pack_file: *std.fs.File.Reader, | ||
| 374 | index_file: *std.fs.File.Reader, | ||
| 375 | ) !void { | ||
| 348 | try pack_file.seekTo(0); | 376 | try pack_file.seekTo(0); |
| 349 | try index_file.seekTo(0); | 377 | try index_file.seekTo(0); |
| 350 | const index_header = try IndexHeader.read(index_file.reader()); | 378 | odb.* = .{ |
| 351 | return .{ | ||
| 352 | .format = format, | 379 | .format = format, |
| 353 | .pack_file = pack_file, | 380 | .pack_file = pack_file, |
| 354 | .index_header = index_header, | 381 | .index_header = undefined, |
| 355 | .index_file = index_file, | 382 | .index_file = index_file, |
| 356 | .allocator = allocator, | 383 | .allocator = allocator, |
| 357 | }; | 384 | }; |
| 385 | var buffer: [1032]u8 = undefined; | ||
| 386 | var index_file_br = index_file.readable(&buffer); | ||
| 387 | try odb.index_header.read(&index_file_br); | ||
| 358 | } | 388 | } |
| 359 | 389 | ||
| 360 | fn deinit(odb: *Odb) void { | 390 | fn deinit(odb: *Odb) void { |
| ... | @@ -364,27 +394,30 @@ const Odb = struct { | ... | @@ -364,27 +394,30 @@ const Odb = struct { |
| 364 | 394 | ||
| 365 | /// Reads the object at the current position in the database. | 395 | /// Reads the object at the current position in the database. |
| 366 | fn readObject(odb: *Odb) !Object { | 396 | fn readObject(odb: *Odb) !Object { |
| 367 | var base_offset = try odb.pack_file.getPos(); | 397 | var pack_read_buffer: [64]u8 = undefined; |
| 398 | var base_offset = odb.pack_file.pos; | ||
| 399 | var pack_br = odb.pack_file.readable(&pack_read_buffer); | ||
| 368 | var base_header: EntryHeader = undefined; | 400 | var base_header: EntryHeader = undefined; |
| 369 | var delta_offsets: std.ArrayListUnmanaged(u64) = .empty; | 401 | var delta_offsets: std.ArrayListUnmanaged(u64) = .empty; |
| 370 | defer delta_offsets.deinit(odb.allocator); | 402 | defer delta_offsets.deinit(odb.allocator); |
| 371 | const base_object = while (true) { | 403 | const base_object = while (true) { |
| 372 | if (odb.cache.get(base_offset)) |base_object| break base_object; | 404 | if (odb.cache.get(base_offset)) |base_object| break base_object; |
| 373 | 405 | ||
| 374 | base_header = try EntryHeader.read(odb.format, odb.pack_file.reader()); | 406 | base_header = try EntryHeader.read(odb.format, &pack_br); |
| 375 | switch (base_header) { | 407 | switch (base_header) { |
| 376 | .ofs_delta => |ofs_delta| { | 408 | .ofs_delta => |ofs_delta| { |
| 377 | try delta_offsets.append(odb.allocator, base_offset); | 409 | try delta_offsets.append(odb.allocator, base_offset); |
| 378 | base_offset = std.math.sub(u64, base_offset, ofs_delta.offset) catch return error.InvalidFormat; | 410 | base_offset = std.math.sub(u64, base_offset, ofs_delta.offset) catch return error.InvalidFormat; |
| 379 | try odb.pack_file.seekTo(base_offset); | 411 | try odb.pack_file.seekTo(base_offset); |
| 412 | pack_br = odb.pack_file.readable(&pack_read_buffer); | ||
| 380 | }, | 413 | }, |
| 381 | .ref_delta => |ref_delta| { | 414 | .ref_delta => |ref_delta| { |
| 382 | try delta_offsets.append(odb.allocator, base_offset); | 415 | try delta_offsets.append(odb.allocator, base_offset); |
| 383 | try odb.seekOid(ref_delta.base_object); | 416 | try odb.seekOid(ref_delta.base_object); |
| 384 | base_offset = try odb.pack_file.getPos(); | 417 | base_offset = odb.pack_file.pos - pack_br.bufferedLen(); |
| 385 | }, | 418 | }, |
| 386 | else => { | 419 | else => { |
| 387 | const base_data = try readObjectRaw(odb.allocator, odb.pack_file.reader(), base_header.uncompressedLength()); | 420 | const base_data = try readObjectRaw(odb.allocator, &pack_br, base_header.uncompressedLength()); |
| 388 | errdefer odb.allocator.free(base_data); | 421 | errdefer odb.allocator.free(base_data); |
| 389 | const base_object: Object = .{ .type = base_header.objectType(), .data = base_data }; | 422 | const base_object: Object = .{ .type = base_header.objectType(), .data = base_data }; |
| 390 | try odb.cache.put(odb.allocator, base_offset, base_object); | 423 | try odb.cache.put(odb.allocator, base_offset, base_object); |
| ... | @@ -414,7 +447,8 @@ const Odb = struct { | ... | @@ -414,7 +447,8 @@ const Odb = struct { |
| 414 | const found_index = while (start_index < end_index) { | 447 | const found_index = while (start_index < end_index) { |
| 415 | const mid_index = start_index + (end_index - start_index) / 2; | 448 | const mid_index = start_index + (end_index - start_index) / 2; |
| 416 | try odb.index_file.seekTo(IndexHeader.size + mid_index * oid_length); | 449 | try odb.index_file.seekTo(IndexHeader.size + mid_index * oid_length); |
| 417 | const mid_oid = try Oid.readBytes(odb.format, odb.index_file.reader()); | 450 | var br = odb.index_file.interface().unbuffered(); |
| 451 | const mid_oid = try Oid.readBytes(odb.format, &br); | ||
| 418 | switch (mem.order(u8, mid_oid.slice(), oid.slice())) { | 452 | switch (mem.order(u8, mid_oid.slice(), oid.slice())) { |
| 419 | .lt => start_index = mid_index + 1, | 453 | .lt => start_index = mid_index + 1, |
| 420 | .gt => end_index = mid_index, | 454 | .gt => end_index = mid_index, |
| ... | @@ -424,13 +458,16 @@ const Odb = struct { | ... | @@ -424,13 +458,16 @@ const Odb = struct { |
| 424 | 458 | ||
| 425 | const n_objects = odb.index_header.fan_out_table[255]; | 459 | const n_objects = odb.index_header.fan_out_table[255]; |
| 426 | const offset_values_start = IndexHeader.size + n_objects * (oid_length + 4); | 460 | const offset_values_start = IndexHeader.size + n_objects * (oid_length + 4); |
| 461 | var buffer: [8]u8 = undefined; | ||
| 427 | try odb.index_file.seekTo(offset_values_start + found_index * 4); | 462 | try odb.index_file.seekTo(offset_values_start + found_index * 4); |
| 428 | const l1_offset: packed struct { value: u31, big: bool } = @bitCast(try odb.index_file.reader().readInt(u32, .big)); | 463 | var br = odb.index_file.interface().buffered(&buffer); |
| 464 | const l1_offset: packed struct { value: u31, big: bool } = @bitCast(try br.takeInt(u32, .big)); | ||
| 429 | const pack_offset = pack_offset: { | 465 | const pack_offset = pack_offset: { |
| 430 | if (l1_offset.big) { | 466 | if (l1_offset.big) { |
| 431 | const l2_offset_values_start = offset_values_start + n_objects * 4; | 467 | const l2_offset_values_start = offset_values_start + n_objects * 4; |
| 432 | try odb.index_file.seekTo(l2_offset_values_start + l1_offset.value * 4); | 468 | try odb.index_file.seekTo(l2_offset_values_start + l1_offset.value * 4); |
| 433 | break :pack_offset try odb.index_file.reader().readInt(u64, .big); | 469 | br = odb.index_file.interface().buffered(&buffer); |
| 470 | break :pack_offset try br.takeInt(u64, .big); | ||
| 434 | } else { | 471 | } else { |
| 435 | break :pack_offset l1_offset.value; | 472 | break :pack_offset l1_offset.value; |
| 436 | } | 473 | } |
| ... | @@ -556,7 +593,7 @@ const Packet = union(enum) { | ... | @@ -556,7 +593,7 @@ const Packet = union(enum) { |
| 556 | const max_data_length = 65516; | 593 | const max_data_length = 65516; |
| 557 | 594 | ||
| 558 | /// Reads a packet in pkt-line format. | 595 | /// Reads a packet in pkt-line format. |
| 559 | fn read(reader: anytype, buf: *[max_data_length]u8) !Packet { | 596 | fn read(reader: *std.io.BufferedReader, buf: *[max_data_length]u8) !Packet { |
| 560 | const length = std.fmt.parseUnsigned(u16, &try reader.readBytesNoEof(4), 16) catch return error.InvalidPacket; | 597 | const length = std.fmt.parseUnsigned(u16, &try reader.readBytesNoEof(4), 16) catch return error.InvalidPacket; |
| 561 | switch (length) { | 598 | switch (length) { |
| 562 | 0 => return .flush, | 599 | 0 => return .flush, |
| ... | @@ -571,7 +608,7 @@ const Packet = union(enum) { | ... | @@ -571,7 +608,7 @@ const Packet = union(enum) { |
| 571 | } | 608 | } |
| 572 | 609 | ||
| 573 | /// Writes a packet in pkt-line format. | 610 | /// Writes a packet in pkt-line format. |
| 574 | fn write(packet: Packet, writer: anytype) !void { | 611 | fn write(packet: Packet, writer: *std.io.BufferedWriter) !void { |
| 575 | switch (packet) { | 612 | switch (packet) { |
| 576 | .flush => try writer.writeAll("0000"), | 613 | .flush => try writer.writeAll("0000"), |
| 577 | .delimiter => try writer.writeAll("0001"), | 614 | .delimiter => try writer.writeAll("0001"), |
| ... | @@ -1070,21 +1107,12 @@ const PackHeader = struct { | ... | @@ -1070,21 +1107,12 @@ const PackHeader = struct { |
| 1070 | const signature = "PACK"; | 1107 | const signature = "PACK"; |
| 1071 | const supported_version = 2; | 1108 | const supported_version = 2; |
| 1072 | 1109 | ||
| 1073 | fn read(reader: anytype) !PackHeader { | 1110 | fn read(reader: *std.io.BufferedReader) !PackHeader { |
| 1074 | const actual_signature = reader.readBytesNoEof(4) catch |e| switch (e) { | 1111 | const actual_signature = try reader.take(4); |
| 1075 | error.EndOfStream => return error.InvalidHeader, | 1112 | if (!mem.eql(u8, actual_signature, signature)) return error.InvalidHeader; |
| 1076 | else => |other| return other, | 1113 | const version = try reader.takeInt(u32, .big); |
| 1077 | }; | ||
| 1078 | if (!mem.eql(u8, &actual_signature, signature)) return error.InvalidHeader; | ||
| 1079 | const version = reader.readInt(u32, .big) catch |e| switch (e) { | ||
| 1080 | error.EndOfStream => return error.InvalidHeader, | ||
| 1081 | else => |other| return other, | ||
| 1082 | }; | ||
| 1083 | if (version != supported_version) return error.UnsupportedVersion; | 1114 | if (version != supported_version) return error.UnsupportedVersion; |
| 1084 | const total_objects = reader.readInt(u32, .big) catch |e| switch (e) { | 1115 | const total_objects = try reader.takeInt(u32, .big); |
| 1085 | error.EndOfStream => return error.InvalidHeader, | ||
| 1086 | else => |other| return other, | ||
| 1087 | }; | ||
| 1088 | return .{ .total_objects = total_objects }; | 1116 | return .{ .total_objects = total_objects }; |
| 1089 | } | 1117 | } |
| 1090 | }; | 1118 | }; |
| ... | @@ -1133,12 +1161,9 @@ const EntryHeader = union(Type) { | ... | @@ -1133,12 +1161,9 @@ const EntryHeader = union(Type) { |
| 1133 | }; | 1161 | }; |
| 1134 | } | 1162 | } |
| 1135 | 1163 | ||
| 1136 | fn read(format: Oid.Format, reader: anytype) !EntryHeader { | 1164 | fn read(format: Oid.Format, reader: *std.io.BufferedReader) !EntryHeader { |
| 1137 | const InitialByte = packed struct { len: u4, type: u3, has_next: bool }; | 1165 | const InitialByte = packed struct { len: u4, type: u3, has_next: bool }; |
| 1138 | const initial: InitialByte = @bitCast(reader.readByte() catch |e| switch (e) { | 1166 | const initial: InitialByte = @bitCast(try reader.takeByte()); |
| 1139 | error.EndOfStream => return error.InvalidFormat, | ||
| 1140 | else => |other| return other, | ||
| 1141 | }); | ||
| 1142 | const rest_len = if (initial.has_next) try readSizeVarInt(reader) else 0; | 1167 | const rest_len = if (initial.has_next) try readSizeVarInt(reader) else 0; |
| 1143 | var uncompressed_length: u64 = initial.len; | 1168 | var uncompressed_length: u64 = initial.len; |
| 1144 | uncompressed_length |= std.math.shlExact(u64, rest_len, 4) catch return error.InvalidFormat; | 1169 | uncompressed_length |= std.math.shlExact(u64, rest_len, 4) catch return error.InvalidFormat; |
| ... | @@ -1162,25 +1187,25 @@ const EntryHeader = union(Type) { | ... | @@ -1162,25 +1187,25 @@ const EntryHeader = union(Type) { |
| 1162 | } | 1187 | } |
| 1163 | }; | 1188 | }; |
| 1164 | 1189 | ||
| 1165 | fn readSizeVarInt(r: anytype) !u64 { | 1190 | fn readSizeVarInt(r: *std.io.BufferedReader) !u64 { |
| 1166 | const Byte = packed struct { value: u7, has_next: bool }; | 1191 | const Byte = packed struct { value: u7, has_next: bool }; |
| 1167 | var b: Byte = @bitCast(try r.readByte()); | 1192 | var b: Byte = @bitCast(try r.takeByte()); |
| 1168 | var value: u64 = b.value; | 1193 | var value: u64 = b.value; |
| 1169 | var shift: u6 = 0; | 1194 | var shift: u6 = 0; |
| 1170 | while (b.has_next) { | 1195 | while (b.has_next) { |
| 1171 | b = @bitCast(try r.readByte()); | 1196 | b = @bitCast(try r.takeByte()); |
| 1172 | shift = std.math.add(u6, shift, 7) catch return error.InvalidFormat; | 1197 | shift = std.math.add(u6, shift, 7) catch return error.InvalidFormat; |
| 1173 | value |= @as(u64, b.value) << shift; | 1198 | value |= @as(u64, b.value) << shift; |
| 1174 | } | 1199 | } |
| 1175 | return value; | 1200 | return value; |
| 1176 | } | 1201 | } |
| 1177 | 1202 | ||
| 1178 | fn readOffsetVarInt(r: anytype) !u64 { | 1203 | fn readOffsetVarInt(r: *std.io.BufferedReader) !u64 { |
| 1179 | const Byte = packed struct { value: u7, has_next: bool }; | 1204 | const Byte = packed struct { value: u7, has_next: bool }; |
| 1180 | var b: Byte = @bitCast(try r.readByte()); | 1205 | var b: Byte = @bitCast(try r.takeByte()); |
| 1181 | var value: u64 = b.value; | 1206 | var value: u64 = b.value; |
| 1182 | while (b.has_next) { | 1207 | while (b.has_next) { |
| 1183 | b = @bitCast(try r.readByte()); | 1208 | b = @bitCast(try r.takeByte()); |
| 1184 | value = std.math.shlExact(u64, value + 1, 7) catch return error.InvalidFormat; | 1209 | value = std.math.shlExact(u64, value + 1, 7) catch return error.InvalidFormat; |
| 1185 | value |= b.value; | 1210 | value |= b.value; |
| 1186 | } | 1211 | } |
| ... | @@ -1194,19 +1219,12 @@ const IndexHeader = struct { | ... | @@ -1194,19 +1219,12 @@ const IndexHeader = struct { |
| 1194 | const supported_version = 2; | 1219 | const supported_version = 2; |
| 1195 | const size = 4 + 4 + @sizeOf([256]u32); | 1220 | const size = 4 + 4 + @sizeOf([256]u32); |
| 1196 | 1221 | ||
| 1197 | fn read(reader: anytype) !IndexHeader { | 1222 | fn read(index_header: *IndexHeader, br: *std.io.BufferedReader) !void { |
| 1198 | var header_bytes = try reader.readBytesNoEof(size); | 1223 | const sig = try br.take(4); |
| 1199 | if (!mem.eql(u8, header_bytes[0..4], signature)) return error.InvalidHeader; | 1224 | if (!mem.eql(u8, sig, signature)) return error.InvalidHeader; |
| 1200 | const version = mem.readInt(u32, header_bytes[4..8], .big); | 1225 | const version = try br.takeInt(u32, .big); |
| 1201 | if (version != supported_version) return error.UnsupportedVersion; | 1226 | if (version != supported_version) return error.UnsupportedVersion; |
| 1202 | 1227 | try br.readSliceEndian(u32, &index_header.fan_out_table, .big); | |
| 1203 | var fan_out_table: [256]u32 = undefined; | ||
| 1204 | var fan_out_table_stream = std.io.fixedBufferStream(header_bytes[8..]); | ||
| 1205 | const fan_out_table_reader = fan_out_table_stream.reader(); | ||
| 1206 | for (&fan_out_table) |*entry| { | ||
| 1207 | entry.* = fan_out_table_reader.readInt(u32, .big) catch unreachable; | ||
| 1208 | } | ||
| 1209 | return .{ .fan_out_table = fan_out_table }; | ||
| 1210 | } | 1228 | } |
| 1211 | }; | 1229 | }; |
| 1212 | 1230 | ||
| ... | @@ -1217,7 +1235,12 @@ const IndexEntry = struct { | ... | @@ -1217,7 +1235,12 @@ const IndexEntry = struct { |
| 1217 | 1235 | ||
| 1218 | /// Writes out a version 2 index for the given packfile, as documented in | 1236 | /// Writes out a version 2 index for the given packfile, as documented in |
| 1219 | /// [pack-format](https://git-scm.com/docs/pack-format). | 1237 | /// [pack-format](https://git-scm.com/docs/pack-format). |
| 1220 | pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, index_writer: anytype) !void { | 1238 | pub fn indexPack( |
| 1239 | allocator: Allocator, | ||
| 1240 | format: Oid.Format, | ||
| 1241 | pack: *std.fs.File.Reader, | ||
| 1242 | index_writer: *std.fs.File.Writer, | ||
| 1243 | ) !void { | ||
| 1221 | try pack.seekTo(0); | 1244 | try pack.seekTo(0); |
| 1222 | 1245 | ||
| 1223 | var index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry) = .empty; | 1246 | var index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry) = .empty; |
| ... | @@ -1270,8 +1293,10 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in | ... | @@ -1270,8 +1293,10 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in |
| 1270 | } | 1293 | } |
| 1271 | @memset(fan_out_table[fan_out_index..], count); | 1294 | @memset(fan_out_table[fan_out_index..], count); |
| 1272 | 1295 | ||
| 1273 | var index_hashed_writer = std.compress.hashedWriter(index_writer, Oid.Hasher.init(format)); | 1296 | var index_writer_bw = index_writer.writable(&.{}); |
| 1274 | const writer = index_hashed_writer.writer(); | 1297 | var index_hashed_writer = index_writer_bw.hashed(Oid.Hasher.init(format)); |
| 1298 | var write_buffer: [256]u8 = undefined; | ||
| 1299 | var writer = index_hashed_writer.writable(&write_buffer); | ||
| 1275 | try writer.writeAll(IndexHeader.signature); | 1300 | try writer.writeAll(IndexHeader.signature); |
| 1276 | try writer.writeInt(u32, IndexHeader.supported_version, .big); | 1301 | try writer.writeInt(u32, IndexHeader.supported_version, .big); |
| 1277 | for (fan_out_table) |fan_out_entry| { | 1302 | for (fan_out_table) |fan_out_entry| { |
| ... | @@ -1303,8 +1328,9 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in | ... | @@ -1303,8 +1328,9 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in |
| 1303 | } | 1328 | } |
| 1304 | 1329 | ||
| 1305 | try writer.writeAll(pack_checksum.slice()); | 1330 | try writer.writeAll(pack_checksum.slice()); |
| 1331 | try writer.flush(); | ||
| 1306 | const index_checksum = index_hashed_writer.hasher.finalResult(); | 1332 | const index_checksum = index_hashed_writer.hasher.finalResult(); |
| 1307 | try index_writer.writeAll(index_checksum.slice()); | 1333 | try index_writer_bw.writeAll(index_checksum.slice()); |
| 1308 | } | 1334 | } |
| 1309 | 1335 | ||
| 1310 | /// Performs the first pass over the packfile data for index construction. | 1336 | /// Performs the first pass over the packfile data for index construction. |
| ... | @@ -1314,50 +1340,46 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in | ... | @@ -1314,50 +1340,46 @@ pub fn indexPack(allocator: Allocator, format: Oid.Format, pack: std.fs.File, in |
| 1314 | fn indexPackFirstPass( | 1340 | fn indexPackFirstPass( |
| 1315 | allocator: Allocator, | 1341 | allocator: Allocator, |
| 1316 | format: Oid.Format, | 1342 | format: Oid.Format, |
| 1317 | pack: std.fs.File, | 1343 | pack: *std.fs.File.Reader, |
| 1318 | index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry), | 1344 | index_entries: *std.AutoHashMapUnmanaged(Oid, IndexEntry), |
| 1319 | pending_deltas: *std.ArrayListUnmanaged(IndexEntry), | 1345 | pending_deltas: *std.ArrayListUnmanaged(IndexEntry), |
| 1320 | ) !Oid { | 1346 | ) !Oid { |
| 1321 | var pack_buffered_reader = std.io.bufferedReader(pack.reader()); | 1347 | var pack_br = pack.readable(&.{}); |
| 1322 | var pack_counting_reader = std.io.countingReader(pack_buffered_reader.reader()); | 1348 | var pack_hashed_reader = pack_br.hashed(Oid.Hasher.init(format)); |
| 1323 | var pack_hashed_reader = std.compress.hashedReader(pack_counting_reader.reader(), Oid.Hasher.init(format)); | 1349 | var pack_buffer: [2048]u8 = undefined; // Reasonably large buffer for file system. |
| 1324 | const pack_reader = pack_hashed_reader.reader(); | 1350 | var pack_hashed_br = pack_hashed_reader.readable(&pack_buffer); |
| 1325 | 1351 | ||
| 1326 | const pack_header = try PackHeader.read(pack_reader); | 1352 | const pack_header = try PackHeader.read(&pack_hashed_br); |
| 1327 | 1353 | ||
| 1328 | var current_entry: u32 = 0; | 1354 | for (0..pack_header.total_objects) |_| { |
| 1329 | while (current_entry < pack_header.total_objects) : (current_entry += 1) { | 1355 | const entry_offset = pack.pos - pack_hashed_br.bufferContents().len; |
| 1330 | const entry_offset = pack_counting_reader.bytes_read; | 1356 | var entry_crc32_reader = pack_hashed_br.hashed(std.hash.Crc32.init()); |
| 1331 | var entry_crc32_reader = std.compress.hashedReader(pack_reader, std.hash.Crc32.init()); | 1357 | var entry_buffer: [64]u8 = undefined; // Buffer only needed for loading EntryHeader. |
| 1332 | const entry_header = try EntryHeader.read(format, entry_crc32_reader.reader()); | 1358 | var entry_crc32_br = entry_crc32_reader.readable(&entry_buffer); |
| 1359 | const entry_header = try EntryHeader.read(format, &entry_crc32_br); | ||
| 1360 | var entry_decompress_stream: zlib.Decompressor = .init(&entry_crc32_br); | ||
| 1361 | // Decompress uses large output buffer; no input buffer needed. | ||
| 1362 | var entry_decompress_br = entry_decompress_stream.readable(&.{}); | ||
| 1333 | switch (entry_header) { | 1363 | switch (entry_header) { |
| 1334 | .commit, .tree, .blob, .tag => |object| { | 1364 | .commit, .tree, .blob, .tag => |object| { |
| 1335 | var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader()); | 1365 | var oid_hasher = Oid.Hasher.init(format); |
| 1336 | var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader()); | 1366 | var oid_hasher_buffer: [zlib.max_window_len]u8 = undefined; |
| 1337 | var entry_hashed_writer = std.compress.hashedWriter(std.io.null_writer, Oid.Hasher.init(format)); | 1367 | var oid_hasher_bw = oid_hasher.writable(&oid_hasher_buffer); |
| 1338 | const entry_writer = entry_hashed_writer.writer(); | ||
| 1339 | // The object header is not included in the pack data but is | 1368 | // The object header is not included in the pack data but is |
| 1340 | // part of the object's ID | 1369 | // part of the object's ID. |
| 1341 | try entry_writer.print("{s} {}\x00", .{ @tagName(entry_header), object.uncompressed_length }); | 1370 | try oid_hasher_bw.print("{s} {d}\x00", .{ @tagName(entry_header), object.uncompressed_length }); |
| 1342 | var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); | 1371 | const n = try entry_decompress_br.readRemaining(&oid_hasher_bw); |
| 1343 | try fifo.pump(entry_counting_reader.reader(), entry_writer); | 1372 | if (n != object.uncompressed_length) return error.InvalidObject; |
| 1344 | if (entry_counting_reader.bytes_read != object.uncompressed_length) { | 1373 | try oid_hasher_bw.flush(); |
| 1345 | return error.InvalidObject; | 1374 | const oid = oid_hasher.finalResult(); |
| 1346 | } | ||
| 1347 | const oid = entry_hashed_writer.hasher.finalResult(); | ||
| 1348 | try index_entries.put(allocator, oid, .{ | 1375 | try index_entries.put(allocator, oid, .{ |
| 1349 | .offset = entry_offset, | 1376 | .offset = entry_offset, |
| 1350 | .crc32 = entry_crc32_reader.hasher.final(), | 1377 | .crc32 = entry_crc32_reader.hasher.final(), |
| 1351 | }); | 1378 | }); |
| 1352 | }, | 1379 | }, |
| 1353 | inline .ofs_delta, .ref_delta => |delta| { | 1380 | inline .ofs_delta, .ref_delta => |delta| { |
| 1354 | var entry_decompress_stream = std.compress.zlib.decompressor(entry_crc32_reader.reader()); | 1381 | const n = try entry_decompress_br.discardRemaining(); |
| 1355 | var entry_counting_reader = std.io.countingReader(entry_decompress_stream.reader()); | 1382 | if (n != delta.uncompressed_length) return error.InvalidObject; |
| 1356 | var fifo = std.fifo.LinearFifo(u8, .{ .Static = 4096 }).init(); | ||
| 1357 | try fifo.pump(entry_counting_reader.reader(), std.io.null_writer); | ||
| 1358 | if (entry_counting_reader.bytes_read != delta.uncompressed_length) { | ||
| 1359 | return error.InvalidObject; | ||
| 1360 | } | ||
| 1361 | try pending_deltas.append(allocator, .{ | 1383 | try pending_deltas.append(allocator, .{ |
| 1362 | .offset = entry_offset, | 1384 | .offset = entry_offset, |
| 1363 | .crc32 = entry_crc32_reader.hasher.final(), | 1385 | .crc32 = entry_crc32_reader.hasher.final(), |
| ... | @@ -1367,15 +1389,11 @@ fn indexPackFirstPass( | ... | @@ -1367,15 +1389,11 @@ fn indexPackFirstPass( |
| 1367 | } | 1389 | } |
| 1368 | 1390 | ||
| 1369 | const pack_checksum = pack_hashed_reader.hasher.finalResult(); | 1391 | const pack_checksum = pack_hashed_reader.hasher.finalResult(); |
| 1370 | const recorded_checksum = try Oid.readBytes(format, pack_buffered_reader.reader()); | 1392 | const recorded_checksum = try Oid.readBytes(format, &pack_br); |
| 1371 | if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) { | 1393 | if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) { |
| 1372 | return error.CorruptedPack; | 1394 | return error.CorruptedPack; |
| 1373 | } | 1395 | } |
| 1374 | _ = pack_reader.readByte() catch |e| switch (e) { | 1396 | return pack_checksum; |
| 1375 | error.EndOfStream => return pack_checksum, | ||
| 1376 | else => |other| return other, | ||
| 1377 | }; | ||
| 1378 | return error.InvalidFormat; | ||
| 1379 | } | 1397 | } |
| 1380 | 1398 | ||
| 1381 | /// Attempts to determine the final object ID of the given deltified object. | 1399 | /// Attempts to determine the final object ID of the given deltified object. |
| ... | @@ -1384,7 +1402,7 @@ fn indexPackFirstPass( | ... | @@ -1384,7 +1402,7 @@ fn indexPackFirstPass( |
| 1384 | fn indexPackHashDelta( | 1402 | fn indexPackHashDelta( |
| 1385 | allocator: Allocator, | 1403 | allocator: Allocator, |
| 1386 | format: Oid.Format, | 1404 | format: Oid.Format, |
| 1387 | pack: std.fs.File, | 1405 | pack: *std.fs.File.Reader, |
| 1388 | delta: IndexEntry, | 1406 | delta: IndexEntry, |
| 1389 | index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry), | 1407 | index_entries: std.AutoHashMapUnmanaged(Oid, IndexEntry), |
| 1390 | cache: *ObjectCache, | 1408 | cache: *ObjectCache, |
| ... | @@ -1398,7 +1416,9 @@ fn indexPackHashDelta( | ... | @@ -1398,7 +1416,9 @@ fn indexPackHashDelta( |
| 1398 | if (cache.get(base_offset)) |base_object| break base_object; | 1416 | if (cache.get(base_offset)) |base_object| break base_object; |
| 1399 | 1417 | ||
| 1400 | try pack.seekTo(base_offset); | 1418 | try pack.seekTo(base_offset); |
| 1401 | base_header = try EntryHeader.read(format, pack.reader()); | 1419 | var pack_read_buffer: [64]u8 = undefined; |
| 1420 | var pack_br = pack.readable(&pack_read_buffer); | ||
| 1421 | base_header = try EntryHeader.read(format, &pack_br); | ||
| 1402 | switch (base_header) { | 1422 | switch (base_header) { |
| 1403 | .ofs_delta => |ofs_delta| { | 1423 | .ofs_delta => |ofs_delta| { |
| 1404 | try delta_offsets.append(allocator, base_offset); | 1424 | try delta_offsets.append(allocator, base_offset); |
| ... | @@ -1409,7 +1429,7 @@ fn indexPackHashDelta( | ... | @@ -1409,7 +1429,7 @@ fn indexPackHashDelta( |
| 1409 | base_offset = (index_entries.get(ref_delta.base_object) orelse return null).offset; | 1429 | base_offset = (index_entries.get(ref_delta.base_object) orelse return null).offset; |
| 1410 | }, | 1430 | }, |
| 1411 | else => { | 1431 | else => { |
| 1412 | const base_data = try readObjectRaw(allocator, pack.reader(), base_header.uncompressedLength()); | 1432 | const base_data = try readObjectRaw(allocator, &pack_br, base_header.uncompressedLength()); |
| 1413 | errdefer allocator.free(base_data); | 1433 | errdefer allocator.free(base_data); |
| 1414 | const base_object: Object = .{ .type = base_header.objectType(), .data = base_data }; | 1434 | const base_object: Object = .{ .type = base_header.objectType(), .data = base_data }; |
| 1415 | try cache.put(allocator, base_offset, base_object); | 1435 | try cache.put(allocator, base_offset, base_object); |
| ... | @@ -1421,9 +1441,12 @@ fn indexPackHashDelta( | ... | @@ -1421,9 +1441,12 @@ fn indexPackHashDelta( |
| 1421 | const base_data = try resolveDeltaChain(allocator, format, pack, base_object, delta_offsets.items, cache); | 1441 | const base_data = try resolveDeltaChain(allocator, format, pack, base_object, delta_offsets.items, cache); |
| 1422 | 1442 | ||
| 1423 | var entry_hasher: Oid.Hasher = .init(format); | 1443 | var entry_hasher: Oid.Hasher = .init(format); |
| 1424 | var entry_hashed_writer = std.compress.hashedWriter(std.io.null_writer, &entry_hasher); | 1444 | var entry_hasher_buffer: [64]u8 = undefined; |
| 1425 | try entry_hashed_writer.writer().print("{s} {}\x00", .{ @tagName(base_object.type), base_data.len }); | 1445 | var entry_hasher_bw = entry_hasher.writable(&entry_hasher_buffer); |
| 1426 | entry_hasher.update(base_data); | 1446 | // Writes to hashers cannot fail. |
| 1447 | entry_hasher_bw.print("{s} {d}\x00", .{ @tagName(base_object.type), base_data.len }) catch unreachable; | ||
| 1448 | entry_hasher_bw.writeAll(base_data) catch unreachable; | ||
| 1449 | entry_hasher_bw.flush() catch unreachable; | ||
| 1427 | return entry_hasher.finalResult(); | 1450 | return entry_hasher.finalResult(); |
| 1428 | } | 1451 | } |
| 1429 | 1452 | ||
| ... | @@ -1434,7 +1457,7 @@ fn indexPackHashDelta( | ... | @@ -1434,7 +1457,7 @@ fn indexPackHashDelta( |
| 1434 | fn resolveDeltaChain( | 1457 | fn resolveDeltaChain( |
| 1435 | allocator: Allocator, | 1458 | allocator: Allocator, |
| 1436 | format: Oid.Format, | 1459 | format: Oid.Format, |
| 1437 | pack: std.fs.File, | 1460 | pack: *std.fs.File.Reader, |
| 1438 | base_object: Object, | 1461 | base_object: Object, |
| 1439 | delta_offsets: []const u64, | 1462 | delta_offsets: []const u64, |
| 1440 | cache: *ObjectCache, | 1463 | cache: *ObjectCache, |
| ... | @@ -1446,21 +1469,22 @@ fn resolveDeltaChain( | ... | @@ -1446,21 +1469,22 @@ fn resolveDeltaChain( |
| 1446 | 1469 | ||
| 1447 | const delta_offset = delta_offsets[i]; | 1470 | const delta_offset = delta_offsets[i]; |
| 1448 | try pack.seekTo(delta_offset); | 1471 | try pack.seekTo(delta_offset); |
| 1449 | const delta_header = try EntryHeader.read(format, pack.reader()); | 1472 | var pack_read_buffer: [64]u8 = undefined; |
| 1450 | const delta_data = try readObjectRaw(allocator, pack.reader(), delta_header.uncompressedLength()); | 1473 | var pack_br = pack.readable(&pack_read_buffer); |
| 1451 | defer allocator.free(delta_data); | 1474 | const delta_header = try EntryHeader.read(format, &pack_br); |
| 1452 | var delta_stream = std.io.fixedBufferStream(delta_data); | 1475 | _ = delta_header; |
| 1453 | const delta_reader = delta_stream.reader(); | 1476 | var delta_decompress: zlib.Decompressor = .init(&pack_br); |
| 1454 | _ = try readSizeVarInt(delta_reader); // base object size | 1477 | var delta_decompress_buffer: [zlib.max_window_len]u8 = undefined; |
| 1455 | const expanded_size = try readSizeVarInt(delta_reader); | 1478 | var delta_reader = delta_decompress.readable(&delta_decompress_buffer); |
| 1456 | 1479 | _ = try readSizeVarInt(&delta_reader); // base object size | |
| 1480 | const expanded_size = try readSizeVarInt(&delta_reader); | ||
| 1457 | const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge; | 1481 | const expanded_alloc_size = std.math.cast(usize, expanded_size) orelse return error.ObjectTooLarge; |
| 1458 | const expanded_data = try allocator.alloc(u8, expanded_alloc_size); | 1482 | const expanded_data = try allocator.alloc(u8, expanded_alloc_size); |
| 1459 | errdefer allocator.free(expanded_data); | 1483 | errdefer allocator.free(expanded_data); |
| 1460 | var expanded_delta_stream = std.io.fixedBufferStream(expanded_data); | 1484 | var expanded_delta_stream: std.io.BufferedWriter = undefined; |
| 1461 | var base_stream = std.io.fixedBufferStream(base_data); | 1485 | expanded_delta_stream.initFixed(expanded_data); |
| 1462 | try expandDelta(&base_stream, delta_reader, expanded_delta_stream.writer()); | 1486 | try expandDelta(base_data, &delta_reader, &expanded_delta_stream); |
| 1463 | if (expanded_delta_stream.pos != expanded_size) return error.InvalidObject; | 1487 | if (expanded_delta_stream.end != expanded_size) return error.InvalidObject; |
| 1464 | 1488 | ||
| 1465 | try cache.put(allocator, delta_offset, .{ .type = base_object.type, .data = expanded_data }); | 1489 | try cache.put(allocator, delta_offset, .{ .type = base_object.type, .data = expanded_data }); |
| 1466 | base_data = expanded_data; | 1490 | base_data = expanded_data; |
| ... | @@ -1468,31 +1492,23 @@ fn resolveDeltaChain( | ... | @@ -1468,31 +1492,23 @@ fn resolveDeltaChain( |
| 1468 | return base_data; | 1492 | return base_data; |
| 1469 | } | 1493 | } |
| 1470 | 1494 | ||
| 1471 | /// Reads the complete contents of an object from `reader`. This function may | 1495 | /// Reads the complete contents of an object from `reader`. |
| 1472 | /// read more bytes than required from `reader`, so the reader position after | 1496 | fn readObjectRaw(gpa: Allocator, reader: *std.io.BufferedReader, size: u64) ![]u8 { |
| 1473 | /// returning is not reliable. | ||
| 1474 | fn readObjectRaw(allocator: Allocator, reader: anytype, size: u64) ![]u8 { | ||
| 1475 | const alloc_size = std.math.cast(usize, size) orelse return error.ObjectTooLarge; | 1497 | const alloc_size = std.math.cast(usize, size) orelse return error.ObjectTooLarge; |
| 1476 | var buffered_reader = std.io.bufferedReader(reader); | 1498 | var decompress: zlib.Decompressor = .init(reader); |
| 1477 | var decompress_stream = std.compress.zlib.decompressor(buffered_reader.reader()); | 1499 | var buffer: std.ArrayListUnmanaged(u8) = .empty; |
| 1478 | const data = try allocator.alloc(u8, alloc_size); | 1500 | defer buffer.deinit(gpa); |
| 1479 | errdefer allocator.free(data); | 1501 | try decompress.reader().readRemainingArrayList(gpa, null, &buffer, .limited(alloc_size), zlib.max_window_len); |
| 1480 | try decompress_stream.reader().readNoEof(data); | 1502 | if (buffer.items.len < size) return error.EndOfStream; |
| 1481 | _ = decompress_stream.reader().readByte() catch |e| switch (e) { | 1503 | return buffer.toOwnedSlice(gpa); |
| 1482 | error.EndOfStream => return data, | ||
| 1483 | else => |other| return other, | ||
| 1484 | }; | ||
| 1485 | return error.InvalidFormat; | ||
| 1486 | } | 1504 | } |
| 1487 | 1505 | ||
| 1488 | /// Expands delta data from `delta_reader` to `writer`. `base_object` must | ||
| 1489 | /// support `reader` and `seekTo` (such as a `std.io.FixedBufferStream`). | ||
| 1490 | /// | ||
| 1491 | /// The format of the delta data is documented in | 1506 | /// The format of the delta data is documented in |
| 1492 | /// [pack-format](https://git-scm.com/docs/pack-format). | 1507 | /// [pack-format](https://git-scm.com/docs/pack-format). |
| 1493 | fn expandDelta(base_object: anytype, delta_reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter) !void { | 1508 | fn expandDelta(base_object: []const u8, delta_reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter) !void { |
| 1509 | var base_offset: u32 = 0; | ||
| 1494 | while (true) { | 1510 | while (true) { |
| 1495 | const inst: packed struct { value: u7, copy: bool } = @bitCast(delta_reader.readByte() catch |e| switch (e) { | 1511 | const inst: packed struct { value: u7, copy: bool } = @bitCast(delta_reader.takeByte() catch |e| switch (e) { |
| 1496 | error.EndOfStream => return, | 1512 | error.EndOfStream => return, |
| 1497 | else => |other| return other, | 1513 | else => |other| return other, |
| 1498 | }); | 1514 | }); |
| ... | @@ -1507,23 +1523,22 @@ fn expandDelta(base_object: anytype, delta_reader: *std.io.BufferedReader, write | ... | @@ -1507,23 +1523,22 @@ fn expandDelta(base_object: anytype, delta_reader: *std.io.BufferedReader, write |
| 1507 | size3: bool, | 1523 | size3: bool, |
| 1508 | } = @bitCast(inst.value); | 1524 | } = @bitCast(inst.value); |
| 1509 | const offset_parts: packed struct { offset1: u8, offset2: u8, offset3: u8, offset4: u8 } = .{ | 1525 | const offset_parts: packed struct { offset1: u8, offset2: u8, offset3: u8, offset4: u8 } = .{ |
| 1510 | .offset1 = if (available.offset1) try delta_reader.readByte() else 0, | 1526 | .offset1 = if (available.offset1) try delta_reader.takeByte() else 0, |
| 1511 | .offset2 = if (available.offset2) try delta_reader.readByte() else 0, | 1527 | .offset2 = if (available.offset2) try delta_reader.takeByte() else 0, |
| 1512 | .offset3 = if (available.offset3) try delta_reader.readByte() else 0, | 1528 | .offset3 = if (available.offset3) try delta_reader.takeByte() else 0, |
| 1513 | .offset4 = if (available.offset4) try delta_reader.readByte() else 0, | 1529 | .offset4 = if (available.offset4) try delta_reader.takeByte() else 0, |
| 1514 | }; | 1530 | }; |
| 1515 | const offset: u32 = @bitCast(offset_parts); | 1531 | base_offset = @bitCast(offset_parts); |
| 1516 | const size_parts: packed struct { size1: u8, size2: u8, size3: u8 } = .{ | 1532 | const size_parts: packed struct { size1: u8, size2: u8, size3: u8 } = .{ |
| 1517 | .size1 = if (available.size1) try delta_reader.readByte() else 0, | 1533 | .size1 = if (available.size1) try delta_reader.takeByte() else 0, |
| 1518 | .size2 = if (available.size2) try delta_reader.readByte() else 0, | 1534 | .size2 = if (available.size2) try delta_reader.takeByte() else 0, |
| 1519 | .size3 = if (available.size3) try delta_reader.readByte() else 0, | 1535 | .size3 = if (available.size3) try delta_reader.takeByte() else 0, |
| 1520 | }; | 1536 | }; |
| 1521 | var size: u24 = @bitCast(size_parts); | 1537 | var size: u24 = @bitCast(size_parts); |
| 1522 | if (size == 0) size = 0x10000; | 1538 | if (size == 0) size = 0x10000; |
| 1523 | try base_object.seekTo(offset); | ||
| 1524 | 1539 | ||
| 1525 | var base_object_br = base_object.reader(); | 1540 | try writer.writeAll(base_object[base_offset..][0..size]); |
| 1526 | try base_object_br.readAll(writer, .limited(size)); | 1541 | base_offset += size; |
| 1527 | } else if (inst.value != 0) { | 1542 | } else if (inst.value != 0) { |
| 1528 | try delta_reader.readAll(writer, .limited(inst.value)); | 1543 | try delta_reader.readAll(writer, .limited(inst.value)); |
| 1529 | } else { | 1544 | } else { |
| ... | @@ -1557,7 +1572,8 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void | ... | @@ -1557,7 +1572,8 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void |
| 1557 | 1572 | ||
| 1558 | var index_file = try git_dir.dir.createFile("testrepo.idx", .{ .read = true }); | 1573 | var index_file = try git_dir.dir.createFile("testrepo.idx", .{ .read = true }); |
| 1559 | defer index_file.close(); | 1574 | defer index_file.close(); |
| 1560 | try indexPack(testing.allocator, format, pack_file, index_file.writer()); | 1575 | var index_file_writer = index_file.writer(); |
| 1576 | try indexPack(testing.allocator, format, pack_file, &index_file_writer); | ||
| 1561 | 1577 | ||
| 1562 | // Arbitrary size limit on files read while checking the repository contents | 1578 | // Arbitrary size limit on files read while checking the repository contents |
| 1563 | // (all files in the test repo are known to be smaller than this) | 1579 | // (all files in the test repo are known to be smaller than this) |
| ... | @@ -1571,7 +1587,8 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void | ... | @@ -1571,7 +1587,8 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void |
| 1571 | const testrepo_idx = @embedFile("git/testdata/testrepo-" ++ @tagName(format) ++ ".idx"); | 1587 | const testrepo_idx = @embedFile("git/testdata/testrepo-" ++ @tagName(format) ++ ".idx"); |
| 1572 | try testing.expectEqualSlices(u8, testrepo_idx, index_file_data); | 1588 | try testing.expectEqualSlices(u8, testrepo_idx, index_file_data); |
| 1573 | 1589 | ||
| 1574 | var repository = try Repository.init(testing.allocator, format, pack_file, index_file); | 1590 | var index_file_reader = index_file_writer.moveToReader(); |
| 1591 | var repository = try Repository.init(testing.allocator, format, pack_file, &index_file_reader); | ||
| 1575 | defer repository.deinit(); | 1592 | defer repository.deinit(); |
| 1576 | 1593 | ||
| 1577 | var worktree = testing.tmpDir(.{ .iterate = true }); | 1594 | var worktree = testing.tmpDir(.{ .iterate = true }); |
| ... | @@ -1652,10 +1669,12 @@ test "SHA-256 packfile indexing and checkout" { | ... | @@ -1652,10 +1669,12 @@ test "SHA-256 packfile indexing and checkout" { |
| 1652 | /// Checks out a commit of a packfile. Intended for experimenting with and | 1669 | /// Checks out a commit of a packfile. Intended for experimenting with and |
| 1653 | /// benchmarking possible optimizations to the indexing and checkout behavior. | 1670 | /// benchmarking possible optimizations to the indexing and checkout behavior. |
| 1654 | pub fn main() !void { | 1671 | pub fn main() !void { |
| 1655 | const allocator = std.heap.c_allocator; | 1672 | var debug_allocator: std.heap.DebugAllocator(.{}) = .init; |
| 1673 | defer _ = debug_allocator.deinit(); | ||
| 1674 | const gpa = if (std.debug.runtime_safety) debug_allocator.allocator() else std.heap.smp_allocator; | ||
| 1656 | 1675 | ||
| 1657 | const args = try std.process.argsAlloc(allocator); | 1676 | const args = try std.process.argsAlloc(gpa); |
| 1658 | defer std.process.argsFree(allocator, args); | 1677 | defer std.process.argsFree(gpa, args); |
| 1659 | if (args.len != 5) { | 1678 | if (args.len != 5) { |
| 1660 | return error.InvalidArguments; // Arguments: format packfile commit worktree | 1679 | return error.InvalidArguments; // Arguments: format packfile commit worktree |
| 1661 | } | 1680 | } |
| ... | @@ -1674,15 +1693,17 @@ pub fn main() !void { | ... | @@ -1674,15 +1693,17 @@ pub fn main() !void { |
| 1674 | std.debug.print("Starting index...\n", .{}); | 1693 | std.debug.print("Starting index...\n", .{}); |
| 1675 | var index_file = try git_dir.createFile("idx", .{ .read = true }); | 1694 | var index_file = try git_dir.createFile("idx", .{ .read = true }); |
| 1676 | defer index_file.close(); | 1695 | defer index_file.close(); |
| 1677 | var index_buffered_writer = std.io.bufferedWriter(index_file.writer()); | 1696 | var index_file_writer = index_file.writer(); |
| 1678 | try indexPack(allocator, format, pack_file, index_buffered_writer.writer()); | 1697 | var pack_file_reader = pack_file.reader(); |
| 1679 | try index_buffered_writer.flush(); | 1698 | try indexPack(gpa, format, &pack_file_reader, &index_file_writer); |
| 1680 | try index_file.sync(); | 1699 | try index_file.sync(); |
| 1681 | 1700 | ||
| 1682 | std.debug.print("Starting checkout...\n", .{}); | 1701 | std.debug.print("Starting checkout...\n", .{}); |
| 1683 | var repository = try Repository.init(allocator, format, pack_file, index_file); | 1702 | var index_file_reader = index_file_writer.moveToReader(); |
| 1703 | var repository: Repository = undefined; | ||
| 1704 | try repository.init(gpa, format, &pack_file_reader, &index_file_reader); | ||
| 1684 | defer repository.deinit(); | 1705 | defer repository.deinit(); |
| 1685 | var diagnostics: Diagnostics = .{ .allocator = allocator }; | 1706 | var diagnostics: Diagnostics = .{ .allocator = gpa }; |
| 1686 | defer diagnostics.deinit(); | 1707 | defer diagnostics.deinit(); |
| 1687 | try repository.checkout(worktree, commit, &diagnostics); | 1708 | try repository.checkout(worktree, commit, &diagnostics); |
| 1688 | 1709 |
src/main.zig+3-4| ... | @@ -3330,12 +3330,11 @@ fn buildOutputType( | ... | @@ -3330,12 +3330,11 @@ fn buildOutputType( |
| 3330 | // for the hashing algorithm here and in the cache are the same. | 3330 | // for the hashing algorithm here and in the cache are the same. |
| 3331 | // We are providing our own cache key, because this file has nothing | 3331 | // We are providing our own cache key, because this file has nothing |
| 3332 | // to do with the cache manifest. | 3332 | // to do with the cache manifest. |
| 3333 | var hasher = Cache.Hasher.init("0123456789abcdef"); | ||
| 3334 | var file_writer = f.writer(); | 3333 | var file_writer = f.writer(); |
| 3335 | var file_writer_bw = file_writer.interface().unbuffered(); | 3334 | var file_writer_bw = file_writer.writable(&.{}); |
| 3336 | var hasher_writer = hasher.writer(&file_writer_bw); | 3335 | var hasher_writer = file_writer_bw.hashed(Cache.Hasher.init("0123456789abcdef")); |
| 3337 | var buffer: [1000]u8 = undefined; | 3336 | var buffer: [1000]u8 = undefined; |
| 3338 | var bw = hasher_writer.interface().buffered(&buffer); | 3337 | var bw = hasher_writer.writable(&buffer); |
| 3339 | bw.writeFileAll(.stdin(), .{}) catch |err| switch (err) { | 3338 | bw.writeFileAll(.stdin(), .{}) catch |err| switch (err) { |
| 3340 | error.WriteFailed => fatal("failed to write {s}: {s}", .{ dump_path, file_writer.err.? }), | 3339 | error.WriteFailed => fatal("failed to write {s}: {s}", .{ dump_path, file_writer.err.? }), |
| 3341 | else => fatal("failed to pipe stdin to {s}: {s}", .{ dump_path, err }), | 3340 | else => fatal("failed to pipe stdin to {s}: {s}", .{ dump_path, err }), |