501 {
505 ensure(maxSize > 0,
"BAD MAX SIZE");
506
507 if (maxSize == std::numeric_limits<size_t>::max() || maxSize >= 100000000) {
508
510 if (
auto res = fullBuff.
init(alloc, 4000); res.is_error()) {
511 return error(ErrType::ALLOCATION_FAILED);
512 }
513
514
516
517 size_t count = 0;
518
519 while (true) {
520 auto readRes = self.read_one();
521 if (readRes.is_error()) {
522 if (readRes.error().code == ErrType::END_OF_FILE) {
523 return error(ErrType::END_OF_FILE);
524 }
525 return error(ErrType::ALLOCATION_FAILED);
526 }
527
528 auto cur = readRes.value();
529 if (cur == delim) {
530 break;
531 }
532 if (
auto pushRes = fullBuff.
push(alloc, cur); pushRes.is_error()) {
533 return error(ErrType::ALLOCATION_FAILED);
534 }
535 ++count;
536 }
537
538 if (count == 0) {
539 return BuffSlice{nullptr, 0};
540 }
541
542
543
544 auto finalRes = alloc.
create_many<std::remove_const_t<ReadElem>>(count);
545 if (finalRes.is_error()) {
546 return error(ErrType::ALLOCATION_FAILED);
547 }
548
549 auto finalSlice = finalRes.value();
550
552
553 auto iter = fullBuff.
iter();
554 std::remove_const_t<ReadElem> curElem;
555 while (iter.next().copy_if_present(curElem)) {
556 if (auto r = finalWriter.write(curElem); r.is_error()) {
558 return error(ErrType::ALLOCATION_FAILED);
559 }
560 }
561
562
563 return finalSlice;
564 }
565 else {
566
567 auto outRes = alloc.
create_many<std::remove_const_t<ReadElem>>(maxSize);
568 if (outRes.is_error()) {
569 return error(ErrType::ALLOCATION_FAILED);
570 }
571 auto out = outRes.value();
573 if (res.is_error()) {
575 return res.error();
576 }
577 auto finalRes = res.value();
578
579
580
581 if (finalRes.size() + alignof(ReadElem) < out.size()) {
582 if (finalRes.size() == 0) {
584 return BuffSlice{nullptr, 0};
585 }
586
587 auto smallerRes = alloc.
create_many<std::remove_const_t<ReadElem>>(finalRes.size());
588 if (smallerRes.is_error()) {
589
590 return out.sub(0, finalRes.size());
591 }
592 auto smaller = smallerRes.value();
594 ensure(w.write_all(finalRes).is_success(),
"SOMETHING IS WRONG WITH SLICE WRITER!");
597 }
598 return success(out.sub(0, finalRes.size()));
599 }
600 }
#define ensure(check,...)
Ensures that a check holds true, aborts the program if not true Will print error if the condition is ...
#define mtdefer
Defer statement that will mtdefer execution until the scope is left, at which point the code will run...
Result< typename Reader< T >::ResSlice, typename Reader< T >::ErrType > read_until_no_eof(Reader< T > &self, typename Reader< T >::BuffSlice buff, const std::remove_const_t< typename Reader< T >::ReadElem > &delim)
Reads data from a reader into a Slice up until there is either a delimiter If the buffer is not big e...
Success< void > success()
Creates a successful void Result object.
Error< Underlying > error(Underlying err)
Creates an error.
io::Writer< impl::SliceWriterImpl< T > > slice_writer(Slice< T > out)
Creates a writer to write to a Slice.
void destroy_many(Slice< T > s)
Destroys objects allocated by this allocator by calling the destructors and freeing memory.
Result< Slice< T >, AllocationError > create_many(size_t count=1)
Allocates some block of memory with an allocator with a known type Will call default constructor on t...
Segmented list where each segment contains multiple nodes Allows growing the list without having to i...
Result< void, CollectionAddNoAllocationError > push(const T &elem) noexcept
Pushes a new element.
void deinit(Allocator &alloc)
Cleans up memory tied to segmented list.
Result< void, AllocationError > init(Allocator &alloc, size_t initCapacity)
Initializes a segmented list.
ConstIter iter() const noexcept
Const iterator that gives element references.
Slice< std::remove_const_t< ReadElem > > BuffSlice
typename Impl::ReadElem ReadElem
typename Impl::ErrType ErrType