Line data Source code
1 : #include "ioUtils.h" 2 : #include "elsaDefines.h" 3 : 4 : #include <algorithm> 5 : #include <cctype> 6 : #include <cstdlib> 7 : 8 : namespace elsa 9 : { 10 : void StringUtils::trim(std::string& str) 11 66 : { 12 : // trim whitespace from beginning 13 66 : str.erase(str.begin(), std::find_if(str.begin(), str.end(), 14 97 : [](int ch) { return std::isspace(ch) == 0; })); 15 : // trim whitespace from end 16 66 : str.erase( 17 97 : std::find_if(str.rbegin(), str.rend(), [](int ch) { return std::isspace(ch) == 0; }) 18 66 : .base(), 19 66 : str.end()); 20 66 : } 21 : 22 : void StringUtils::toLower(std::string& str) 23 37 : { 24 37 : std::transform(str.begin(), str.end(), str.begin(), 25 303 : [](unsigned char c) { return std::tolower(c); }); 26 37 : } 27 : 28 : void StringUtils::toUpper(std::string& str) 29 2 : { 30 2 : std::transform(str.begin(), str.end(), str.begin(), 31 22 : [](unsigned char c) { return std::toupper(c); }); 32 2 : } 33 : 34 : index_t DataUtils::getSizeOfDataType(DataUtils::DataType type) 35 11 : { 36 11 : switch (type) { 37 1 : case DataType::INT8: 38 2 : case DataType::UINT8: 39 2 : return 1; 40 1 : case DataType::INT16: 41 2 : case DataType::UINT16: 42 2 : return 2; 43 1 : case DataType::INT32: 44 2 : case DataType::UINT32: 45 6 : case DataType::FLOAT32: 46 6 : return 4; 47 2 : case DataType::FLOAT64: 48 1 : return 8; 49 : 50 2 : default: 51 0 : throw InvalidArgumentError("DataUtils::getSizeOfDataType: unknown data type"); 52 11 : } 53 11 : } 54 : 55 : template <typename data_t> 56 : data_t DataUtils::parse(const std::string& str) 57 15 : { 58 15 : data_t value; 59 15 : std::stringstream convert(str); 60 15 : convert >> value; 61 15 : if (convert.fail()) 62 1 : throw Error("DataUtils::parse: failed to interpret string"); 63 14 : return value; 64 14 : } 65 : 66 : template <typename data_t> 67 : std::vector<data_t> DataUtils::parseVector(const std::string& str) 68 8 : { 69 8 : std::vector<data_t> dataVector; 70 : 71 8 : data_t value; 72 8 : std::stringstream convert(str); 73 24 : while (!convert.eof()) { 74 17 : convert >> value; 75 17 : if (convert.fail()) 76 1 : throw Error("DataUtils::parseVector: failed to interpret string"); 77 16 : dataVector.push_back(value); 78 16 : } 79 : 80 8 : return dataVector; 81 8 : } 82 : 83 : template <typename raw_data_t, typename data_t> 84 : void DataUtils::parseRawData(std::istream& file, DataContainer<data_t>& data) 85 4 : { 86 4 : auto sizeInElements = static_cast<std::size_t>(data.getSize()); 87 4 : auto sizeInBytes = static_cast<index_t>(sizeInElements * sizeof(raw_data_t)); 88 : 89 : // allocate temporary storage 90 4 : auto ptr = std::make_unique<raw_data_t[]>(sizeInElements); 91 4 : if (!ptr) 92 0 : throw Error("DataUtils::parseRawData: failed allocating memory"); 93 : 94 : // parse data into the storage 95 4 : file.read(reinterpret_cast<char*>(ptr.get()), sizeInBytes); 96 4 : if (file.gcount() != sizeInBytes) 97 0 : throw Error("DataUtils::parseRawData: failed to read sufficient data"); 98 : 99 : // perform a component-wise copy to the data container 100 433 : for (std::size_t i = 0; i < sizeInElements; ++i) 101 429 : data[static_cast<index_t>(i)] = static_cast<data_t>(ptr[i]); 102 4 : } 103 : 104 : std::string FileSystemUtils::getAbsolutePath(std::string path, std::string base) 105 1 : { 106 : // note: this should really be done with C++17 <filesystem>... if it were universally 107 : // available 108 : 109 : // split off filename at end 110 1 : auto found = base.find_last_of("/\\"); 111 1 : if (found == std::string::npos) 112 1 : base = "."; 113 0 : else 114 0 : base = base.substr(0, found); 115 : 116 : // use POSIX realpath [TODO: will not work on Windows!] 117 1 : char* resolved = realpath(base.c_str(), nullptr); 118 1 : std::string basePath(resolved); 119 1 : free(resolved); 120 : 121 1 : return (basePath + "/" + path); 122 1 : } 123 : 124 : // ------------------------------------------ 125 : // explicit template instantiation 126 : template float DataUtils::parse(const std::string&); 127 : template double DataUtils::parse(const std::string&); 128 : template index_t DataUtils::parse(const std::string&); 129 : 130 : template std::vector<float> DataUtils::parseVector(const std::string&); 131 : template std::vector<double> DataUtils::parseVector(const std::string&); 132 : template std::vector<index_t> DataUtils::parseVector(const std::string&); 133 : 134 : template void DataUtils::parseRawData<uint16_t, float>(std::istream&, DataContainer<float>&); 135 : template void DataUtils::parseRawData<float, float>(std::istream&, DataContainer<float>&); 136 : template void DataUtils::parseRawData<double, float>(std::istream&, DataContainer<float>&); 137 : template void DataUtils::parseRawData<uint16_t, double>(std::istream&, DataContainer<double>&); 138 : template void DataUtils::parseRawData<float, double>(std::istream&, DataContainer<double>&); 139 : template void DataUtils::parseRawData<double, double>(std::istream&, DataContainer<double>&); 140 : template void DataUtils::parseRawData<uint16_t, index_t>(std::istream&, 141 : DataContainer<index_t>&); 142 : template void DataUtils::parseRawData<float, index_t>(std::istream&, DataContainer<index_t>&); 143 : template void DataUtils::parseRawData<double, index_t>(std::istream&, DataContainer<index_t>&); 144 : } // namespace elsa