| ... | ... | @@ -287,16 +287,20 @@ pub const LimitedAllocError = Allocator.Error || ShortError || error{StreamTooLo |
| 287 | 287 | /// Transfers all bytes from the current position to the end of the stream, up |
| 288 | 288 | /// to `limit`, returning them as a caller-owned allocated slice. |
| 289 | 289 | /// |
| 290 | | /// If `limit` is reached or exceeded, `error.StreamTooLong` is returned |
| 291 | | /// instead. In such case, the next byte that would be read will be the first |
| 292 | | /// one to exceed `limit`, and all preceeding bytes have been discarded. |
| 290 | /// If `limit` is exceeded, `error.StreamTooLong` is returned instead. |
| 291 | /// In such case, the next byte that would be read will be one byte past the |
| 292 | /// first one to exceed `limit`, and all preceeding bytes have been discarded. |
| 293 | 293 | /// |
| 294 | 294 | /// See also: |
| 295 | 295 | /// * `appendRemaining` |
| 296 | 296 | pub fn allocRemaining(r: *Reader, gpa: Allocator, limit: Limit) LimitedAllocError![]u8 { |
| 297 | 297 | var buffer: ArrayList(u8) = .empty; |
| 298 | 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 | 304 | return buffer.toOwnedSlice(gpa); |
| 301 | 305 | } |
| 302 | 306 | |
| ... | ... | @@ -1894,6 +1898,31 @@ test "takeStruct and peekStruct packed" { |
| 1894 | 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 | 1926 | /// Provides a `Reader` implementation by passing data from an underlying |
| 1898 | 1927 | /// reader through `Hasher.update`. |
| 1899 | 1928 | /// |