27#include "serialization/deserialize.h"
29#include <vclib/concepts/mesh/elements/element.h>
30#include <vclib/misc/string.h>
31#include <vclib/misc/tokenizer.h>
50template<
bool THROW = true>
51inline std::string readNextNonEmptyLine(std::istream& file)
55 std::getline(file, line);
56 if constexpr (THROW) {
58 throw MalformedFileException(
"Unexpected end of file.");
61 if (file && line.size() > 0) {
62 removeCarriageReturn(line);
64 }
while (file && line.size() == 0);
80inline std::ifstream openInputFileStream(
81 const std::string& filename,
82 const std::string& ext =
"")
84 setlocale(LC_ALL,
"C");
86 std::string actualfilename = filename;
91 std::ifstream fp(actualfilename, std::ifstream::binary);
92 fp.imbue(std::locale().classic());
95 throw CannotOpenFileException(filename);
109inline std::string readNextNonEmptyLine(std::istream& file)
111 return detail::readNextNonEmptyLine<>(file);
121inline std::string readNextNonEmptyLineNoThrow(std::istream& file)
123 return detail::readNextNonEmptyLine<false>(file);
138inline Tokenizer readAndTokenizeNextNonEmptyLine(
140 std::vector<char> separators = {
' ',
'\t'})
146 line = readNextNonEmptyLine(file);
147 tokenizer = Tokenizer(line, separators);
148 }
while (tokenizer.begin() == tokenizer.end());
163inline Tokenizer readAndTokenizeNextNonEmptyLineNoThrow(
165 std::vector<char> separators = {
' ',
'\t'})
171 line = readNextNonEmptyLineNoThrow(file);
172 tokenizer = Tokenizer(line, separators);
173 }
while (file && tokenizer.begin() == tokenizer.end());
195T readChar(std::istream& file, std::endian end = std::endian::native)
198 deserialize(file, c, end);
199 return static_cast<T
>(c);
212T readUChar(std::istream& file, std::endian end = std::endian::native)
215 deserialize(file, c, end);
216 return static_cast<T
>(c);
229T readShort(std::istream& file, std::endian end = std::endian::native)
232 deserialize(file, c, end);
233 return static_cast<T
>(c);
246T readUShort(std::istream& file, std::endian end = std::endian::native)
249 deserialize(file, c, end);
250 return static_cast<T
>(c);
263T readInt(std::istream& file, std::endian end = std::endian::native)
266 deserialize(file, c, end);
267 return static_cast<T
>(c);
280T readUInt(std::istream& file, std::endian end = std::endian::native)
283 deserialize(file, c, end);
284 return static_cast<T
>(c);
305 std::endian end = std::endian::native,
306 bool isColor =
false)
309 deserialize(file, c, end);
310 if constexpr (std::integral<T>) {
312 return static_cast<T
>(c * 255);
314 return static_cast<T
>(c);
335 std::endian end = std::endian::native,
336 bool isColor =
false)
339 deserialize(file, c, end);
340 if constexpr (std::integral<T>) {
342 return static_cast<T
>(c * 255);
344 return static_cast<T
>(c);
371 std::endian end = std::endian::native,
372 bool isColor =
false)
376 case PrimitiveType::CHAR: p = readChar<T>(file, end);
break;
377 case PrimitiveType::UCHAR: p = readUChar<T>(file, end);
break;
378 case PrimitiveType::SHORT: p = readShort<T>(file, end);
break;
379 case PrimitiveType::USHORT: p = readUShort<T>(file, end);
break;
380 case PrimitiveType::INT: p = readInt<T>(file, end);
break;
381 case PrimitiveType::UINT: p = readUInt<T>(file, end);
break;
382 case PrimitiveType::FLOAT: p = readFloat<T>(file, end, isColor);
break;
383 case PrimitiveType::DOUBLE: p = readDouble<T>(file, end, isColor);
break;
384 default: assert(0); p = 0;
387 if (isColor && !std::is_integral<T>::value)
392template<ElementConcept El>
393void readCustomComponent(
396 const std::string& cName,
398 std::endian end = std::endian::native)
400 std::type_index ti = elem.customComponentType(cName);
401 if (ti ==
typeid(
char))
402 elem.template customComponent<char>(cName) =
403 readPrimitiveType<char>(file, type, end);
404 else if (ti ==
typeid(
unsigned char))
405 elem.template customComponent<unsigned char>(cName) =
406 readPrimitiveType<unsigned char>(file, type, end);
407 else if (ti ==
typeid(
short))
408 elem.template customComponent<short>(cName) =
409 readPrimitiveType<short>(file, type, end);
410 else if (ti ==
typeid(
unsigned short))
411 elem.template customComponent<unsigned short>(cName) =
412 readPrimitiveType<unsigned short>(file, type, end);
413 else if (ti ==
typeid(
int))
414 elem.template customComponent<int>(cName) =
415 readPrimitiveType<int>(file, type, end);
416 else if (ti ==
typeid(
unsigned int))
417 elem.template customComponent<uint>(cName) =
418 readPrimitiveType<uint>(file, type, end);
419 else if (ti ==
typeid(
float))
420 elem.template customComponent<float>(cName) =
421 readPrimitiveType<float>(file, type, end);
422 else if (ti ==
typeid(
double))
423 elem.template customComponent<double>(cName) =
424 readPrimitiveType<double>(file, type, end);
432T readChar(Tokenizer::iterator& token, std::endian = std::endian::native)
434 return std::stoi(*token++);
438T readUChar(Tokenizer::iterator& token, std::endian = std::endian::native)
440 return std::stoi(*token++);
444T readShort(Tokenizer::iterator& token, std::endian = std::endian::native)
446 return std::stoi(*token++);
450T readUShort(Tokenizer::iterator& token, std::endian = std::endian::native)
452 return std::stoi(*token++);
456T readInt(Tokenizer::iterator& token, std::endian = std::endian::native)
458 return std::stoi(*token++);
462T readUInt(Tokenizer::iterator& token, std::endian = std::endian::native)
464 return std::stoi(*token++);
469 Tokenizer::iterator& token,
470 std::endian = std::endian::native,
471 bool isColor =
false)
473 if (isColor && std::is_integral<T>::value) {
474 return std::stod(*token++) * 255;
477 return std::stod(*token++);
483 Tokenizer::iterator& token,
484 std::endian = std::endian::native,
485 bool isColor =
false)
487 if (isColor && std::is_integral<T>::value) {
488 return std::stod(*token++) * 255;
491 return std::stod(*token++);
497 Tokenizer::iterator& token,
499 std::endian = std::endian::native,
500 bool isColor =
false)
504 case PrimitiveType::CHAR:
505 case PrimitiveType::UCHAR:
506 case PrimitiveType::SHORT:
507 case PrimitiveType::USHORT:
508 case PrimitiveType::INT:
509 case PrimitiveType::UINT: p = std::stoi(*token++);
break;
510 case PrimitiveType::FLOAT:
511 case PrimitiveType::DOUBLE:
513 p = std::stod(*token++) * 255;
516 p = std::stod(*token++);
519 default: assert(0); p = 0;
522 if (isColor && !std::is_integral<T>::value)
527template<ElementConcept El>
528void readCustomComponent(
529 Tokenizer::iterator& token,
531 const std::string& cName,
533 std::endian = std::endian::native)
535 std::type_index ti = elem.customComponentType(cName);
536 if (ti ==
typeid(
char))
537 elem.template customComponent<char>(cName) =
538 readPrimitiveType<char>(token, type);
539 else if (ti ==
typeid(
unsigned char))
540 elem.template customComponent<unsigned char>(cName) =
541 readPrimitiveType<unsigned char>(token, type);
542 else if (ti ==
typeid(
short))
543 elem.template customComponent<short>(cName) =
544 readPrimitiveType<short>(token, type);
545 else if (ti ==
typeid(
unsigned short))
546 elem.template customComponent<unsigned short>(cName) =
547 readPrimitiveType<unsigned short>(token, type);
548 else if (ti ==
typeid(
int))
549 elem.template customComponent<int>(cName) =
550 readPrimitiveType<int>(token, type);
551 else if (ti ==
typeid(
unsigned int))
552 elem.template customComponent<uint>(cName) =
553 readPrimitiveType<uint>(token, type);
554 else if (ti ==
typeid(
float))
555 elem.template customComponent<float>(cName) =
556 readPrimitiveType<float>(token, type);
557 else if (ti ==
typeid(
double))
558 elem.template customComponent<double>(cName) =
559 readPrimitiveType<double>(token, type);
static std::string addExtensionIfNeeded(const std::string &filename, const std::string &ext)
Adds an extension to a file name if it doesn't already have it.
Definition file_info.h:271
PrimitiveType
A simple type that enumerates the main primitive types.
Definition base.h:58