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 0 : void StringUtils::trim(std::string& str) 11 : { 12 : // trim whitespace from beginning 13 0 : str.erase(str.begin(), std::find_if(str.begin(), str.end(), 14 0 : [](int ch) { return std::isspace(ch) == 0; })); 15 : // trim whitespace from end 16 0 : str.erase( 17 0 : std::find_if(str.rbegin(), str.rend(), [](int ch) { return std::isspace(ch) == 0; }) 18 0 : .base(), 19 0 : str.end()); 20 0 : } 21 : 22 0 : void StringUtils::toLower(std::string& str) 23 : { 24 0 : std::transform(str.begin(), str.end(), str.begin(), 25 0 : [](unsigned char c) { return std::tolower(c); }); 26 0 : } 27 : 28 0 : void StringUtils::toUpper(std::string& str) 29 : { 30 0 : std::transform(str.begin(), str.end(), str.begin(), 31 0 : [](unsigned char c) { return std::toupper(c); }); 32 0 : } 33 : 34 0 : index_t DataUtils::getSizeOfDataType(DataUtils::DataType type) 35 : { 36 0 : switch (type) { 37 0 : case DataType::INT8: 38 : case DataType::UINT8: 39 0 : return 1; 40 0 : case DataType::INT16: 41 : case DataType::UINT16: 42 0 : return 2; 43 0 : case DataType::INT32: 44 : case DataType::UINT32: 45 : case DataType::FLOAT32: 46 0 : return 4; 47 0 : case DataType::FLOAT64: 48 0 : return 8; 49 : 50 0 : default: 51 0 : throw InvalidArgumentError("DataUtils::getSizeOfDataType: unknown data type"); 52 : } 53 : } 54 : 55 : template <typename data_t> 56 0 : data_t DataUtils::parse(const std::string& str) 57 : { 58 : data_t value; 59 0 : std::stringstream convert(str); 60 0 : convert >> value; 61 0 : if (convert.fail()) 62 0 : throw Error("DataUtils::parse: failed to interpret string"); 63 0 : return value; 64 0 : } 65 : 66 : template <typename data_t> 67 0 : std::vector<data_t> DataUtils::parseVector(const std::string& str) 68 : { 69 0 : std::vector<data_t> dataVector; 70 : 71 : data_t value; 72 0 : std::stringstream convert(str); 73 0 : while (!convert.eof()) { 74 0 : convert >> value; 75 0 : if (convert.fail()) 76 0 : throw Error("DataUtils::parseVector: failed to interpret string"); 77 0 : dataVector.push_back(value); 78 : } 79 : 80 0 : return dataVector; 81 0 : } 82 : 83 : template <typename raw_data_t, typename data_t> 84 0 : void DataUtils::parseRawData(std::istream& file, DataContainer<data_t>& data) 85 : { 86 0 : auto sizeInElements = static_cast<std::size_t>(data.getSize()); 87 0 : auto sizeInBytes = static_cast<index_t>(sizeInElements * sizeof(raw_data_t)); 88 : 89 : // allocate temporary storage 90 0 : auto ptr = std::make_unique<raw_data_t[]>(sizeInElements); 91 0 : if (!ptr) 92 0 : throw Error("DataUtils::parseRawData: failed allocating memory"); 93 : 94 : // parse data into the storage 95 0 : file.read(reinterpret_cast<char*>(ptr.get()), sizeInBytes); 96 0 : 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 0 : for (std::size_t i = 0; i < sizeInElements; ++i) 101 0 : data[static_cast<index_t>(i)] = static_cast<data_t>(ptr[i]); 102 0 : } 103 : 104 0 : std::string FileSystemUtils::getAbsolutePath(std::string path, std::string base) 105 : { 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 0 : auto found = base.find_last_of("/\\"); 111 0 : if (found == std::string::npos) 112 0 : base = "."; 113 : else 114 0 : base = base.substr(0, found); 115 : 116 : // use POSIX realpath [TODO: will not work on Windows!] 117 0 : char* resolved = realpath(base.c_str(), nullptr); 118 0 : std::string basePath(resolved); 119 0 : free(resolved); 120 : 121 0 : return (basePath + "/" + path); 122 0 : } 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