From 62b0abfe5d3bb5db7c268e699bfdcf39ed0986aa Mon Sep 17 00:00:00 2001 From: Davin Shearer Date: Thu, 13 Jul 2023 16:14:23 -0400 Subject: [PATCH] WIP plugin support --- core/CMakeLists.txt | 7 +- core/src/examples/plugin_replace.c | 52 ++++++ core/src/examples/transform.c | 2 +- core/src/include/omega_edit/edit.h | 28 ++- core/src/include/omega_edit/plugins/replace.h | 53 ++++++ core/src/lib/change.cpp | 2 +- core/src/lib/check.cpp | 7 +- core/src/lib/edit.cpp | 45 ++++- core/src/lib/encode.c | 2 +- core/src/lib/filesystem.cpp | 4 +- core/src/lib/impl_/change_def.hpp | 2 +- core/src/lib/impl_/data_def.hpp | 2 +- core/src/lib/impl_/internal_fun.cpp | 4 +- core/src/lib/impl_/internal_fun.hpp | 4 +- core/src/lib/impl_/internal_fwd_defs.hpp | 2 +- core/src/lib/impl_/macros.h | 2 +- core/src/lib/impl_/model_segment_def.hpp | 2 +- core/src/lib/impl_/search_context_def.h | 2 +- core/src/lib/impl_/session_def.hpp | 4 +- core/src/lib/impl_/viewport_def.hpp | 2 +- core/src/lib/license.c | 2 +- core/src/lib/plugins/replace.c | 163 ++++++++++++++++++ core/src/lib/search.cpp | 11 +- core/src/lib/segment.cpp | 2 +- core/src/lib/session.cpp | 2 +- core/src/lib/stl_string_adapter.cpp | 2 +- core/src/lib/utility.c | 4 +- core/src/lib/version.c | 4 +- core/src/lib/viewport.cpp | 6 +- core/src/lib/visit.cpp | 2 +- core/src/tests/omega_test.cpp | 12 +- packages/client/tests/specs/data/csstest.html | 2 +- 32 files changed, 384 insertions(+), 56 deletions(-) create mode 100644 core/src/examples/plugin_replace.c create mode 100644 core/src/include/omega_edit/plugins/replace.h create mode 100644 core/src/lib/plugins/replace.c diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index e3d742859..a43d00c10 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -88,10 +88,12 @@ set(OMEGA_EDIT_SOURCE_FILES "src/include/omega_edit/utility.h" "src/lib/utility.c" "src/include/omega_edit/encode.h" "src/lib/encode.c" "src/include/omega_edit/filesystem.h" "src/lib/filesystem.cpp" + "src/include/omega_edit/plugins/replace.h" "src/lib/plugins/replace.c" "src/lib/impl_/macros.h" "src/lib/impl_/internal_fwd_defs.hpp" "src/lib/impl_/internal_fun.hpp" "src/lib/impl_/internal_fun.cpp" "src/lib/impl_/find.h" "src/lib/impl_/find.cpp" - "src/lib/impl_/data_def.hpp" "src/lib/impl_/model_def.hpp" "src/lib/impl_/model_segment_def.hpp") + "src/lib/impl_/data_def.hpp" "src/lib/impl_/model_def.hpp" "src/lib/impl_/model_segment_def.hpp" + ) # Don't add RPATH so we can manipulate the library search path using the environment at runtime set(CMAKE_MACOSX_RPATH OFF) @@ -124,6 +126,9 @@ endforeach () # EXAMPLES ####################################################################################################################### if (BUILD_EXAMPLES) + add_executable(plugin_replace "src/examples/plugin_replace.c") + target_link_libraries(plugin_replace PRIVATE omega_edit::omega_edit ${FILESYSTEM_LIB}) + add_executable(replace "src/examples/replace.cpp") target_link_libraries(replace PRIVATE omega_edit::omega_edit ${FILESYSTEM_LIB}) diff --git a/core/src/examples/plugin_replace.c b/core/src/examples/plugin_replace.c new file mode 100644 index 000000000..2ed8d216f --- /dev/null +++ b/core/src/examples/plugin_replace.c @@ -0,0 +1,52 @@ +/********************************************************************************************************************** +* Copyright (c) 2021 Concurrent Technologies Corporation. * +* * +* Licensed 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 is 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 "omega_edit/plugins/replace.h" +#include "omega_edit/check.h" +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (argc != 6) { + fprintf(stderr, "USAGE: %s \n", + argv[0]); + return -1; + } + + omega_session_t *session_ptr = omega_edit_create_session(argv[1], NULL, NULL, NO_EVENTS, NULL); + if (!session_ptr) { + fprintf(stderr, "ERROR: Failed to open input file %s\n", argv[1]); + return -1; + } + + // Create the context + omega_edit_transform_replace_context_t context; + context.search = (omega_byte_t *) argv[3]; + context.search_length = (int64_t) strlen(argv[3]); + context.replace = (omega_byte_t *) argv[4]; + context.replace_length = (int64_t) strlen(argv[4]); + context.case_insensitive = atoi(argv[5]); + context.replacements = 0; + + int rc = omega_check_model(session_ptr); + fprintf(stderr, "%d\n", rc); + assert(0 == rc); + omega_edit_apply_transform(session_ptr, 0, 0, omega_edit_transform_replace, &context); + rc = omega_check_model(session_ptr); + fprintf(stderr, "%d\n", rc); + assert(0 == rc); + return omega_edit_save(session_ptr, argv[2], IO_FLG_OVERWRITE, NULL); +} diff --git a/core/src/examples/transform.c b/core/src/examples/transform.c index 8d61e358c..ee1e5027c 100644 --- a/core/src/examples/transform.c +++ b/core/src/examples/transform.c @@ -29,7 +29,7 @@ int main(int argc, char **argv) { return -1; } omega_session_t *session_ptr = omega_edit_create_session(argv[2], NULL, NULL, NO_EVENTS, NULL); - omega_edit_apply_transform(session_ptr, (argv[1][0] == 'l') ? &to_lower : &to_upper, NULL, 0, 0); + omega_edit_apply_transform_old(session_ptr, (argv[1][0] == 'l') ? &to_lower : &to_upper, NULL, 0, 0); omega_edit_save(session_ptr, argv[3], IO_FLG_OVERWRITE, NULL); omega_edit_destroy_session(session_ptr); return 0; diff --git a/core/src/include/omega_edit/edit.h b/core/src/include/omega_edit/edit.h index 558b6bcf1..96e99e70e 100644 --- a/core/src/include/omega_edit/edit.h +++ b/core/src/include/omega_edit/edit.h @@ -36,6 +36,18 @@ extern "C" { #endif +/** +* Function signature to transform a stream. +* @param in input stream +* @param start_offset offset in input stream to start reading +* @param length number of bytes to read from input stream +* @param out output stream +* @param context plugin context +* @return 0 on success, non-zero on failure +*/ +OMEGA_EDIT_EXPORT typedef int (*omega_edit_transform_func_t)(FILE *in, int64_t start_offset, int64_t length, FILE *out, + void *context); + /** * Create a file editing session from a file path * @param file_path file path, will be opened for read, to create an editing session with, or nullptr if starting from @@ -193,8 +205,20 @@ OMEGA_EDIT_EXPORT int64_t omega_edit_overwrite(omega_session_t *session_ptr, int * @param length the number of bytes from the given offset to apply the mask to * @return zero on success, non-zero otherwise */ -OMEGA_EDIT_EXPORT int omega_edit_apply_transform(omega_session_t *session_ptr, omega_util_byte_transform_t transform, - void *user_data_ptr, int64_t offset, int64_t length); +OMEGA_EDIT_EXPORT int omega_edit_apply_transform_old(omega_session_t *session_ptr, omega_util_byte_transform_t transform, + void *user_data_ptr, int64_t offset, int64_t length); + +/** + * Apply a transform to the bytes starting at the given offset up to the given length + * @param session_ptr session to make the change in + * @param offset offset to make the change + * @param length number of bytes to apply the transform to + * @param transform transform function to apply + * @param transform_context context to pass through to the transform function + * @return zero on success, non-zero otherwise + */ +OMEGA_EDIT_EXPORT int omega_edit_apply_transform(omega_session_t *session_ptr, int64_t offset, int64_t length, + omega_edit_transform_func_t transform, void *transform_context); /** * Creates a session checkpoint. diff --git a/core/src/include/omega_edit/plugins/replace.h b/core/src/include/omega_edit/plugins/replace.h new file mode 100644 index 000000000..eedbc6f89 --- /dev/null +++ b/core/src/include/omega_edit/plugins/replace.h @@ -0,0 +1,53 @@ +/********************************************************************************************************************** + * Copyright (c) 2021 Concurrent Technologies Corporation. * + * * + * Licensed 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 is 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. * + * * + **********************************************************************************************************************/ + +#ifndef OMEGA_EDIT_PLUGINS_REPLACE_H +#define OMEGA_EDIT_PLUGINS_REPLACE_H + +#include +#include "omega_edit/export.h" +#include "omega_edit/byte.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Replace context. + */ +OMEGA_EDIT_EXPORT typedef struct { + omega_byte_t *search; + int64_t search_length; + omega_byte_t *replace; + int64_t replace_length; + int case_insensitive; + int64_t replacements; +} omega_edit_transform_replace_context_t; + +/** + * Replaces tokens in a stream. + * @param in input stream + * @param start_offset offset in input stream to start reading + * @param length number of bytes to read from input stream + * @param out output stream + * @param context context + * @return 0 on success, non-zero on failure + */ +OMEGA_EDIT_EXPORT int omega_edit_transform_replace(FILE *in, int64_t start_offset, int64_t length, FILE *out, void *context); + +#ifdef __cplusplus +} +#endif + +#endif //OMEGA_EDIT_PLUGINS_REPLACE_H diff --git a/core/src/lib/change.cpp b/core/src/lib/change.cpp index f7a29b6c2..e54b7b70f 100644 --- a/core/src/lib/change.cpp +++ b/core/src/lib/change.cpp @@ -12,7 +12,7 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/change.h" +#include "omega_edit/change.h" #include "impl_/change_def.hpp" #include "impl_/macros.h" #include diff --git a/core/src/lib/check.cpp b/core/src/lib/check.cpp index ff272fa09..193b82415 100644 --- a/core/src/lib/check.cpp +++ b/core/src/lib/check.cpp @@ -12,11 +12,10 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/check.h" +#include "omega_edit/check.h" #include "impl_/change_def.hpp" #include "impl_/internal_fun.hpp" #include "impl_/macros.h" -#include "impl_/model_def.hpp" #include "impl_/session_def.hpp" #include @@ -36,10 +35,12 @@ int omega_check_model(const omega_session_t *session_ptr) { expected_offset += segment->computed_length; } } + CLOG << "Serial: " << session_ptr->models_.front()->model_segments.front()->change_ptr->serial << "\n"; + CLOG << "Kind: " << session_ptr->models_.front()->model_segments.front()->change_ptr->kind << "\n"; if (1 != session_ptr->models_.front()->model_segments.front()->change_ptr->serial || 0 != (session_ptr->models_.front()->model_segments.front()->change_ptr->kind & OMEGA_CHANGE_TRANSACTION_BIT)) { - return -1; + return -2; } } return 0; diff --git a/core/src/lib/edit.cpp b/core/src/lib/edit.cpp index 15c8e70ec..c438a4f95 100644 --- a/core/src/lib/edit.cpp +++ b/core/src/lib/edit.cpp @@ -12,12 +12,12 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/edit.h" -#include "../include/omega_edit/change.h" -#include "../include/omega_edit/search.h" -#include "../include/omega_edit/segment.h" -#include "../include/omega_edit/session.h" -#include "../include/omega_edit/viewport.h" +#include "omega_edit/edit.h" +#include "omega_edit/change.h" +#include "omega_edit/search.h" +#include "omega_edit/segment.h" +#include "omega_edit/session.h" +#include "omega_edit/viewport.h" #include "impl_/change_def.hpp" #include "impl_/internal_fun.hpp" #include "impl_/macros.h" @@ -514,8 +514,8 @@ int64_t omega_edit_overwrite(omega_session_t *session_ptr, int64_t offset, const return omega_edit_overwrite_bytes(session_ptr, offset, (const omega_byte_t *) cstr, length); } -int omega_edit_apply_transform(omega_session_t *session_ptr, omega_util_byte_transform_t transform, void *user_data_ptr, - int64_t offset, int64_t length) { +int omega_edit_apply_transform_old(omega_session_t *session_ptr, omega_util_byte_transform_t transform, void *user_data_ptr, + int64_t offset, int64_t length) { if (!omega_session_changes_paused(session_ptr) && 0 == omega_edit_create_checkpoint(session_ptr)) { const auto in_file = session_ptr->models_.back()->file_path; const auto out_file = in_file + "_"; @@ -543,6 +543,35 @@ int omega_edit_apply_transform(omega_session_t *session_ptr, omega_util_byte_tra return -1; } +int omega_edit_apply_transform(omega_session_t *session_ptr, int64_t offset, int64_t length, + omega_edit_transform_func_t transform, void *transform_context) { + if (!omega_session_changes_paused(session_ptr) && 0 == omega_edit_create_checkpoint(session_ptr)) { + const auto in_file = session_ptr->models_.back()->file_path; + const auto out_file = in_file + "_"; + auto out_file_ptr = fopen(out_file.c_str(), "wb"); + if (0 == transform(session_ptr->models_.back()->file_ptr, offset, length, out_file_ptr, transform_context)) { + errno = 0;// reset errno + if (0 == fclose(session_ptr->models_.back()->file_ptr) && 0 == omega_util_remove_file(in_file.c_str()) && + 0 == rename(out_file.c_str(), in_file.c_str()) && + (session_ptr->models_.back()->file_ptr = fopen(in_file.c_str(), "rb"))) { + for (const auto &viewport_ptr : session_ptr->viewports_) { + viewport_ptr->data_segment.capacity = + -1 * std::abs(viewport_ptr->data_segment.capacity);// indicate dirty read + omega_viewport_notify(viewport_ptr.get(), VIEWPORT_EVT_TRANSFORM, nullptr); + } + omega_session_notify(session_ptr, SESSION_EVT_TRANSFORM, nullptr); + return 0; + } + + // In a bad state (I/O failure), so abort + ABORT(LOG_ERRNO();); + } + // The transform failed, but we can recover from this + if (omega_util_file_exists(out_file.c_str())) { omega_util_remove_file(out_file.c_str()); } + } + return -1; +} + int omega_edit_save(omega_session_t *session_ptr, const char *file_path, int io_flags, char *saved_file_path) { assert(session_ptr); assert(file_path); diff --git a/core/src/lib/encode.c b/core/src/lib/encode.c index 94ce28e78..bc79ffd1b 100644 --- a/core/src/lib/encode.c +++ b/core/src/lib/encode.c @@ -12,7 +12,7 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/encode.h" +#include "omega_edit/encode.h" #include size_t omega_encode_bin2hex(const omega_byte_t *src, char *dst, size_t src_length) { diff --git a/core/src/lib/filesystem.cpp b/core/src/lib/filesystem.cpp index fea499f1c..5b9614d1a 100644 --- a/core/src/lib/filesystem.cpp +++ b/core/src/lib/filesystem.cpp @@ -12,8 +12,8 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/filesystem.h" -#include "../include/omega_edit/utility.h" +#include "omega_edit/filesystem.h" +#include "omega_edit/utility.h" #include "impl_/macros.h" #include #include diff --git a/core/src/lib/impl_/change_def.hpp b/core/src/lib/impl_/change_def.hpp index 5a7eda90e..b0d69ca9d 100644 --- a/core/src/lib/impl_/change_def.hpp +++ b/core/src/lib/impl_/change_def.hpp @@ -15,7 +15,7 @@ #ifndef OMEGA_EDIT_CHANGE_DEF_HPP #define OMEGA_EDIT_CHANGE_DEF_HPP -#include "../../include/omega_edit/fwd_defs.h" +#include "omega_edit/fwd_defs.h" #include "data_def.hpp" #include diff --git a/core/src/lib/impl_/data_def.hpp b/core/src/lib/impl_/data_def.hpp index 20fd35b5b..9d8d8c28e 100644 --- a/core/src/lib/impl_/data_def.hpp +++ b/core/src/lib/impl_/data_def.hpp @@ -15,7 +15,7 @@ #ifndef OMEGA_EDIT_DATA_DEF_HPP #define OMEGA_EDIT_DATA_DEF_HPP -#include "../../include/omega_edit/byte.h" +#include "omega_edit/byte.h" #include /** diff --git a/core/src/lib/impl_/internal_fun.cpp b/core/src/lib/impl_/internal_fun.cpp index 9d5eec829..c99d72ff2 100644 --- a/core/src/lib/impl_/internal_fun.cpp +++ b/core/src/lib/impl_/internal_fun.cpp @@ -13,8 +13,8 @@ **********************************************************************************************************************/ #include "internal_fun.hpp" -#include "../../include/omega_edit/change.h" -#include "../../include/omega_edit/segment.h" +#include "omega_edit/change.h" +#include "omega_edit/segment.h" #include "change_def.hpp" #include "macros.h" #include "model_def.hpp" diff --git a/core/src/lib/impl_/internal_fun.hpp b/core/src/lib/impl_/internal_fun.hpp index 56d371c22..dd5cc5cd9 100644 --- a/core/src/lib/impl_/internal_fun.hpp +++ b/core/src/lib/impl_/internal_fun.hpp @@ -15,8 +15,8 @@ #ifndef OMEGA_EDIT_INTERNAL_FUN_HPP #define OMEGA_EDIT_INTERNAL_FUN_HPP -#include "../../include/omega_edit/byte.h" -#include "../../include/omega_edit/fwd_defs.h" +#include "omega_edit/byte.h" +#include "omega_edit/fwd_defs.h" #include "internal_fwd_defs.hpp" #include diff --git a/core/src/lib/impl_/internal_fwd_defs.hpp b/core/src/lib/impl_/internal_fwd_defs.hpp index 268870f8c..541f334fc 100644 --- a/core/src/lib/impl_/internal_fwd_defs.hpp +++ b/core/src/lib/impl_/internal_fwd_defs.hpp @@ -15,7 +15,7 @@ #ifndef OMEGA_EDIT_INTERNAL_FWD_DEFS_HPP #define OMEGA_EDIT_INTERNAL_FWD_DEFS_HPP -#include "../../include/omega_edit/fwd_defs.h" +#include "omega_edit/fwd_defs.h" #include using omega_model_t = struct omega_model_struct; diff --git a/core/src/lib/impl_/macros.h b/core/src/lib/impl_/macros.h index 7c9700426..9da26dc18 100644 --- a/core/src/lib/impl_/macros.h +++ b/core/src/lib/impl_/macros.h @@ -15,7 +15,7 @@ #ifndef OMEGA_EDIT_MACROS_H #define OMEGA_EDIT_MACROS_H -#include "../../include/omega_edit/config.h" +#include "omega_edit/config.h" #ifdef __cplusplus diff --git a/core/src/lib/impl_/model_segment_def.hpp b/core/src/lib/impl_/model_segment_def.hpp index fbfc4e10f..681edf431 100644 --- a/core/src/lib/impl_/model_segment_def.hpp +++ b/core/src/lib/impl_/model_segment_def.hpp @@ -15,7 +15,7 @@ #ifndef OMEGA_EDIT_MODEL_SEGMENT_DEF_HPP #define OMEGA_EDIT_MODEL_SEGMENT_DEF_HPP -#include "../../include/omega_edit/change.h" +#include "omega_edit/change.h" #include "internal_fwd_defs.hpp" enum class model_segment_kind_t { SEGMENT_READ, SEGMENT_INSERT }; diff --git a/core/src/lib/impl_/search_context_def.h b/core/src/lib/impl_/search_context_def.h index 4c0517f38..5d5072fb7 100644 --- a/core/src/lib/impl_/search_context_def.h +++ b/core/src/lib/impl_/search_context_def.h @@ -15,7 +15,7 @@ #ifndef OMEGA_EDIT_SEARCH_CONTEXT_DEF_H #define OMEGA_EDIT_SEARCH_CONTEXT_DEF_H -#include "../../include/omega_edit/fwd_defs.h" +#include "omega_edit/fwd_defs.h" #include "data_def.hpp" struct omega_search_context_struct { diff --git a/core/src/lib/impl_/session_def.hpp b/core/src/lib/impl_/session_def.hpp index 33159a08f..877e0abf9 100644 --- a/core/src/lib/impl_/session_def.hpp +++ b/core/src/lib/impl_/session_def.hpp @@ -15,8 +15,8 @@ #ifndef OMEGA_EDIT_SESSION_DEF_HPP #define OMEGA_EDIT_SESSION_DEF_HPP -#include "../../include/omega_edit/edit.h" -#include "../../include/omega_edit/fwd_defs.h" +#include "omega_edit/edit.h" +#include "omega_edit/fwd_defs.h" #include "internal_fwd_defs.hpp" #include "model_def.hpp" #include diff --git a/core/src/lib/impl_/viewport_def.hpp b/core/src/lib/impl_/viewport_def.hpp index d0a95dcef..df98096e5 100644 --- a/core/src/lib/impl_/viewport_def.hpp +++ b/core/src/lib/impl_/viewport_def.hpp @@ -15,7 +15,7 @@ #ifndef OMEGA_EDIT_VIEWPORT_DEF_HPP #define OMEGA_EDIT_VIEWPORT_DEF_HPP -#include "../../include/omega_edit/fwd_defs.h" +#include "omega_edit/fwd_defs.h" #include "internal_fwd_defs.hpp" #include "segment_def.hpp" diff --git a/core/src/lib/license.c b/core/src/lib/license.c index fb1d2b228..a3456e23d 100644 --- a/core/src/lib/license.c +++ b/core/src/lib/license.c @@ -12,7 +12,7 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/license.h" +#include "omega_edit/license.h" const char *omega_license_get() { return "Copyright 2021 Concurrent Technologies Corporation\n" diff --git a/core/src/lib/plugins/replace.c b/core/src/lib/plugins/replace.c new file mode 100644 index 000000000..050927e23 --- /dev/null +++ b/core/src/lib/plugins/replace.c @@ -0,0 +1,163 @@ +/********************************************************************************************************************** + * Copyright (c) 2021 Concurrent Technologies Corporation. * + * * + * Licensed 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 is 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 +#include +#include +#include "omega_edit/plugins/replace.h" +#include "omega_edit/utility.h" + +#define READ_BUFFER_SIZE 4096 +#define SEARCH_THRESHOLD 10 +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +static inline void +create_shift_table_(const omega_byte_t *search_token, int64_t search_len, int64_t *table, int case_insensitive) { + int64_t i; + + for (i = 0; i < 256; ++i) { + table[i] = search_len; + } + + for (i = 0; i < search_len - 1; ++i) { + table[case_insensitive ? tolower(search_token[i]) : search_token[i]] = search_len - 1 - i; + } +} + +static inline int64_t +boyer_moore_search_replace_(FILE *file_in, int64_t read_length, const omega_byte_t *search_token, int64_t search_len, + const omega_byte_t *replace_token, int64_t replace_len, FILE *file_out, + int case_insensitive) { + int64_t buffer_fill = 0; + int64_t read_count; + int64_t replacements = 0; + int64_t shift_table[256]; + int64_t total_read = 0; + + create_shift_table_(search_token, search_len, shift_table, case_insensitive); + + unsigned char *read_buffer = (unsigned char *) (malloc(READ_BUFFER_SIZE + search_len)); // overlap for searching + if (read_buffer == NULL) { + return -1; + } + + while (total_read < read_length && + (read_count = fread(read_buffer + buffer_fill, 1, MIN(READ_BUFFER_SIZE, read_length - total_read), + file_in)) > 0) { + total_read += read_count; + size_t i = 0; + buffer_fill += read_count; + + while (i <= buffer_fill - search_len) { + if (case_insensitive ? + omega_util_strnicmp((const char *) read_buffer + i, (const char *) search_token, search_len) != 0 : + memcmp(read_buffer + i, search_token, search_len) != 0) { + i += shift_table[case_insensitive ? tolower(read_buffer[i + search_len - 1]) : read_buffer[i + + search_len - + 1]]; + } else { + if (fwrite(replace_token, 1, replace_len, file_out) != replace_len) { + free(read_buffer); + return -1; + } + ++replacements; + i += search_len; + } + } + + memmove(read_buffer, read_buffer + i, buffer_fill - i); + buffer_fill -= i; + } + + if (fwrite(read_buffer, 1, buffer_fill, file_out) != buffer_fill) { + free(read_buffer); + return -1; + } + + free(read_buffer); + return replacements; +} + +static inline int64_t +simple_search_replace_(FILE *file_in, int64_t read_length, const omega_byte_t *search_token, int64_t search_len, + const omega_byte_t *replace_token, int64_t replace_len, FILE *file_out, int case_insensitive) { + char c; + int64_t replacements = 0; + int64_t total_read = 0; + unsigned char *buffer = (unsigned char *) (malloc(search_len)); + + if (buffer == NULL) { + return -1; + } + + memset(buffer, 0, search_len); + + while (total_read < read_length && fread(&c, 1, 1, file_in) > 0) { + ++total_read; + memmove(buffer, buffer + 1, search_len - 1); + buffer[search_len - 1] = c; + + if (case_insensitive ? omega_util_strnicmp((const char *) buffer, (const char *) search_token, search_len) == 0 + : memcmp(buffer, search_token, search_len) == 0) { + if (fwrite(replace_token, 1, replace_len, file_out) != replace_len) { + free(buffer); + return -1; + } + ++replacements; + memset(buffer, 0, search_len); + } else { + if (fwrite(&buffer[0], 1, 1, file_out) != 1) { + free(buffer); + return -1; + } + } + } + + free(buffer); + return replacements; +} + +static inline int64_t +stream_replace_(FILE *file_in, int64_t read_length, const omega_byte_t *search_token, int64_t search_len, + const omega_byte_t *replace_token, int64_t replace_len, FILE *file_out, int case_insensitive) { + return (search_len < SEARCH_THRESHOLD) ? simple_search_replace_(file_in, read_length, search_token, search_len, + replace_token, replace_len, file_out, + case_insensitive) : boyer_moore_search_replace_( + file_in, read_length, search_token, search_len, replace_token, replace_len, file_out, case_insensitive); +} + +int omega_edit_transform_replace(FILE *in, int64_t start_offset, int64_t length, FILE *out, void *context) { + int rc; + if (length < 1) { + rc = fseeko(in, 0, SEEK_END); + if (rc != 0) { + return rc; + } + length = ftello(in) - start_offset; + if (length < 1) { + return -1; + } + } + rc = fseeko(in, start_offset, SEEK_SET); + if (rc == 0) { + omega_edit_transform_replace_context_t *replace_context = (omega_edit_transform_replace_context_t *) context; + + replace_context->replacements = stream_replace_(in, length, replace_context->search, + replace_context->search_length, replace_context->replace, + replace_context->replace_length, out, + replace_context->case_insensitive); + } + return rc; +} + diff --git a/core/src/lib/search.cpp b/core/src/lib/search.cpp index 6a9829d25..997926cf5 100644 --- a/core/src/lib/search.cpp +++ b/core/src/lib/search.cpp @@ -12,10 +12,10 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/search.h" -#include "../include/omega_edit/segment.h" -#include "../include/omega_edit/session.h" -#include "../include/omega_edit/utility.h" +#include "omega_edit/search.h" +#include "omega_edit/segment.h" +#include "omega_edit/session.h" +#include "omega_edit/utility.h" #include "impl_/find.h" #include "impl_/internal_fun.hpp" #include "impl_/search_context_def.h" @@ -27,6 +27,7 @@ #include #include + static inline omega_byte_t to_lower_(omega_byte_t byte, void *) { return static_cast(std::tolower(byte)); } @@ -102,7 +103,7 @@ int omega_search_next_match(omega_search_context_t *search_context_ptr, int64_t (search_context_ptr->session_offset + search_context_ptr->session_length); auto session_length = is_begin ? search_context_ptr->session_length : search_context_ptr->session_length - - (search_context_ptr->match_offset - search_context_ptr->session_offset); + (search_context_ptr->match_offset - search_context_ptr->session_offset); data_segment.offset = is_begin ? search_context_ptr->session_offset : search_context_ptr->match_offset + advance_context; data_segment.capacity = std::min(session_length, MAX_SEGMENT_LENGTH); diff --git a/core/src/lib/segment.cpp b/core/src/lib/segment.cpp index 39902bd95..37385f83e 100644 --- a/core/src/lib/segment.cpp +++ b/core/src/lib/segment.cpp @@ -12,7 +12,7 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/segment.h" +#include "omega_edit/segment.h" #include "impl_/segment_def.hpp" #include diff --git a/core/src/lib/session.cpp b/core/src/lib/session.cpp index 033c19bee..5bedaafe7 100644 --- a/core/src/lib/session.cpp +++ b/core/src/lib/session.cpp @@ -12,7 +12,6 @@ * * **********************************************************************************************************************/ -#include "omega_edit/session.h" #include "impl_/change_def.hpp" #include "impl_/internal_fun.hpp" #include "impl_/model_def.hpp" @@ -20,6 +19,7 @@ #include "impl_/session_def.hpp" #include "omega_edit/fwd_defs.h" #include "omega_edit/segment.h" +#include "omega_edit/session.h" #include "omega_edit/viewport.h" #include #include diff --git a/core/src/lib/stl_string_adapter.cpp b/core/src/lib/stl_string_adapter.cpp index 9155e84a7..4d3398012 100644 --- a/core/src/lib/stl_string_adapter.cpp +++ b/core/src/lib/stl_string_adapter.cpp @@ -12,7 +12,7 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/stl_string_adaptor.hpp" +#include "omega_edit/stl_string_adaptor.hpp" #include std::string omega_change_get_string(const omega_change_t *change_ptr) diff --git a/core/src/lib/utility.c b/core/src/lib/utility.c index 0dd0e6286..2865bba71 100644 --- a/core/src/lib/utility.c +++ b/core/src/lib/utility.c @@ -12,7 +12,7 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/config.h" +#include "omega_edit/config.h" #ifdef OMEGA_BUILD_WINDOWS #include @@ -45,7 +45,7 @@ #endif #endif -#include "../include/omega_edit/utility.h" +#include "omega_edit/utility.h" #include "impl_/macros.h" #include #include diff --git a/core/src/lib/version.c b/core/src/lib/version.c index 37a6e459d..e1c88b746 100644 --- a/core/src/lib/version.c +++ b/core/src/lib/version.c @@ -14,8 +14,8 @@ * limitations under the License. * **********************************************************************************************************************/ -#include "../include/omega_edit/version.h" -#include "../include/omega_edit/export.h" +#include "omega_edit/version.h" +#include "omega_edit/export.h" #ifndef OMEGA_EDIT_VERSION_MAJOR #define OMEGA_EDIT_VERSION_MAJOR 0 diff --git a/core/src/lib/viewport.cpp b/core/src/lib/viewport.cpp index 3f6997634..ff950c45d 100644 --- a/core/src/lib/viewport.cpp +++ b/core/src/lib/viewport.cpp @@ -12,9 +12,9 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/viewport.h" -#include "../include/omega_edit/segment.h" -#include "../include/omega_edit/session.h" +#include "omega_edit/viewport.h" +#include "omega_edit/segment.h" +#include "omega_edit/session.h" #include "impl_/internal_fun.hpp" #include "impl_/session_def.hpp" #include "impl_/viewport_def.hpp" diff --git a/core/src/lib/visit.cpp b/core/src/lib/visit.cpp index 278c7220e..95d4fa052 100644 --- a/core/src/lib/visit.cpp +++ b/core/src/lib/visit.cpp @@ -12,7 +12,7 @@ * * **********************************************************************************************************************/ -#include "../include/omega_edit/visit.h" +#include "omega_edit/visit.h" #include "impl_/model_def.hpp" #include "impl_/session_def.hpp" #include diff --git a/core/src/tests/omega_test.cpp b/core/src/tests/omega_test.cpp index 556068a55..2f6e1d1d3 100644 --- a/core/src/tests/omega_test.cpp +++ b/core/src/tests/omega_test.cpp @@ -423,7 +423,7 @@ TEST_CASE("Checkpoint Tests", "[CheckpointTests]") { REQUIRE(1 == omega_session_get_num_changes(session_ptr)); REQUIRE(0 == omega_session_get_num_checkpoints(session_ptr)); REQUIRE(-1 == omega_edit_destroy_last_checkpoint(session_ptr)); - REQUIRE(0 == omega_edit_apply_transform(session_ptr, to_lower, nullptr, 0, 0)); + REQUIRE(0 == omega_edit_apply_transform_old(session_ptr, to_lower, nullptr, 0, 0)); REQUIRE(1 == omega_session_get_num_checkpoints(session_ptr)); REQUIRE(1 == omega_session_get_num_changes(session_ptr)); REQUIRE(1 == omega_session_get_num_change_transactions(session_ptr)); @@ -436,30 +436,30 @@ TEST_CASE("Checkpoint Tests", "[CheckpointTests]") { mask_info_t mask_info; mask_info.mask_kind = MASK_XOR; mask_info.mask = 0xFF; - REQUIRE(0 == omega_edit_apply_transform(session_ptr, byte_mask_transform, &mask_info, 10, 26)); + REQUIRE(0 == omega_edit_apply_transform_old(session_ptr, byte_mask_transform, &mask_info, 10, 26)); REQUIRE(2 == omega_session_get_num_checkpoints(session_ptr)); REQUIRE(0 == omega_edit_save(session_ptr, "data/test1.actual.checkpoint.2.dat", omega_io_flags_t::IO_FLG_OVERWRITE, nullptr)); - REQUIRE(0 == omega_edit_apply_transform(session_ptr, byte_mask_transform, &mask_info, 10, 26)); + REQUIRE(0 == omega_edit_apply_transform_old(session_ptr, byte_mask_transform, &mask_info, 10, 26)); REQUIRE(3 == omega_session_get_num_checkpoints(session_ptr)); REQUIRE(0 == omega_edit_save(session_ptr, "data/test1.actual.checkpoint.3.dat", omega_io_flags_t::IO_FLG_OVERWRITE, nullptr)); REQUIRE(0 == compare_files("data/test1.expected.checkpoint.1.dat", "data/test1.actual.checkpoint.3.dat")); mask_info.mask_kind = MASK_AND; - REQUIRE(0 == omega_edit_apply_transform(session_ptr, byte_mask_transform, &mask_info, 10, 0)); + REQUIRE(0 == omega_edit_apply_transform_old(session_ptr, byte_mask_transform, &mask_info, 10, 0)); REQUIRE(4 == omega_session_get_num_checkpoints(session_ptr)); REQUIRE(0 == omega_edit_save(session_ptr, "data/test1.actual.checkpoint.4.dat", omega_io_flags_t::IO_FLG_OVERWRITE, nullptr)); REQUIRE(0 == compare_files("data/test1.expected.checkpoint.1.dat", "data/test1.actual.checkpoint.4.dat")); mask_info.mask_kind = MASK_OR; mask_info.mask = 0x00; - REQUIRE(0 == omega_edit_apply_transform(session_ptr, byte_mask_transform, &mask_info, 10, 0)); + REQUIRE(0 == omega_edit_apply_transform_old(session_ptr, byte_mask_transform, &mask_info, 10, 0)); REQUIRE(5 == omega_session_get_num_checkpoints(session_ptr)); REQUIRE(0 == omega_edit_save(session_ptr, "data/test1.actual.checkpoint.5.dat", omega_io_flags_t::IO_FLG_OVERWRITE, nullptr)); REQUIRE(0 == compare_files("data/test1.expected.checkpoint.1.dat", "data/test1.actual.checkpoint.5.dat")); mask_info.mask_kind = MASK_AND; - REQUIRE(0 == omega_edit_apply_transform(session_ptr, byte_mask_transform, &mask_info, 10, 0)); + REQUIRE(0 == omega_edit_apply_transform_old(session_ptr, byte_mask_transform, &mask_info, 10, 0)); REQUIRE(6 == omega_session_get_num_checkpoints(session_ptr)); REQUIRE(3 == omega_edit_overwrite_string(session_ptr, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); diff --git a/packages/client/tests/specs/data/csstest.html b/packages/client/tests/specs/data/csstest.html index c4477ffb4..691c524e0 100644 --- a/packages/client/tests/specs/data/csstest.html +++ b/packages/client/tests/specs/data/csstest.html @@ -11,6 +11,6 @@
2
3
- +