| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "utils/file/FileUtils.h" |
| |
| #include <zlib.h> |
| |
| #include <algorithm> |
| #include <iostream> |
| |
| namespace org { |
| namespace apache { |
| namespace nifi { |
| namespace minifi { |
| namespace utils { |
| namespace file { |
| |
| uint64_t computeChecksum(const std::string &file_name, uint64_t up_to_position) { |
| constexpr uint64_t BUFFER_SIZE = 4096u; |
| std::array<char, std::size_t{BUFFER_SIZE}> buffer; |
| |
| std::ifstream stream{file_name, std::ios::in | std::ios::binary}; |
| |
| uLong checksum = 0; |
| uint64_t remaining_bytes_to_be_read = up_to_position; |
| |
| while (stream && remaining_bytes_to_be_read > 0) { |
| stream.read(buffer.data(), std::min(BUFFER_SIZE, remaining_bytes_to_be_read)); |
| uInt bytes_read = gsl::narrow<uInt>(stream.gcount()); |
| checksum = crc32(checksum, reinterpret_cast<unsigned char*>(buffer.data()), bytes_read); |
| remaining_bytes_to_be_read -= bytes_read; |
| } |
| |
| return checksum; |
| } |
| |
| bool contains(const std::filesystem::path& file_path, std::string_view text_to_search) { |
| gsl_Expects(text_to_search.size() <= 8192); |
| gsl_ExpectsAudit(std::filesystem::exists(file_path)); |
| std::array<char, 8192> buf1{}; |
| std::array<char, 8192> buf2{}; |
| gsl::span<char> left = buf1; |
| gsl::span<char> right = buf2; |
| |
| const auto charat = [&](size_t idx) { |
| if (idx < left.size()) { |
| return left[idx]; |
| } else if (idx < left.size() + right.size()) { |
| return right[idx - left.size()]; |
| } else { |
| return '\0'; |
| } |
| }; |
| const auto check_range = [&](size_t start, size_t end) -> size_t { |
| for (size_t i = start; i < end; ++i) { |
| size_t j{}; |
| for (j = 0; j < text_to_search.size(); ++j) { |
| if (charat(i + j) != text_to_search[j]) break; |
| } |
| if (j == text_to_search.size()) return true; |
| } |
| return false; |
| }; |
| |
| std::ifstream ifs{file_path, std::ios::binary}; |
| ifs.read(right.data(), gsl::narrow<std::streamsize>(right.size())); |
| do { |
| std::swap(left, right); |
| ifs.read(right.data(), gsl::narrow<std::streamsize>(right.size())); |
| if (check_range(0, left.size())) return true; |
| } while (ifs); |
| return check_range(left.size(), left.size() + right.size()); |
| } |
| |
| } // namespace file |
| } // namespace utils |
| } // namespace minifi |
| } // namespace nifi |
| } // namespace apache |
| } // namespace org |