| ... | @@ -287,16 +287,20 @@ pub const LimitedAllocError = Allocator.Error || ShortError || error{StreamTooLo | ... | @@ -287,16 +287,20 @@ pub const LimitedAllocError = Allocator.Error || ShortError || error{StreamTooLo |
| 287 | /// Transfers all bytes from the current position to the end of the stream, up | 287 | /// Transfers all bytes from the current position to the end of the stream, up |
| 288 | /// to `limit`, returning them as a caller-owned allocated slice. | 288 | /// to `limit`, returning them as a caller-owned allocated slice. |
| 289 | /// | 289 | /// |
| 290 | /// If `limit` is reached or exceeded, `error.StreamTooLong` is returned | 290 | /// If `limit` is exceeded, `error.StreamTooLong` is returned instead. |
| 291 | /// instead. In such case, the next byte that would be read will be the first | 291 | /// In such case, the next byte that would be read will be one byte past the |
| 292 | /// one to exceed `limit`, and all preceeding bytes have been discarded. | 292 | /// first one to exceed `limit`, and all preceeding bytes have been discarded. |
| 293 | /// | 293 | /// |
| 294 | /// See also: | 294 | /// See also: |
| 295 | /// * `appendRemaining` | 295 | /// * `appendRemaining` |
| 296 | pub fn allocRemaining(r: *Reader, gpa: Allocator, limit: Limit) LimitedAllocError![]u8 { | 296 | pub fn allocRemaining(r: *Reader, gpa: Allocator, limit: Limit) LimitedAllocError![]u8 { |
| 297 | var buffer: ArrayList(u8) = .empty; | 297 | var buffer: ArrayList(u8) = .empty; |
| 298 | defer buffer.deinit(gpa); | 298 | defer buffer.deinit(gpa); |
| 299 | try appendRemaining(r, gpa, &buffer, limit); | 299 | |
| | 300 | try appendRemaining(r, gpa, &buffer, switch (limit) { |
| | 301 | .unlimited => limit, |
| | 302 | .nothing, _ => .limited(@backingInt(limit) + 1), |
| | 303 | }); |
| 300 | return buffer.toOwnedSlice(gpa); | 304 | return buffer.toOwnedSlice(gpa); |
| 301 | } | 305 | } |
| 302 | | 306 | |
| ... | @@ -1894,6 +1898,31 @@ test "takeStruct and peekStruct packed" { | ... | @@ -1894,6 +1898,31 @@ test "takeStruct and peekStruct packed" { |
| 1894 | try testing.expectError(error.EndOfStream, r.takeStruct(S, .little)); | 1898 | try testing.expectError(error.EndOfStream, r.takeStruct(S, .little)); |
| 1895 | } | 1899 | } |
| 1896 | | 1900 | |
| | 1901 | test allocRemaining { |
| | 1902 | { |
| | 1903 | var r: Reader = .fixed("abc"); |
| | 1904 | const str = try r.allocRemaining(testing.allocator, .unlimited); |
| | 1905 | defer testing.allocator.free(str); |
| | 1906 | try testing.expectEqualStrings("abc", str); |
| | 1907 | } |
| | 1908 | { |
| | 1909 | var r: Reader = .fixed("abc"); |
| | 1910 | const str = try r.allocRemaining(testing.allocator, .limited(5)); |
| | 1911 | defer testing.allocator.free(str); |
| | 1912 | try testing.expectEqualStrings("abc", str); |
| | 1913 | } |
| | 1914 | { |
| | 1915 | var r: Reader = .fixed("abc"); |
| | 1916 | const str = try r.allocRemaining(testing.allocator, .limited(3)); |
| | 1917 | defer testing.allocator.free(str); |
| | 1918 | try testing.expectEqualStrings("abc", str); |
| | 1919 | } |
| | 1920 | { |
| | 1921 | var r: Reader = .fixed("abcd"); |
| | 1922 | try testing.expectError(error.StreamTooLong, r.allocRemaining(testing.allocator, .limited(3))); |
| | 1923 | } |
| | 1924 | } |
| | 1925 | |
| 1897 | /// Provides a `Reader` implementation by passing data from an underlying | 1926 | /// Provides a `Reader` implementation by passing data from an underlying |
| 1898 | /// reader through `Hasher.update`. | 1927 | /// reader through `Hasher.update`. |
| 1899 | /// | 1928 | /// |