Example #1
2
File: main.go Project: flier/gohs
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
}
Example #2
0
File: main.go Project: flier/gohs
/**
 * This function will read in the file with the specified name, with an
 * expression per line, ignoring lines starting with '#' and build a Hyperscan
 * database for it.
 */
func databasesFromFile(filename string) (hyperscan.StreamDatabase, hyperscan.BlockDatabase) {
	// do the actual file reading and string handling
	patterns := parseFile(filename)

	fmt.Printf("Compiling Hyperscan databases with %d patterns.\n", len(patterns))

	var clock Clock

	clock.Start()

	sdb, err := hyperscan.NewStreamDatabase(patterns...)

	clock.Stop()

	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: Could not compile patterns, %s", err)
		os.Exit(-1)
	}

	fmt.Printf("Hyperscan streaming mode database compiled in %.2f ms\n", clock.Time().Seconds()*1000)

	clock.Start()

	bdb, err := hyperscan.NewBlockDatabase(patterns...)

	clock.Stop()

	if err != nil {
		fmt.Fprintf(os.Stderr, "ERROR: Could not compile patterns, %s", err)
		os.Exit(-1)
	}

	fmt.Printf("Hyperscan block mode database compiled in %.2f ms\n", clock.Time().Seconds()*1000)

	return sdb, bdb
}