MT Core (C++)
Core library for replacing C++ standard in project usage
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1#ifndef MTCORE_CSV_COMMON_HPP
2#define MTCORE_CSV_COMMON_HPP
3
5
6namespace mtcore::csv {
7 static constexpr u64 chunkSize = 64;
8
20
21 struct ReadError {
25 size_t pos;
26
27 bool operator==(const ReadError &o) const { return code == o.code && pos == o.pos; }
28
29 bool operator==(const ReadErrorCode &o) const { return code == o; }
30
31 bool operator!=(const ReadError &o) const { return !(*this == o); }
32
33 bool operator!=(const ReadErrorCode &o) const { return !(*this == o); }
34
35 static const ReadError END_OF_FILE;
38
39 template<WriterImpl WI>
41 const char* codeStr = "";
42 switch (code) {
44 codeStr = "INTERNAL_LIMIT_REACHED";
45 break;
47 codeStr = "UNEXPECTED_EOF";
48 break;
50 codeStr = "INVALID_LINE_ENDING";
51 break;
53 codeStr = "QUOTE_PREMATURELY_TERMINATED";
54 break;
56 codeStr = "UNEXPECTED_QUOTE";
57 break;
59 codeStr = "END_OF_FILE";
60 break;
62 codeStr = "ALLOCATION_FAILED";
63 break;
65 codeStr = "SIZE_EXCEEDED";
66 break;
67 }
68
69 return io::print(writer, "ReadError\\{{}, {}\\}", codeStr, pos);
70 }
71 };
72
78 struct Options {
80 char lf = '\n';
81 char quote = '"';
82 char sep = ',';
83 size_t internalIterLimit = 65536;
84
85 [[nodiscard]] bool valid() const;
86 };
87
88 namespace common {
89 [[nodiscard]] u64 quoted_regions(u64 m);
90
92
93 template<WriterImpl WI>
95 const Options options = {}) {
96 ensure(options.valid());
97 const auto quote = options.quote;
98 if (field.len < 2 || field[0] != quote) {
99 return writer.write_all(field);
100 }
101
102 const auto data = unquote_quoted(field, options);
103 Optional<char> nextChar;
104 Optional<char> curChar;
105 size_t ni = 1;
106 size_t written = 0;
107
108 if (0 < data.len) {
109 curChar = data[0];
110 if (1 < data.len) {
111 nextChar = data[1];
112 }
113 }
114
115 char c;
116 while (curChar.copy_if_present(c)) {
117 mtdefer {
118 ni++;
119 curChar = nextChar;
120 if (ni < data.len) {
121 nextChar = data[ni];
122 }
123 else {
124 nextChar = nullopt;
125 }
126 };
127
128 if (c != quote) {
129 if (auto r = writer.write(c); r.is_error()) {
130 return r.error();
131 }
132 ++written;
133 continue;
134 }
135
136 if (nextChar == quote) {
137 mtdefer {
138 ni += 1;
139 curChar = nextChar;
140 if (ni < data.len) {
141 nextChar = data[ni];
142 }
143 else {
144 nextChar = nullopt;
145 }
146 };
147
148 if (auto r = writer.write(c); r.is_error()) {
149 return r.error();
150 }
151 ++written;
152 }
153 }
154
155 return success(written);
156 }
157 } // namespace common
158
159 [[nodiscard]] u64 bit_match_64(char ch, Slice<const char> s);
160} // namespace mtcore::csv
161
162#endif // MTCORE_CSV_COMMON_HPP
constexpr auto nullopt
Placeholder value for an empty Optional.
Definition optional.hpp:409
io::Writer< csv::impl::Writer< WI > > writer(io::Writer< WI > &underlying, Options opts={})
Creates a CSV writer which will encode the data before writing it out.
Result< size_t, typename Writer< WI >::ErrType > print(Writer< WI > &writer, const char *fmt, const Args &...args)
Prints arguments using a format string Element insert points are designated by a pair of curly braces...
#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...
Success< void > success()
Creates a successful void Result object.
Definition result.hpp:398
uint64_t u64
Alias for 64-bit unsigned ints.
Slice< const char > unquote_quoted(Slice< const char > data, Options opts)
Result< size_t, typename io::Writer< WI >::ErrType > decode(io::Writer< WI > &writer, Slice< const char > field, const Options options={})
Definition common.hpp:94
u64 quoted_regions(u64 m)
CSV namespace for CSV-related utilities.
Definition common.hpp:6
static constexpr u64 chunkSize
Definition common.hpp:7
u64 bit_match_64(char ch, Slice< const char > s)
Represents a value that may or may not exist (an "Optional" value) Similar concept to std::optional,...
Definition optional.hpp:235
bool copy_if_present(std::remove_const_t< T > &out) const noexcept
Copies a value to a reference output destination if a value is present Designed to be used by simple ...
Definition optional.hpp:327
Represents a Result that may have an error (error code) or a success value A type of "void" means the...
Definition result.hpp:170
A Slice which is just a pointer + length Accessing elements through the array operator will do bounds...
CSV options for defining the CSV format.
Definition common.hpp:78
size_t internalIterLimit
Definition common.hpp:83
Optional< char > cr
Definition common.hpp:79
bool valid() const
bool operator==(const ReadError &o) const
Definition common.hpp:27
ReadErrorCode code
Error code.
Definition common.hpp:23
static const ReadError SIZE_EXCEEDED
Definition common.hpp:37
bool operator==(const ReadErrorCode &o) const
Definition common.hpp:29
Result< size_t, typename io::Writer< WI >::ErrType > fmt(io::Writer< WI > &writer, const io::FormatOptions &)
Definition common.hpp:40
bool operator!=(const ReadErrorCode &o) const
Definition common.hpp:33
bool operator!=(const ReadError &o) const
Definition common.hpp:31
static const ReadError ALLOCATION_FAILED
Definition common.hpp:36
size_t pos
Human-readable position (i.e.
Definition common.hpp:25
static const ReadError END_OF_FILE
Definition common.hpp:35
Options for specifying formatting.
Definition format.hpp:36
A writer that writes data to some sort of stream or buffer Note: the data elements written should be ...
Definition io/writer.hpp:51