Blender V5.0
BLI_csv_parse.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_any.hh"
10#include "BLI_function_ref.hh"
12#include "BLI_offset_indices.hh"
13#include "BLI_string_ref.hh"
14#include "BLI_vector.hh"
15
17
22class CsvRecord {
23 private:
24 Span<Span<char>> fields_;
25
26 public:
27 CsvRecord(Span<Span<char>> fields);
28
30 int64_t size() const;
31 IndexRange index_range() const;
32
34 Span<char> field(const int64_t index) const;
35 StringRef field_str(const int64_t index) const;
36};
37
42 private:
44 Span<Span<char>> fields_;
45
46 public:
48
50 int64_t size() const;
51 IndexRange index_range() const;
52
54 CsvRecord record(const int64_t index) const;
55};
56
73
95std::optional<Vector<Any<>>> parse_csv_in_chunks(
96 const Span<char> buffer,
98 FunctionRef<void(const CsvRecord &record)> process_header,
99 FunctionRef<Any<>(const CsvRecords &records)> process_records);
100
105template<typename ChunkT>
106inline std::optional<Vector<ChunkT>> parse_csv_in_chunks(
107 const Span<char> buffer,
109 FunctionRef<void(const CsvRecord &record)> process_header,
110 FunctionRef<ChunkT(const CsvRecords &records)> process_records)
111{
112 std::optional<Vector<Any<>>> result = parse_csv_in_chunks(
113 buffer, options, process_header, [&](const CsvRecords &records) {
114 return Any<>(process_records(records));
115 });
116 if (!result.has_value()) {
117 return std::nullopt;
118 }
119 Vector<ChunkT> result_chunks;
120 result_chunks.reserve(result->size());
121 for (Any<> &value : *result) {
122 result_chunks.append(std::move(value.get<ChunkT>()));
123 }
124 return result_chunks;
125}
126
134 const CsvParseOptions &options,
135 LinearAllocator<> &allocator);
136
137/* -------------------------------------------------------------------- */
140
141inline CsvRecord::CsvRecord(Span<Span<char>> fields) : fields_(fields) {}
142
144{
145 return fields_.size();
146}
147
149{
150 return fields_.index_range();
151}
152
153inline Span<char> CsvRecord::field(const int64_t index) const
154{
155 BLI_assert(index >= 0);
156 if (index >= fields_.size()) {
157 return {};
158 }
159 return fields_[index];
160}
161
162inline StringRef CsvRecord::field_str(const int64_t index) const
163{
164 const Span<char> value = this->field(index);
165 return StringRef(value.data(), value.size());
166}
167
169
170/* -------------------------------------------------------------------- */
173
175 : offsets_(offsets), fields_(fields)
176{
177}
178
180{
181 return offsets_.size();
182}
183
185{
186 return offsets_.index_range();
187}
188
189inline CsvRecord CsvRecords::record(const int64_t index) const
190{
191 return CsvRecord(fields_.slice(offsets_[index]));
192}
193
195
196/* -------------------------------------------------------------------- */
199
200namespace detail {
201
212int64_t find_end_of_simple_field(Span<char> buffer, int64_t start, char delimiter);
213
223std::optional<int64_t> find_end_of_quoted_field(Span<char> buffer,
224 int64_t start,
225 char quote,
226 Span<char> escape_chars);
227
236std::optional<int64_t> parse_record_fields(const Span<char> buffer,
237 const int64_t start,
238 const char delimiter,
239 const char quote,
240 const Span<char> quote_escape_chars,
241 Vector<Span<char>> &r_fields);
242
243} // namespace detail
244
246
247} // namespace blender::csv_parse
#define BLI_assert(a)
Definition BLI_assert.h:46
long long int int64_t
constexpr IndexRange index_range() const
constexpr const T * data() const
Definition BLI_span.hh:215
constexpr int64_t size() const
Definition BLI_span.hh:252
void append(const T &value)
void reserve(const int64_t min_capacity)
CsvRecord(Span< Span< char > > fields)
StringRef field_str(const int64_t index) const
Span< char > field(const int64_t index) const
CsvRecords(OffsetIndices< int64_t > offsets, Span< Span< char > > fields)
CsvRecord record(const int64_t index) const
CCL_NAMESPACE_BEGIN struct Options options
#define str(s)
int64_t find_end_of_simple_field(Span< char > buffer, int64_t start, char delimiter)
Definition csv_parse.cc:284
std::optional< int64_t > parse_record_fields(const Span< char > buffer, const int64_t start, const char delimiter, const char quote, const Span< char > quote_escape_chars, Vector< Span< char > > &r_fields)
Definition csv_parse.cc:199
std::optional< int64_t > find_end_of_quoted_field(Span< char > buffer, int64_t start, char quote, Span< char > escape_chars)
Definition csv_parse.cc:299
std::optional< Vector< Any<> > > parse_csv_in_chunks(const Span< char > buffer, const CsvParseOptions &options, FunctionRef< void(const CsvRecord &record)> process_header, FunctionRef< Any<>(const CsvRecords &records)> process_records)
Definition csv_parse.cc:91
StringRef unescape_field(const StringRef str, const CsvParseOptions &options, LinearAllocator<> &allocator)
Definition csv_parse.cc:169