xref: /linux/include/linux/textsearch.h (revision 13b2d15d991b3f0f4ebfffbed081dbff27ac1c9d)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __LINUX_TEXTSEARCH_H
3 #define __LINUX_TEXTSEARCH_H
4 
5 #include <linux/types.h>
6 #include <linux/list.h>
7 #include <linux/kernel.h>
8 #include <linux/err.h>
9 #include <linux/slab.h>
10 
11 struct module;
12 
13 struct ts_config;
14 
15 #define TS_AUTOLOAD	1 /* Automatically load textsearch modules when needed */
16 #define TS_IGNORECASE	2 /* Searches string case insensitively */
17 
18 /**
19  * struct ts_state - search state
20  * @offset: offset for next match
21  * @cb: control buffer, for persistent variables of get_next_block()
22  */
23 struct ts_state
24 {
25 	unsigned int		offset;
26 	char			cb[48];
27 };
28 
29 /**
30  * struct ts_ops - search module operations
31  * @name: name of search algorithm
32  * @init: initialization function to prepare a search
33  * @find: find the next occurrence of the pattern
34  * @destroy: destroy algorithm specific parts of a search configuration
35  * @get_pattern: return head of pattern
36  * @get_pattern_len: return length of pattern
37  * @owner: module reference to algorithm
38  * @list: list to search
39  */
40 struct ts_ops
41 {
42 	const char		*name;
43 	struct ts_config *	(*init)(const void *, unsigned int, gfp_t, int);
44 	unsigned int		(*find)(struct ts_config *,
45 					struct ts_state *);
46 	void			(*destroy)(struct ts_config *);
47 	void *			(*get_pattern)(struct ts_config *);
48 	unsigned int		(*get_pattern_len)(struct ts_config *);
49 	struct module		*owner;
50 	struct list_head	list;
51 };
52 
53 /**
54  * struct ts_config - search configuration
55  * @ops: operations of chosen algorithm
56  * @flags: flags
57  * @get_next_block: callback to fetch the next block to search in
58  * @finish: callback to finalize a search
59  */
60 struct ts_config
61 {
62 	struct ts_ops		*ops;
63 	int 			flags;
64 
65 	/**
66 	 * @get_next_block: fetch next block of data
67 	 * @consumed: number of bytes consumed by the caller
68 	 * @dst: destination buffer
69 	 * @conf: search configuration
70 	 * @state: search state
71 	 *
72 	 * Called repeatedly until 0 is returned. Must assign the
73 	 * head of the next block of data to &*dst and return the length
74 	 * of the block or 0 if at the end. consumed == 0 indicates
75 	 * a new search. May store/read persistent values in state->cb.
76 	 */
77 	unsigned int		(*get_next_block)(unsigned int consumed,
78 						  const u8 **dst,
79 						  struct ts_config *conf,
80 						  struct ts_state *state);
81 
82 	/**
83 	 * @finish: finalize/clean a series of get_next_block() calls
84 	 * @conf: search configuration
85 	 * @state: search state
86 	 *
87 	 * Called after the last use of get_next_block(), may be used
88 	 * to cleanup any leftovers.
89 	 */
90 	void			(*finish)(struct ts_config *conf,
91 					  struct ts_state *state);
92 };
93 
94 /**
95  * textsearch_next - continue searching for a pattern
96  * @conf: search configuration
97  * @state: search state
98  *
99  * Continues a search looking for more occurrences of the pattern.
100  * textsearch_find() must be called to find the first occurrence
101  * in order to reset the state.
102  *
103  * Returns the position of the next occurrence of the pattern or
104  * UINT_MAX if not match was found.
105  */
textsearch_next(struct ts_config * conf,struct ts_state * state)106 static inline unsigned int textsearch_next(struct ts_config *conf,
107 					   struct ts_state *state)
108 {
109 	unsigned int ret = conf->ops->find(conf, state);
110 
111 	if (conf->finish)
112 		conf->finish(conf, state);
113 
114 	return ret;
115 }
116 
117 /**
118  * textsearch_find - start searching for a pattern
119  * @conf: search configuration
120  * @state: search state
121  *
122  * Returns the position of first occurrence of the pattern or
123  * UINT_MAX if no match was found.
124  */
textsearch_find(struct ts_config * conf,struct ts_state * state)125 static inline unsigned int textsearch_find(struct ts_config *conf,
126 					   struct ts_state *state)
127 {
128 	state->offset = 0;
129 	return textsearch_next(conf, state);
130 }
131 
132 /**
133  * textsearch_get_pattern - return head of the pattern
134  * @conf: search configuration
135  */
textsearch_get_pattern(struct ts_config * conf)136 static inline void *textsearch_get_pattern(struct ts_config *conf)
137 {
138 	return conf->ops->get_pattern(conf);
139 }
140 
141 /**
142  * textsearch_get_pattern_len - return length of the pattern
143  * @conf: search configuration
144  */
textsearch_get_pattern_len(struct ts_config * conf)145 static inline unsigned int textsearch_get_pattern_len(struct ts_config *conf)
146 {
147 	return conf->ops->get_pattern_len(conf);
148 }
149 
150 extern int textsearch_register(struct ts_ops *);
151 extern int textsearch_unregister(struct ts_ops *);
152 extern struct ts_config *textsearch_prepare(const char *, const void *,
153 					    unsigned int, gfp_t, int);
154 extern void textsearch_destroy(struct ts_config *conf);
155 extern unsigned int textsearch_find_continuous(struct ts_config *,
156 					       struct ts_state *,
157 					       const void *, unsigned int);
158 
159 
160 #define TS_PRIV_ALIGNTO	8
161 #define TS_PRIV_ALIGN(len) (((len) + TS_PRIV_ALIGNTO-1) & ~(TS_PRIV_ALIGNTO-1))
162 
alloc_ts_config(size_t payload,gfp_t gfp_mask)163 static inline struct ts_config *alloc_ts_config(size_t payload,
164 						gfp_t gfp_mask)
165 {
166 	struct ts_config *conf;
167 
168 	conf = kzalloc(TS_PRIV_ALIGN(sizeof(*conf)) + payload, gfp_mask);
169 	if (conf == NULL)
170 		return ERR_PTR(-ENOMEM);
171 
172 	return conf;
173 }
174 
ts_config_priv(struct ts_config * conf)175 static inline void *ts_config_priv(struct ts_config *conf)
176 {
177 	return ((u8 *) conf + TS_PRIV_ALIGN(sizeof(struct ts_config)));
178 }
179 
180 #endif
181