rizin/librz/search/options.c
Khairul Azhar Kasmiran 3204f0c405
Use stdint types for ut64 and friends (#6276)
* Use `stdint` types for `ut64` and friends
* Use `inttypes.h` format specifiers
2026-04-22 21:43:04 +08:00

166 lines
5 KiB
C

// SPDX-FileCopyrightText: 2024 RizinOrg <info@rizin.re>
// SPDX-FileCopyrightText: 2024 deroad <wargio@libero.it>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_search.h>
#include "search_internal.h"
RZ_API RZ_OWN RzSearchOpt *rz_search_opt_new() {
RzSearchOpt *opt = RZ_NEW0(RzSearchOpt);
if (!opt) {
return NULL;
}
opt->max_threads = RZ_THREAD_N_CORES_ALL_AVAILABLE;
opt->chunk_size = RZ_SEARCH_DEFAULT_CHUNK_SIZE;
return opt;
}
RZ_API void rz_search_opt_free(RZ_NULLABLE RzSearchOpt *opt) {
if (!opt) {
return;
}
rz_search_find_opt_free(opt->find_opts);
free(opt);
}
RZ_API bool rz_search_opt_set_max_hits(RZ_NONNULL RzSearchOpt *opt, size_t max_hits) {
rz_return_val_if_fail(opt, false);
opt->max_hits = max_hits;
return true;
}
static bool set_chunk_size(RZ_NONNULL RzSearchOpt *opt, ut64 chunk_size) {
rz_return_val_if_fail(opt, false);
if (chunk_size < RZ_SEARCH_MIN_CHUNK_SIZE || chunk_size > RZ_SEARCH_MAX_CHUNK_SIZE) {
RZ_LOG_ERROR("search: Chunk size is not in range of %#" PFMT64x "-%#" PFMT64x " bytes.\n",
(ut64)RZ_SEARCH_MIN_CHUNK_SIZE,
(ut64)RZ_SEARCH_MAX_CHUNK_SIZE);
return false;
}
opt->chunk_size = chunk_size;
return true;
}
static bool element_chunk_ratio_ok(ut64 element_size, ut64 chunk_size) {
rz_return_val_if_fail(element_size != 0, false);
if (element_size >= chunk_size) {
return false;
}
return (chunk_size / element_size) >= RZ_SEARCH_MIN_ELEMENTS_PER_CHUNK;
}
/**
* \brief Sets opt->element_size and the updates the chunk size dependent on `element_size`.
* \param opt The search options.
* \param element_size The size in bytes of the element to search for.
*/
RZ_API bool rz_search_opt_set_chunk_size(RZ_NONNULL RzSearchOpt *opt, ut64 element_size) {
rz_return_val_if_fail(opt, false);
if (!element_chunk_ratio_ok(element_size, opt->chunk_size)) {
if (!set_chunk_size(opt, element_size * RZ_SEARCH_MIN_ELEMENTS_PER_CHUNK)) {
RZ_LOG_ERROR("search: Element to search is too big.\n");
return false;
}
}
opt->element_size = element_size;
return true;
}
RZ_API bool rz_search_opt_set_max_threads(RZ_NONNULL RzSearchOpt *opt, RzThreadNCores max_threads) {
rz_return_val_if_fail(opt, false);
opt->max_threads = max_threads;
return true;
}
/**
* \brief Returns the number of threads defined in the options \p opt.
*/
RZ_API size_t rz_search_opt_get_max_threads(RZ_NONNULL const RzSearchOpt *opt) {
rz_return_val_if_fail(opt, 0);
return opt->max_threads;
}
/**
* \brief Enables the printing of progress during the search.
*
* \param opt The search options to update.
* \param show_progress A string describing the progress type. Can be:
* - "off", "no", "false", "0": No progress is printed.
* - "interval": The currently searched in interval is printed.
* - else: Print number of current hits during search.
*
* \return True if options were correctly updated, false otherwise.
*/
RZ_API bool rz_search_opt_set_show_progress_from_str(RZ_NONNULL RzSearchOpt *opt, const char *show_progress) {
rz_return_val_if_fail(opt, false);
if (rz_str_is_false(show_progress)) {
opt->show_progress = RZ_SEARCH_PROGRESS_DISABLED;
} else if (RZ_STR_EQ(show_progress, "intervals")) {
opt->show_progress = RZ_SEARCH_PROGRESS_INTERVALS;
} else {
opt->show_progress = RZ_SEARCH_PROGRESS_NUM_HITS;
}
return true;
}
RZ_API RzSearchProgress rz_search_opt_get_show_progress(RZ_NONNULL RzSearchOpt *opt) {
rz_return_val_if_fail(opt, RZ_SEARCH_PROGRESS_DISABLED);
return opt->show_progress;
}
RZ_API bool rz_search_opt_set_cancel_cb(RZ_NONNULL RzSearchOpt *opt, RzSearchCancelCallback callback, void *user) {
rz_return_val_if_fail(opt, false);
opt->cancel_cb = callback;
opt->cancel_usr = user;
return true;
}
RZ_API bool rz_search_opt_set_find_options(RZ_NONNULL RzSearchOpt *opt, RZ_OWN RzSearchFindOpt *find_opts) {
if (!opt) {
rz_search_find_opt_free(find_opts);
rz_return_val_if_reached(false);
}
rz_search_find_opt_free(opt->find_opts);
opt->find_opts = find_opts;
return true;
}
RZ_API const RzSearchFindOpt *rz_search_opt_get_find_options(RZ_NONNULL const RzSearchOpt *opt) {
rz_return_val_if_fail(opt, NULL);
return opt->find_opts;
}
RZ_API RZ_OWN RzSearchFindOpt *rz_search_find_opt_new() {
RzSearchFindOpt *fopts = RZ_NEW0(RzSearchFindOpt);
if (!fopts) {
return NULL;
}
fopts->alignment = 1;
return fopts;
}
RZ_API void rz_search_find_opt_free(RZ_NULLABLE RzSearchFindOpt *opt) {
free(opt);
}
RZ_API bool rz_search_find_opt_set_overlap_match(RZ_NONNULL RzSearchFindOpt *opt, bool overlap_match) {
rz_return_val_if_fail(opt, false);
opt->match_overlap = overlap_match;
return true;
}
RZ_API bool rz_search_find_opt_get_overlap_match(RZ_NONNULL RzSearchFindOpt *opt) {
rz_return_val_if_fail(opt, false);
return opt->match_overlap;
}
RZ_API bool rz_search_find_opt_set_alignment(RZ_NONNULL RzSearchFindOpt *opt, size_t alignment) {
rz_return_val_if_fail(opt, false);
opt->alignment = alignment;
return true;
}
RZ_API ut16 rz_search_find_opt_get_alignment(RZ_NONNULL const RzSearchFindOpt *opt) {
rz_return_val_if_fail(opt, 0);
return opt->alignment;
}