| ... | @@ -1911,7 +1911,7 @@ pub fn writePackedInt(comptime T: type, bytes: []u8, bit_offset: usize, value: T | ... | @@ -1911,7 +1911,7 @@ pub fn writePackedInt(comptime T: type, bytes: []u8, bit_offset: usize, value: T |
| 1911 | /// Any extra bytes in buffer after writing the integer are set to zero. To | 1911 | /// Any extra bytes in buffer after writing the integer are set to zero. To |
| 1912 | /// avoid the branch to check for extra buffer bytes, use writeIntLittle | 1912 | /// avoid the branch to check for extra buffer bytes, use writeIntLittle |
| 1913 | /// instead. | 1913 | /// instead. |
| 1914 | pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void { | 1914 | fn writeIntSliceLittleNative(comptime T: type, buffer: []u8, value: T) void { |
| 1915 | assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8)); | 1915 | assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8)); |
| 1916 | | 1916 | |
| 1917 | if (@typeInfo(T).Int.bits == 0) { | 1917 | if (@typeInfo(T).Int.bits == 0) { |
| ... | @@ -1921,21 +1921,27 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void { | ... | @@ -1921,21 +1921,27 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void { |
| 1921 | buffer[0] = @as(u8, @bitCast(value)); | 1921 | buffer[0] = @as(u8, @bitCast(value)); |
| 1922 | return; | 1922 | return; |
| 1923 | } | 1923 | } |
| 1924 | // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough | 1924 | |
| 1925 | const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits); | 1925 | const write_end = @divExact(@typeInfo(T).Int.bits, 8); |
| 1926 | var bits = @as(uint, @bitCast(value)); | 1926 | @as(*align(1) T, @ptrCast(buffer)).* = value; |
| 1927 | for (buffer) |*b| { | 1927 | @memset(buffer[write_end..], 0); |
| 1928 | b.* = @as(u8, @truncate(bits)); | 1928 | } |
| 1929 | bits >>= 8; | 1929 | |
| 1930 | } | 1930 | fn writeIntSliceLittleForeign(comptime T: type, buffer: []u8, value: T) void { |
| | 1931 | return writeIntSliceLittleNative(T, buffer, @byteSwap(value)); |
| 1931 | } | 1932 | } |
| 1932 | | 1933 | |
| | 1934 | pub const writeIntSliceLittle = switch (native_endian) { |
| | 1935 | .Little => writeIntSliceLittleNative, |
| | 1936 | .Big => writeIntSliceLittleForeign, |
| | 1937 | }; |
| | 1938 | |
| 1933 | /// Writes a twos-complement big-endian integer to memory. | 1939 | /// Writes a twos-complement big-endian integer to memory. |
| 1934 | /// Asserts that buffer.len >= @typeInfo(T).Int.bits / 8. | 1940 | /// Asserts that buffer.len >= @typeInfo(T).Int.bits / 8. |
| 1935 | /// The bit count of T must be divisible by 8. | 1941 | /// The bit count of T must be divisible by 8. |
| 1936 | /// Any extra bytes in buffer before writing the integer are set to zero. To | 1942 | /// Any extra bytes in buffer before writing the integer are set to zero. To |
| 1937 | /// avoid the branch to check for extra buffer bytes, use writeIntBig instead. | 1943 | /// avoid the branch to check for extra buffer bytes, use writeIntBig instead. |
| 1938 | pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void { | 1944 | fn writeIntSliceBigNative(comptime T: type, buffer: []u8, value: T) void { |
| 1939 | assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8)); | 1945 | assert(buffer.len >= @divExact(@typeInfo(T).Int.bits, 8)); |
| 1940 | | 1946 | |
| 1941 | if (@typeInfo(T).Int.bits == 0) { | 1947 | if (@typeInfo(T).Int.bits == 0) { |
| ... | @@ -1946,25 +1952,28 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void { | ... | @@ -1946,25 +1952,28 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void { |
| 1946 | return; | 1952 | return; |
| 1947 | } | 1953 | } |
| 1948 | | 1954 | |
| 1949 | // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough | 1955 | const write_start = buffer.len - @divExact(@typeInfo(T).Int.bits, 8); |
| 1950 | const uint = std.meta.Int(.unsigned, @typeInfo(T).Int.bits); | 1956 | @memset(buffer[0..write_start], 0); |
| 1951 | var bits = @as(uint, @bitCast(value)); | 1957 | @as(*align(1) T, @ptrCast(buffer[write_start..])).* = value; |
| 1952 | var index: usize = buffer.len; | 1958 | } |
| 1953 | while (index != 0) { | 1959 | |
| 1954 | index -= 1; | 1960 | fn writeIntSliceBigForeign(comptime T: type, buffer: []u8, value: T) void { |
| 1955 | buffer[index] = @as(u8, @truncate(bits)); | 1961 | return writeIntSliceBigNative(T, buffer, @byteSwap(value)); |
| 1956 | bits >>= 8; | | |
| 1957 | } | | |
| 1958 | } | 1962 | } |
| 1959 | | 1963 | |
| | 1964 | pub const writeIntSliceBig = switch (native_endian) { |
| | 1965 | .Little => writeIntSliceBigForeign, |
| | 1966 | .Big => writeIntSliceBigNative, |
| | 1967 | }; |
| | 1968 | |
| 1960 | pub const writeIntSliceNative = switch (native_endian) { | 1969 | pub const writeIntSliceNative = switch (native_endian) { |
| 1961 | .Little => writeIntSliceLittle, | 1970 | .Little => writeIntSliceLittleNative, |
| 1962 | .Big => writeIntSliceBig, | 1971 | .Big => writeIntSliceBigNative, |
| 1963 | }; | 1972 | }; |
| 1964 | | 1973 | |
| 1965 | pub const writeIntSliceForeign = switch (native_endian) { | 1974 | pub const writeIntSliceForeign = switch (native_endian) { |
| 1966 | .Little => writeIntSliceBig, | 1975 | .Little => writeIntSliceBigForeign, |
| 1967 | .Big => writeIntSliceLittle, | 1976 | .Big => writeIntSliceLittleForeign, |
| 1968 | }; | 1977 | }; |
| 1969 | | 1978 | |
| 1970 | /// Writes a twos-complement integer to memory, with the specified endianness. | 1979 | /// Writes a twos-complement integer to memory, with the specified endianness. |