Beispiel #1
2
func main() {
	flag.Parse()

	if flag.NArg() != 2 {
		fmt.Fprintf(os.Stderr, "Usage: %s <pattern> <input file>\n", os.Args[0])
		os.Exit(-1)
	}

	if !*flagNoColor {
		stat, _ := os.Stdout.Stat()

		if stat != nil && stat.Mode()&os.ModeType != 0 {
			theme = highlight
		}
	}

	pattern := hyperscan.NewPattern(flag.Arg(0), hyperscan.DotAll|hyperscan.SomLeftMost)
	inputFN := flag.Arg(1)

	/* First, we attempt to compile the pattern provided on the command line.
	 * We assume 'DOTALL' semantics, meaning that the '.' meta-character will
	 * match newline characters. The compiler will analyse the given pattern and
	 * either return a compiled Hyperscan database, or an error message
	 * explaining why the pattern didn't compile.
	 */
	database, err := hyperscan.NewBlockDatabase(pattern)

	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: Unable to compile pattern \"%s\": %s\n", pattern.String(), err.Error())
		os.Exit(-1)
	}

	defer database.Close()

	/* Next, we read the input data file into a buffer. */
	inputData, err := ioutil.ReadFile(inputFN)

	if err != nil {
		os.Exit(-1)
	}

	/* Finally, we issue a call to hs_scan, which will search the input buffer
	 * for the pattern represented in the bytecode. Note that in order to do
	 * this, scratch space needs to be allocated with the hs_alloc_scratch
	 * function. In typical usage, you would reuse this scratch space for many
	 * calls to hs_scan, but as we're only doing one, we'll be allocating it
	 * and deallocating it as soon as our matching is done.
	 *
	 * When matches occur, the specified callback function (eventHandler in
	 * this file) will be called. Note that although it is reminiscent of
	 * asynchronous APIs, Hyperscan operates synchronously: all matches will be
	 * found, and all callbacks issued, *before* hs_scan returns.
	 *
	 * In this example, we provide the input pattern as the context pointer so
	 * that the callback is able to print out the pattern that matched on each
	 * match event.
	 */
	scratch, err := hyperscan.NewScratch(database)

	if err != nil {
		fmt.Fprint(os.Stderr, "ERROR: Unable to allocate scratch space. Exiting.\n")
		os.Exit(-1)
	}

	defer scratch.Free()

	fmt.Printf("Scanning %d bytes with Hyperscan\n", len(inputData))

	if err := database.Scan(inputData, scratch, eventHandler, inputData); err != nil {
		fmt.Fprint(os.Stderr, "ERROR: Unable to scan input buffer. Exiting.\n")
		os.Exit(-1)
	}

	/* Scanning is complete, any matches have been handled, so now we just
	 * clean up and exit.
	 */

	return
}
Beispiel #2
0
func NewBenchmark(streaming hyperscan.StreamDatabase, block hyperscan.BlockDatabase) (*Benchmark, error) {
	scratch, err := hyperscan.NewScratch(streaming)

	if err != nil {
		return nil, fmt.Errorf("could not allocate scratch space, %s", err)
	}

	if err := scratch.Realloc(block); err != nil {
		return nil, fmt.Errorf("could not reallocate scratch space, %s", err)
	}

	return &Benchmark{
		dbStreaming: streaming,
		dbBlock:     block,
		scratch:     scratch,
		streamMap:   make(map[uint64]int),
	}, nil
}