// Sort file paths in reverse order when the file names are numbers. // The order is reversed, because the collection is treated as a stack. bool DirectoryCompare(const directory_entry & d1, const directory_entry & d2) { string f1 = d1.path().stem().string(); string f2 = d2.path().stem().string(); int n1 = atoi(f1.c_str()); // 0 for non-numeric int n2 = atoi(f2.c_str()); // 0 for non-numeric return n2 < n1; // reverse-sort }
/* ** Determines whether the directory entry's name matches the glob ** pattern. */ bool operator()(const directory_entry& ent) const noexcept { #ifndef NDEBUG assert(m_pat.length() > 0); #endif // Offset into pattern that we are matching. auto i = 0u; // Offset into the file name. auto j = 0u; auto s = ent.name(); do switch(m_pat[i]) { default: if (m_pat[i++] != s[j++]) return false; continue; case '*': ++i; return match_wildcard(s, i, j); case '?': ++i; ++j; continue; case '[': ++i; if (!match_group(s, i, j)) return false; continue; case '\\': ++i; if (m_pat[i++] != s[j++]) return false; continue; } while (i != m_pat.length() && j != s.length()); return (i == m_pat.length() || m_pat[i] == '*') && j == s.length(); }
void hash_entry(const directory_entry &i, crypto_generichash_state &state) { auto &p = i.path(); size_t size = 0; if (is_regular_file(i.status())) size = (size_t)file_size(i.path()); if (is_regular(i.status())) { char chunk_buffer[16 * 1024]; size_t chunk_buffer_size = sizeof(chunk_buffer); size_t chunk_cnt = size / chunk_buffer_size; size_t last_chunk_size = size % chunk_buffer_size; std::ifstream file(p.native(), std::ifstream::binary); if (last_chunk_size != 0) ++chunk_cnt; else last_chunk_size = chunk_buffer_size; for (size_t chunk = 0; chunk < chunk_cnt; ++chunk) { size_t chunk_size = chunk_buffer_size; if (chunk == chunk_cnt - 1) chunk_size = last_chunk_size; file.read(&chunk_buffer[0], chunk_size); crypto_generichash_update(&state, (unsigned char *)&chunk_buffer[0], chunk_size); } return; } if (is_symlink(i.status())) { path sym_path(::read_symlink(p)); std::string s = sym_path.generic_string(); crypto_generichash_update(&state, (unsigned char *) s.c_str(), s.length()); return; } if (is_directory(i.status())) { crypto_generichash_update(&state, (const unsigned char *)"d", 1); return; } }
std::string operator()(const directory_entry &p) const { return p.path().filename().c_str(); }
std::string dispatch(directory_entry const & from) { return from.path().string(); }