| 723 | |
| 724 | template <typename Vector> |
| 725 | void readCSVStringInto(Vector & s, ReadBuffer & buf, const FormatSettings::CSV & settings) |
| 726 | { |
| 727 | if (buf.eof()) |
| 728 | throwReadAfterEOF(); |
| 729 | |
| 730 | const char delimiter = settings.delimiter; |
| 731 | const char maybe_quote = *buf.position(); |
| 732 | |
| 733 | /// Emptiness and not even in quotation marks. |
| 734 | if (maybe_quote == delimiter) |
| 735 | return; |
| 736 | |
| 737 | if ((settings.allow_single_quotes && maybe_quote == '\'') || (settings.allow_double_quotes && maybe_quote == '"')) |
| 738 | { |
| 739 | ++buf.position(); |
| 740 | |
| 741 | /// The quoted case. We are looking for the next quotation mark. |
| 742 | while (!buf.eof()) |
| 743 | { |
| 744 | char * next_pos = reinterpret_cast<char *>(memchr(buf.position(), maybe_quote, buf.buffer().end() - buf.position())); |
| 745 | |
| 746 | if (nullptr == next_pos) |
| 747 | next_pos = buf.buffer().end(); |
| 748 | |
| 749 | appendToStringOrVector(s, buf, next_pos); |
| 750 | buf.position() = next_pos; |
| 751 | |
| 752 | if (!buf.hasPendingData()) |
| 753 | continue; |
| 754 | |
| 755 | /// Now there is a quotation mark under the cursor. Is there any following? |
| 756 | ++buf.position(); |
| 757 | if (buf.eof()) |
| 758 | return; |
| 759 | |
| 760 | if (*buf.position() == maybe_quote) |
| 761 | { |
| 762 | s.push_back(maybe_quote); |
| 763 | ++buf.position(); |
| 764 | continue; |
| 765 | } |
| 766 | |
| 767 | return; |
| 768 | } |
| 769 | } |
| 770 | else |
| 771 | { |
| 772 | /// Unquoted case. Look for delimiter or \r or \n. |
| 773 | while (!buf.eof()) |
| 774 | { |
| 775 | char * next_pos = buf.position(); |
| 776 | |
| 777 | [&]() |
| 778 | { |
| 779 | #ifdef __SSE2__ |
| 780 | auto rc = _mm_set1_epi8('\r'); |
| 781 | auto nc = _mm_set1_epi8('\n'); |
| 782 | auto dc = _mm_set1_epi8(delimiter); |
no test coverage detected