diff --git a/build.sh b/build.sh index 92c2ddc..0c4ff04 100755 --- a/build.sh +++ b/build.sh @@ -5,6 +5,7 @@ set -xeu set -o pipefail HYPERSCAN=5.4.0 +PCRE_VERSION=8.41 VECTORSCAN=af8c6d375cba32a50a9e575de83807d96a0fb503 detect_platform() { @@ -79,27 +80,31 @@ make -j $THREADS make install cd .. +curl -L -o pcre-$PCRE_VERSION.tar.gz https://sourceforge.net/projects/pcre/files/pcre/8.41/pcre-$PCRE_VERSION.tar.gz +tar -zxf pcre-$PCRE_VERSION.tar.gz +mv pcre-$PCRE_VERSION hyperscan-$HYPERSCAN + cd hyperscan-$HYPERSCAN case $DETECTED_PLATFORM in linux-x86_64) - CFLAGS='-O -fPIC' CC="gcc" CXX="g++ -std=c++11 -m64 -fPIC" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DPCRE_SOURCE="." . + CFLAGS='-O -fPIC' CC="gcc" CXX="g++ -std=c++11 -m64 -fPIC" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DBUILD_STATIC_AND_SHARED=ON -DPCRE_SOURCE="pcre-$PCRE_VERSION" . make -j $THREADS hs hs_runtime hs_compile make install/strip ;; macosx-x86_64) - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DARCH_OPT_FLAGS='-Wno-error' -DPCRE_SOURCE="." . + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DARCH_OPT_FLAGS='-Wno-error' -DBUILD_STATIC_AND_SHARED=ON -DPCRE_SOURCE="pcre-$PCRE_VERSION" . make -j $THREADS hs hs_runtime hs_compile make install/strip ;; macosx-arm64) - CFLAGS="-target arm64-apple-macos11" CXXFLAGS="-target arm64-apple-macos11" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DARCH_OPT_FLAGS='-Wno-error' -DPCRE_SOURCE="." . + CFLAGS="-target arm64-apple-macos11" CXXFLAGS="-target arm64-apple-macos11" cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DARCH_OPT_FLAGS='-Wno-error' -DBUILD_STATIC_AND_SHARED=ON -DPCRE_SOURCE="pcre-$PCRE_VERSION" . make -j $THREADS hs hs_runtime hs_compile make install/strip ;; windows-x86_64) unset TEMP TMP # temp is defined in uppercase by bash and lowercase by windows, which causes problems with cmake + msbuild - CXXFLAGS="/Wv:17" cmake -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DARCH_OPT_FLAGS='' -DPCRE_SOURCE="." . + CXXFLAGS="/Wv:17" cmake -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$(pwd)/.." -DCMAKE_INSTALL_LIBDIR="lib" -DARCH_OPT_FLAGS='' -DBUILD_STATIC_AND_SHARED=ON -DPCRE_SOURCE="pcre-$PCRE_VERSION" . MSBuild.exe hyperscan.sln //p:Configuration=Release //p:Platform=x64 cp -r src/* ../include/hs/ cp lib/*.lib ../lib diff --git a/src/main/java/com/gliwka/hyperscan/jni/JavaCppPreset.java b/src/main/java/com/gliwka/hyperscan/jni/JavaCppPreset.java index fd9894b..1181bae 100644 --- a/src/main/java/com/gliwka/hyperscan/jni/JavaCppPreset.java +++ b/src/main/java/com/gliwka/hyperscan/jni/JavaCppPreset.java @@ -37,7 +37,10 @@ define = "NO_JNI_DETACH_THREAD", //JNI callback on same thread value = {"linux-x86_64", "macosx-x86_64", "macosx-arm64", "windows-x86_64"}, compiler = "cpp11", - include = {"hs/hs_common.h", "hs/hs_compile.h", "hs/hs_runtime.h", "hs/hs.h"}, + include = { + "hs/hs_common.h", "hs/hs_compile.h", "hs/hs_runtime.h", "hs/hs.h", + "hs/ch_common.h", "hs/ch_compile.h", "hs/ch_runtime.h", "hs/ch.h" + }, link = {"hs", "hs_runtime"} ) }, diff --git a/src/sample/ChScanExample.java b/src/sample/ChScanExample.java new file mode 100644 index 0000000..220a9d5 --- /dev/null +++ b/src/sample/ChScanExample.java @@ -0,0 +1,120 @@ +package sample; + + +import com.gliwka.hyperscan.jni.ch_capture_t; +import com.gliwka.hyperscan.jni.ch_compile_error_t; +import com.gliwka.hyperscan.jni.ch_database_t; +import com.gliwka.hyperscan.jni.ch_error_event_handler; +import com.gliwka.hyperscan.jni.ch_match_event_handler; +import com.gliwka.hyperscan.jni.ch_scratch_t; +import com.gliwka.hyperscan.jni.hyperscan; +import org.bytedeco.javacpp.BytePointer; +import org.bytedeco.javacpp.IntPointer; +import org.bytedeco.javacpp.Loader; +import org.bytedeco.javacpp.Pointer; +import org.bytedeco.javacpp.PointerPointer; +import org.bytedeco.javacpp.annotation.Cast; +import org.bytedeco.javacpp.annotation.Const; + +import java.util.LinkedList; + +import static com.gliwka.hyperscan.jni.hyperscan.HS_FLAG_SINGLEMATCH; +import static com.gliwka.hyperscan.jni.hyperscan.HS_MODE_BLOCK; + + +public class ChScanExample { + + public static void main(String... args) { + Loader.load(hyperscan.class); + + String[] patterns = {"abc1", "asa", "dab"}; + ch_database_t database_t = null; + ch_match_event_handler matchEventHandler = null; + ch_error_event_handler errorEventHandler = null; + ch_scratch_t scratchSpace = new ch_scratch_t(); + ch_compile_error_t compile_error_t; + final LinkedList matchedIds = new LinkedList<>(); + try (PointerPointer database_t_p = new PointerPointer<>(1); + PointerPointer compile_error_t_p = new PointerPointer<>(1); + IntPointer compileFlags = new IntPointer(HS_FLAG_SINGLEMATCH, HS_FLAG_SINGLEMATCH, HS_FLAG_SINGLEMATCH); + IntPointer patternIds = new IntPointer(1, 2, 3); + PointerPointer expressionsPointer = new PointerPointer(patterns); + ) { + matchEventHandler = new ch_match_event_handler() { + @Override + public int call(@Cast("unsigned int") int id, + @Cast("unsigned long long") long from, + @Cast("unsigned long long") long to, + @Cast("unsigned int") int flags, + @Cast("unsigned int") int size, + @Const ch_capture_t captured, + Pointer ctx) { + + System.out.println("id" + id + ": " + from + "-" + to); + matchedIds.add(new long[]{from, to}); + return 0; + } + }; + + errorEventHandler = new ch_error_event_handler() { + @Override + public int call(@Cast("ch_error_event_t") int error_type, + @Cast("unsigned int") int id, Pointer info, + Pointer ctx) { + + System.out.println("Error for id" + id + ":" + error_type); + return 0; + } + }; + + int result = hyperscan.ch_compile_multi( + expressionsPointer, + compileFlags, + patternIds, + 3, + HS_MODE_BLOCK, + null, + database_t_p, + compile_error_t_p + ); + + database_t = new ch_database_t(database_t_p.get(0)); + compile_error_t = new ch_compile_error_t(compile_error_t_p.get(0)); + if (result != 0) { + System.out.println(compile_error_t.message().getString()); + System.exit(1); + } + result = hyperscan.ch_alloc_scratch(database_t, scratchSpace); + if (result != 0) { + System.out.println("Error during scratch space allocation"); + System.exit(1); + } + + String textToSearch = "-21dasaaadabcaaa"; + + hyperscan.ch_scan( + database_t, + textToSearch, + textToSearch.length(), + 0, + scratchSpace, + matchEventHandler, + errorEventHandler, + expressionsPointer + ); + + System.out.println("Count: " + matchedIds.size()); + + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + hyperscan.ch_free_scratch(scratchSpace); + if (database_t != null) { + hyperscan.ch_free_database(database_t); + } + if (matchEventHandler != null) { + matchEventHandler.close(); + } + } + } +} diff --git a/src/sample/HyperscanSample.java b/src/sample/HyperscanSample.java new file mode 100644 index 0000000..8cf8605 --- /dev/null +++ b/src/sample/HyperscanSample.java @@ -0,0 +1,77 @@ +package sample; + +import com.gliwka.hyperscan.jni.hs_compile_error_t; +import com.gliwka.hyperscan.jni.hs_database_t; +import com.gliwka.hyperscan.jni.hs_scratch_t; +import com.gliwka.hyperscan.jni.hyperscan; +import com.gliwka.hyperscan.jni.match_event_handler; +import org.bytedeco.javacpp.BytePointer; +import org.bytedeco.javacpp.IntPointer; +import org.bytedeco.javacpp.Loader; +import org.bytedeco.javacpp.Pointer; +import org.bytedeco.javacpp.PointerPointer; +import org.bytedeco.javacpp.annotation.Cast; + +import static com.gliwka.hyperscan.jni.hyperscan.HS_FLAG_SINGLEMATCH; +import static com.gliwka.hyperscan.jni.hyperscan.HS_MODE_BLOCK; + + +public class HyperscanSample { + + public static void main(String[] args) { + Loader.load(hyperscan.class); + + String[] patterns = {"abc1", "asa", "dab"}; + hs_database_t database_t = null; + match_event_handler matchEventHandler = null; + hs_scratch_t scratchSpace = new hs_scratch_t(); + hs_compile_error_t compile_error_t; + + try (PointerPointer database_t_p = new PointerPointer<>(1); + PointerPointer compile_error_t_p = new PointerPointer<>(1); + IntPointer compileFlags = new IntPointer(HS_FLAG_SINGLEMATCH, HS_FLAG_SINGLEMATCH, HS_FLAG_SINGLEMATCH); + IntPointer patternIds = new IntPointer(1, 1, 1); + PointerPointer expressionsPointer = new PointerPointer<>(patterns) + ) { + + matchEventHandler = new match_event_handler() { + @Override + public int call(@Cast("unsigned int") int id, + @Cast("unsigned long long") long from, + @Cast("unsigned long long") long to, + @Cast("unsigned int") int flags, Pointer context) { + System.out.println(from + "-" + to); + System.out.println(id); + return 0; + } + }; + + int result = hyperscan.hs_compile_multi(expressionsPointer, compileFlags, patternIds, 3, HS_MODE_BLOCK, + null, database_t_p, compile_error_t_p); + + database_t = new hs_database_t(database_t_p.get(0)); + compile_error_t = new hs_compile_error_t(compile_error_t_p.get(0)); + if (result != 0) { + System.out.println(compile_error_t.message().getString()); + System.exit(1); + } + result = hyperscan.hs_alloc_scratch(database_t, scratchSpace); + if (result != 0) { + System.out.println("Error during scratch space allocation"); + System.exit(1); + } + + String textToSearch = "-21dasaaadabcaaa"; + hyperscan.hs_scan(database_t, textToSearch, textToSearch.length(), 0, scratchSpace, matchEventHandler, expressionsPointer); + + } finally { + hyperscan.hs_free_scratch(scratchSpace); + if (database_t != null) { + hyperscan.hs_free_database(database_t); + } + if (matchEventHandler != null) { + matchEventHandler.close(); + } + } + } +}