| ... | ... | @@ -481,7 +481,6 @@ pub fn readVecAll(r: *Reader, data: [][]u8) Error!void { |
| 481 | 481 | /// is returned instead. |
| 482 | 482 | /// |
| 483 | 483 | /// See also: |
| 484 | | /// * `peek` |
| 485 | 484 | /// * `toss` |
| 486 | 485 | pub fn peek(r: *Reader, n: usize) Error![]u8 { |
| 487 | 486 | try r.fill(n); |
| ... | ... | @@ -732,7 +731,7 @@ pub const DelimiterError = error{ |
| 732 | 731 | }; |
| 733 | 732 | |
| 734 | 733 | /// Returns a slice of the next bytes of buffered data from the stream until |
| 735 | | /// `sentinel` is found, advancing the seek position. |
| 734 | /// `sentinel` is found, advancing the seek position past the sentinel. |
| 736 | 735 | /// |
| 737 | 736 | /// Returned slice has a sentinel. |
| 738 | 737 | /// |
| ... | ... | @@ -765,7 +764,7 @@ pub fn peekSentinel(r: *Reader, comptime sentinel: u8) DelimiterError![:sentinel |
| 765 | 764 | } |
| 766 | 765 | |
| 767 | 766 | /// Returns a slice of the next bytes of buffered data from the stream until |
| 768 | | /// `delimiter` is found, advancing the seek position. |
| 767 | /// `delimiter` is found, advancing the seek position past the delimiter. |
| 769 | 768 | /// |
| 770 | 769 | /// Returned slice includes the delimiter as the last byte. |
| 771 | 770 | /// |
| ... | ... | @@ -818,7 +817,8 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 { |
| 818 | 817 | } |
| 819 | 818 | |
| 820 | 819 | /// Returns a slice of the next bytes of buffered data from the stream until |
| 821 | | /// `delimiter` is found, advancing the seek position up to the delimiter. |
| 820 | /// `delimiter` is found, advancing the seek position up to (but not past) |
| 821 | /// the delimiter. |
| 822 | 822 | /// |
| 823 | 823 | /// Returned slice excludes the delimiter. End-of-stream is treated equivalent |
| 824 | 824 | /// to a delimiter, unless it would result in a length 0 return value, in which |
| ... | ... | @@ -832,20 +832,13 @@ pub fn peekDelimiterInclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 { |
| 832 | 832 | /// Invalidates previously returned values from `peek`. |
| 833 | 833 | /// |
| 834 | 834 | /// See also: |
| 835 | /// * `takeDelimiter` |
| 835 | 836 | /// * `takeDelimiterInclusive` |
| 836 | 837 | /// * `peekDelimiterExclusive` |
| 837 | 838 | pub fn takeDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 { |
| 838 | | const result = r.peekDelimiterInclusive(delimiter) catch |err| switch (err) { |
| 839 | | error.EndOfStream => { |
| 840 | | const remaining = r.buffer[r.seek..r.end]; |
| 841 | | if (remaining.len == 0) return error.EndOfStream; |
| 842 | | r.toss(remaining.len); |
| 843 | | return remaining; |
| 844 | | }, |
| 845 | | else => |e| return e, |
| 846 | | }; |
| 839 | const result = try r.peekDelimiterExclusive(delimiter); |
| 847 | 840 | r.toss(result.len); |
| 848 | | return result[0 .. result.len - 1]; |
| 841 | return result; |
| 849 | 842 | } |
| 850 | 843 | |
| 851 | 844 | /// Returns a slice of the next bytes of buffered data from the stream until |
| ... | ... | @@ -866,7 +859,7 @@ pub fn takeDelimiterExclusive(r: *Reader, delimiter: u8) DelimiterError![]u8 { |
| 866 | 859 | /// * `takeDelimiterInclusive` |
| 867 | 860 | /// * `takeDelimiterExclusive` |
| 868 | 861 | pub fn takeDelimiter(r: *Reader, delimiter: u8) error{ ReadFailed, StreamTooLong }!?[]u8 { |
| 869 | | const result = r.peekDelimiterInclusive(delimiter) catch |err| switch (err) { |
| 862 | const inclusive = r.peekDelimiterInclusive(delimiter) catch |err| switch (err) { |
| 870 | 863 | error.EndOfStream => { |
| 871 | 864 | const remaining = r.buffer[r.seek..r.end]; |
| 872 | 865 | if (remaining.len == 0) return null; |
| ... | ... | @@ -875,8 +868,8 @@ pub fn takeDelimiter(r: *Reader, delimiter: u8) error{ ReadFailed, StreamTooLong |
| 875 | 868 | }, |
| 876 | 869 | else => |e| return e, |
| 877 | 870 | }; |
| 878 | | r.toss(result.len + 1); |
| 879 | | return result[0 .. result.len - 1]; |
| 871 | r.toss(inclusive.len); |
| 872 | return inclusive[0 .. inclusive.len - 1]; |
| 880 | 873 | } |
| 881 | 874 | |
| 882 | 875 | /// Returns a slice of the next bytes of buffered data from the stream until |
| ... | ... | @@ -1403,6 +1396,9 @@ test peekSentinel { |
| 1403 | 1396 | var r: Reader = .fixed("ab\nc"); |
| 1404 | 1397 | try testing.expectEqualStrings("ab", try r.peekSentinel('\n')); |
| 1405 | 1398 | try testing.expectEqualStrings("ab", try r.peekSentinel('\n')); |
| 1399 | r.toss(3); |
| 1400 | try testing.expectError(error.EndOfStream, r.peekSentinel('\n')); |
| 1401 | try testing.expectEqualStrings("c", try r.peek(1)); |
| 1406 | 1402 | } |
| 1407 | 1403 | |
| 1408 | 1404 | test takeDelimiterInclusive { |
| ... | ... | @@ -1417,22 +1413,52 @@ test peekDelimiterInclusive { |
| 1417 | 1413 | try testing.expectEqualStrings("ab\n", try r.peekDelimiterInclusive('\n')); |
| 1418 | 1414 | r.toss(3); |
| 1419 | 1415 | try testing.expectError(error.EndOfStream, r.peekDelimiterInclusive('\n')); |
| 1416 | try testing.expectEqualStrings("c", try r.peek(1)); |
| 1420 | 1417 | } |
| 1421 | 1418 | |
| 1422 | 1419 | test takeDelimiterExclusive { |
| 1423 | 1420 | var r: Reader = .fixed("ab\nc"); |
| 1421 | |
| 1424 | 1422 | try testing.expectEqualStrings("ab", try r.takeDelimiterExclusive('\n')); |
| 1423 | try testing.expectEqualStrings("", try r.takeDelimiterExclusive('\n')); |
| 1424 | try testing.expectEqualStrings("", try r.takeDelimiterExclusive('\n')); |
| 1425 | try testing.expectEqualStrings("\n", try r.take(1)); |
| 1426 | |
| 1425 | 1427 | try testing.expectEqualStrings("c", try r.takeDelimiterExclusive('\n')); |
| 1426 | 1428 | try testing.expectError(error.EndOfStream, r.takeDelimiterExclusive('\n')); |
| 1427 | 1429 | } |
| 1428 | 1430 | |
| 1429 | 1431 | test peekDelimiterExclusive { |
| 1430 | 1432 | var r: Reader = .fixed("ab\nc"); |
| 1433 | |
| 1431 | 1434 | try testing.expectEqualStrings("ab", try r.peekDelimiterExclusive('\n')); |
| 1432 | 1435 | try testing.expectEqualStrings("ab", try r.peekDelimiterExclusive('\n')); |
| 1433 | | r.toss(3); |
| 1436 | r.toss(2); |
| 1437 | try testing.expectEqualStrings("", try r.peekDelimiterExclusive('\n')); |
| 1438 | try testing.expectEqualStrings("\n", try r.take(1)); |
| 1439 | |
| 1434 | 1440 | try testing.expectEqualStrings("c", try r.peekDelimiterExclusive('\n')); |
| 1435 | 1441 | try testing.expectEqualStrings("c", try r.peekDelimiterExclusive('\n')); |
| 1442 | r.toss(1); |
| 1443 | try testing.expectError(error.EndOfStream, r.peekDelimiterExclusive('\n')); |
| 1444 | } |
| 1445 | |
| 1446 | test takeDelimiter { |
| 1447 | var r: Reader = .fixed("ab\nc\n\nd"); |
| 1448 | try testing.expectEqualStrings("ab", (try r.takeDelimiter('\n')).?); |
| 1449 | try testing.expectEqualStrings("c", (try r.takeDelimiter('\n')).?); |
| 1450 | try testing.expectEqualStrings("", (try r.takeDelimiter('\n')).?); |
| 1451 | try testing.expectEqualStrings("d", (try r.takeDelimiter('\n')).?); |
| 1452 | try testing.expectEqual(null, try r.takeDelimiter('\n')); |
| 1453 | try testing.expectEqual(null, try r.takeDelimiter('\n')); |
| 1454 | |
| 1455 | r = .fixed("ab\nc\n\nd\n"); // one trailing newline does not affect behavior |
| 1456 | try testing.expectEqualStrings("ab", (try r.takeDelimiter('\n')).?); |
| 1457 | try testing.expectEqualStrings("c", (try r.takeDelimiter('\n')).?); |
| 1458 | try testing.expectEqualStrings("", (try r.takeDelimiter('\n')).?); |
| 1459 | try testing.expectEqualStrings("d", (try r.takeDelimiter('\n')).?); |
| 1460 | try testing.expectEqual(null, try r.takeDelimiter('\n')); |
| 1461 | try testing.expectEqual(null, try r.takeDelimiter('\n')); |
| 1436 | 1462 | } |
| 1437 | 1463 | |
| 1438 | 1464 | test streamDelimiter { |