std::pair<TweakableState, double> TweakableParser<double>::parse(Containers::ArrayView<const char> value) { char* end; const double result = std::strtod(value, &end); if(end == value.begin() || std::find(value.begin(), value.end(), '.') == value.end()) { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a floating-point literal"; return {TweakableState::Recompile, {}}; } if(end != value.end()) { Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after a floating-point literal"; return {TweakableState::Recompile, {}}; } return {TweakableState::Success, result}; }
std::pair<TweakableState, unsigned long long> TweakableParser<unsigned long long>::parse(Containers::ArrayView<const char> value) { const std::pair<const char*, int> valueBase = integerBase(value); char* end; const int result = std::strtoull(valueBase.first, &end, valueBase.second); if(end == value.begin()) { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not an integer literal"; return {TweakableState::Recompile, {}}; } if(value.size() < 3 || (value[value.size() - 1] != 'l' && value[value.size() - 1] != 'L' && value[value.size() - 2] != 'l' && value[value.size() - 2] != 'L' && value[value.size() - 2] != 'u' && value[value.size() - 2] != 'U')) { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected ull"; return {TweakableState::Recompile, {}}; } if(end != value.end() - 3) { Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after an integer literal"; return {TweakableState::Recompile, {}}; } return {TweakableState::Success, result}; }
std::pair<TweakableState, long double> TweakableParser<long double>::parse(Containers::ArrayView<const char> value) { char* end; const long double result = std::strtold(value, &end); if(end == value.begin() || std::find(value.begin(), value.end(), '.') == value.end()) { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not a floating-point literal"; return {TweakableState::Recompile, {}}; } /* If value would be empty, the above catches that */ if(value.back() != 'l' && value.back() != 'L') { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected l"; return {TweakableState::Recompile, {}}; } if(end != value.end() - 1) { Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after a floating-point literal"; return {TweakableState::Recompile, {}}; } return {TweakableState::Success, result}; }
void JpegImporter::doOpenData(const Containers::ArrayView<const char> data) { /* Because here we're copying the data and using the _in to check if file is opened, having them nullptr would mean openData() would fail without any error message. It's not possible to do this check on the importer side, because empty file is valid in some formats (OBJ or glTF). We also can't do the full import here because then doImage2D() would need to copy the imported data instead anyway (and the uncompressed size is much larger). This way it'll also work nicely with a future openMemory(). */ if(data.empty()) { Error{} << "Trade::JpegImporter::openData(): the file is empty"; return; } _in = Containers::Array<unsigned char>(data.size()); std::copy(data.begin(), data.end(), _in.begin()); }
std::pair<TweakableState, int> TweakableParser<int>::parse(Containers::ArrayView<const char> value) { const std::pair<const char*, int> valueBase = integerBase(value); char* end; const int result = std::strtol(valueBase.first, &end, valueBase.second); if(end == value.begin()) { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not an integer literal"; return {TweakableState::Recompile, {}}; } if(end != value.end()) { Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after an integer literal"; return {TweakableState::Recompile, {}}; } return {TweakableState::Success, result}; }
std::pair<TweakableState, long> TweakableParser<long>::parse(Containers::ArrayView<const char> value) { const std::pair<const char*, int> valueBase = integerBase(value); char* end; const long result = std::strtol(valueBase.first, &end, valueBase.second); if(end == value.begin()) { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "is not an integer literal"; return {TweakableState::Recompile, {}}; } /* If value would be empty, the above catches that */ if(value.back() != 'l' && value.back() != 'L') { Warning{} << "Utility::TweakableParser:" << std::string{value, value.size()} << "has an unexpected suffix, expected l"; return {TweakableState::Recompile, {}}; } if(end != value.end() - 1) { Warning{} << "Utility::TweakableParser: unexpected characters" << std::string{const_cast<const char*>(end), value.end()} << "after an integer literal"; return {TweakableState::Recompile, {}}; } return {TweakableState::Success, result}; }
void JpegImporter::doOpenData(const Containers::ArrayView<const char> data) { _in = Containers::Array<unsigned char>(data.size()); std::copy(data.begin(), data.end(), _in.begin()); }
void WavImporter::doOpenData(Containers::ArrayView<const char> data) { /* Check file size */ if(data.size() < sizeof(WavHeader)) { Error() << "Audio::WavImporter::openData(): the file is too short:" << data.size() << "bytes"; return; } /* Get header contents and fix endianness */ WavHeader header(*reinterpret_cast<const WavHeader*>(data.begin())); Utility::Endianness::littleEndianInPlace(header.chunkSize, header.subChunk1Size, header.audioFormat, header.numChannels, header.sampleRate, header.byteRate, header.blockAlign, header.bitsPerSample, header.subChunk2Size); /* Check file signature */ if(std::strncmp(header.chunkId, "RIFF", 4) != 0 || std::strncmp(header.format, "WAVE", 4) != 0 || std::strncmp(header.subChunk1Id, "fmt ", 4) != 0 || std::strncmp(header.subChunk2Id, "data", 4) != 0) { Error() << "Audio::WavImporter::openData(): the file signature is invalid"; return; } /* Check file size */ if(header.chunkSize + 8 != data.size()) { Error() << "Audio::WavImporter::openData(): the file has improper size, expected" << header.chunkSize + 8 << "but got" << data.size(); return; } /* Check PCM format */ if(header.audioFormat != 1) { Error() << "Audio::WavImporter::openData(): unsupported audio format" << header.audioFormat; return; } /* Verify more things */ if(header.subChunk1Size != 16 || header.subChunk2Size + 44 != data.size() || header.blockAlign != header.numChannels*header.bitsPerSample/8 || header.byteRate != header.sampleRate*header.blockAlign) { Error() << "Audio::WavImporter::openData(): the file is corrupted"; return; } /* Decide about format */ if(header.numChannels == 1 && header.bitsPerSample == 8) _format = Buffer::Format::Mono8; else if(header.numChannels == 1 && header.bitsPerSample == 16) _format = Buffer::Format::Mono16; else if(header.numChannels == 2 && header.bitsPerSample == 8) _format = Buffer::Format::Stereo8; else if(header.numChannels == 2 && header.bitsPerSample == 16) _format = Buffer::Format::Stereo16; else { Error() << "Audio::WavImporter::openData(): unsupported channel count" << header.numChannels << "with" << header.bitsPerSample << "bits per sample"; return; } /* Save frequency */ _frequency = header.sampleRate; /** @todo Convert the data from little endian too */ CORRADE_INTERNAL_ASSERT(!Utility::Endianness::isBigEndian()); /* Copy the data */ _data = Containers::Array<char>(header.subChunk2Size); std::copy(data.begin()+sizeof(WavHeader), data.end(), _data.begin()); return; }
void TgaImporter::doOpenData(const Containers::ArrayView<const char> data) { _in = Containers::Array<char>{data.size()}; std::copy(data.begin(), data.end(), _in.begin()); }