MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ open()

bool MayaFlux::IO::DelimitedTextReader::open ( const std::string &  filepath,
FileReadOptions  options = FileReadOptions::ALL 
)
overridevirtual

Open a CSV or TSV file and establish its Composite layout.

Parameters
filepathSource path.
optionsFileReader options.
Returns
True when the file and header are valid.

Implements MayaFlux::IO::FileReader.

Definition at line 213 of file DelimitedTextReader.cpp.

215{
216 close();
217 m_last_error.clear();
218 if (!can_read(filepath)) {
219 m_last_error = "Expected a .csv or .tsv file";
220 return false;
221 }
222
224 m_last_error = "Headerless input requires a supplied CompositeLayout";
225 return false;
226 }
227
228 m_filepath = resolve_path(filepath);
231 : (extension_of(filepath) == ".tsv" ? '\t' : ',');
232
233 m_file.open(m_filepath, std::ios::binary);
234 if (!m_file) {
235 m_last_error = "Cannot open delimited text file";
236 return false;
237 }
238
239 std::vector<ParsedField> names;
240 bool at_end = false;
241 if (m_has_header) {
242 if (!read_record(names, at_end) || at_end) {
243 if (at_end)
244 m_last_error = "Delimited text file has no header";
245 close();
246 return false;
247 }
248
249 if (!names.empty() && names.front().value.starts_with("\xEF\xBB\xBF"))
250 names.front().value.erase(0, 3);
251 }
252
253 if (m_requested_layout) {
255 const auto& fields = m_layout->fields();
256 if (fields.empty() || (m_has_header && fields.size() != names.size())) {
257 m_last_error = "Header does not match the supplied CompositeLayout";
258 close();
259 return false;
260 }
261
262 for (size_t i = 0; i < fields.size(); ++i) {
263 if (!supported_field(fields[i])
264 || (m_has_header && fields[i].name != names[i].value)) {
265 m_last_error = "Unsupported or mismatched Composite field: " + fields[i].name;
266 close();
267 return false;
268 }
269 }
270 } else {
271 Kakshya::CompositeLayout layout;
272 for (auto& name : names) {
273 if (!layout.add_field<std::string>(std::move(name.value))) {
274 m_last_error = "Header field names must be nonempty and unique";
275 close();
276 return false;
277 }
278 }
279
280 m_layout = std::move(layout);
281 }
282
283 Kakshya::CompositeArray empty(*m_layout);
284 m_layout = empty.layout();
285
286 m_data_start = m_file.tellg();
287 if (m_data_start == std::streampos(-1)) {
288 m_file.clear();
289 m_file.seekg(0, std::ios::end);
290 m_data_start = m_file.tellg();
291 }
292
293 m_file.clear();
294 m_file.seekg(m_data_start);
295
296 m_row_position = 0;
297 m_at_end = false;
298 return true;
299}
glm::vec3 value
std::string name
Definition VKDevice.cpp:123
std::optional< Kakshya::CompositeLayout > m_requested_layout
bool read_record(std::vector< ParsedField > &fields, bool &at_end)
bool can_read(const std::string &filepath) const override
Check for the .csv or .tsv extension.
std::optional< Kakshya::CompositeLayout > m_layout
void close() override
Close the input and release its active layout.
static std::string resolve_path(const std::string &filepath)
Resolve a filepath against the project source root if not found as-is.

References MayaFlux::Kakshya::CompositeLayout::add_field(), can_read(), close(), MayaFlux::Kakshya::CompositeArray::layout(), m_active_delimiter, m_at_end, m_data_start, m_delimiter, m_file, m_filepath, m_has_header, MayaFlux::IO::CompositeReader::m_last_error, m_layout, m_requested_layout, m_row_position, name, read_record(), MayaFlux::IO::FileReader::resolve_path(), and value.

+ Here is the call graph for this function: