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/*
2
3Copyright 2025 Matthew Tolman
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16
17*/
18
19#ifndef MTCORE_CSV_COMMON_HPP
20#define MTCORE_CSV_COMMON_HPP
21
23
24namespace mtcore::csv {
25 static constexpr u64 chunkSize = 64;
26
38
39 struct ReadError {
43 size_t pos;
44
45 bool operator==(const ReadError &o) const { return code == o.code && pos == o.pos; }
46
47 bool operator==(const ReadErrorCode &o) const { return code == o; }
48
49 bool operator!=(const ReadError &o) const { return !(*this == o); }
50
51 bool operator!=(const ReadErrorCode &o) const { return !(*this == o); }
52
53 static const ReadError END_OF_FILE;
56
57 template<WriterImpl WI>
59 const char *codeStr = "";
60 switch (code) {
62 codeStr = "INTERNAL_LIMIT_REACHED";
63 break;
65 codeStr = "UNEXPECTED_EOF";
66 break;
68 codeStr = "INVALID_LINE_ENDING";
69 break;
71 codeStr = "QUOTE_PREMATURELY_TERMINATED";
72 break;
74 codeStr = "UNEXPECTED_QUOTE";
75 break;
77 codeStr = "END_OF_FILE";
78 break;
80 codeStr = "ALLOCATION_FAILED";
81 break;
83 codeStr = "SIZE_EXCEEDED";
84 break;
85 }
86
87 return io::print(writer, "ReadError\\{{}, {}\\}", codeStr, pos);
88 }
89 };
90
96 struct Options {
98 char lf = '\n';
99 char quote = '"';
100 char sep = ',';
101 size_t internalIterLimit = 65536;
102
103 [[nodiscard]] bool valid() const;
104 };
105
106 namespace common {
107 [[nodiscard]] u64 quoted_regions(u64 m);
108
110
111 template<WriterImpl WI>
113 const Options options = {}) {
114 ensure(options.valid());
115 const auto quote = options.quote;
116 if (field.len < 2 || field[0] != quote) {
117 return writer.write_all(field);
118 }
119
120 const auto data = unquote_quoted(field, options);
121 Optional<char> nextChar;
122 Optional<char> curChar;
123 size_t ni = 1;
124 size_t written = 0;
125
126 if (0 < data.len) {
127 curChar = data[0];
128 if (1 < data.len) {
129 nextChar = data[1];
130 }
131 }
132
133 char c;
134 while (curChar.copy_if_present(c)) {
135 mtdefer {
136 ni++;
137 curChar = nextChar;
138 if (ni < data.len) {
139 nextChar = data[ni];
140 }
141 else {
142 nextChar = nullopt;
143 }
144 };
145
146 if (c != quote) {
147 if (auto r = writer.write(c); r.is_error()) {
148 return r.error();
149 }
150 ++written;
151 continue;
152 }
153
154 if (nextChar == quote) {
155 mtdefer {
156 ni += 1;
157 curChar = nextChar;
158 if (ni < data.len) {
159 nextChar = data[ni];
160 }
161 else {
162 nextChar = nullopt;
163 }
164 };
165
166 if (auto r = writer.write(c); r.is_error()) {
167 return r.error();
168 }
169 ++written;
170 }
171 }
172
173 return success(written);
174 }
175 } // namespace common
176
177 [[nodiscard]] u64 bit_match_64(char ch, Slice<const char> s);
178} // namespace mtcore::csv
179
180#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:112
u64 quoted_regions(u64 m)
CSV namespace for CSV-related utilities.
Definition common.hpp:24
static constexpr u64 chunkSize
Definition common.hpp:25
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:96
Optional< char > cr
Definition common.hpp:97
bool valid() const
bool operator==(const ReadError &o) const
Definition common.hpp:45
ReadErrorCode code
Error code.
Definition common.hpp:41
static const ReadError SIZE_EXCEEDED
Definition common.hpp:55
bool operator==(const ReadErrorCode &o) const
Definition common.hpp:47
Result< size_t, typename io::Writer< WI >::ErrType > fmt(io::Writer< WI > &writer, const io::FormatOptions &)
Definition common.hpp:58
bool operator!=(const ReadErrorCode &o) const
Definition common.hpp:51
bool operator!=(const ReadError &o) const
Definition common.hpp:49
static const ReadError ALLOCATION_FAILED
Definition common.hpp:54
size_t pos
Human-readable position (i.e.
Definition common.hpp:43
static const ReadError END_OF_FILE
Definition common.hpp:53
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