void session_update(timeval const & now, array_view_const_char message) override { uint16_t message_length = message.size() + 1; // Null-terminator is included. StaticOutStream<16> payload; payload.out_timeval_to_uint64le_usec(now); payload.out_uint16_le(message_length); send_wrm_chunk(this->trans, SESSION_UPDATE, payload.get_offset() + message_length, 1); this->trans.send(payload.get_data(), payload.get_offset()); this->trans.send(message.data(), message.size()); this->trans.send("\0", 1); this->last_sent_timer = this->timer; }
/** * filter format: * \code{regex} * option = "ocr" | "kbd" | "content" | "regex" | "exact-content" | "exact-regex" * option_separator = "," | "-" * filter * = \s* pattern * | \s* "$:" pattern * | \s* "$" option ( option_separator option )* ":" pattern * \endcode * * With \c conf_regex = KBD_INPUT, exact-content and exact-regex are respectively equivalent to content and regex */ PatternValue get_pattern_value(array_view_const_char const pattern_rule) { using Cat = PatternValue::Cat; struct IsWordSeparator { bool operator == (char c) const { return c == '-' || c == ','; } }; PatternValue pattern_value; constexpr PatternValue empty_pattern_value {}; auto av = array_view_const_char{ ltrim(pattern_rule.begin(), pattern_rule.end()), pattern_rule.end()}; if (not av.empty() && av.front() == '$') { auto end_option_list = std::find(av.begin()+1, av.end(), ':'); if (end_option_list != av.end() && end_option_list+1 != av.end()) { array_view_const_char options(av.begin()+1, end_option_list); bool is_exact = false; for (auto token : get_split(options, IsWordSeparator{})) { auto eq = [](range<char const*> b, array_view_const_char a) { return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); }; if (eq(token, cstr_array_view("exact"))) { is_exact = true; } else { if (eq(token, cstr_array_view("ocr"))) { pattern_value.is_ocr = true; if (is_exact) { pattern_value.cat = Cat::is_exact_str; } } else if (eq(token, cstr_array_view("kbd"))) { pattern_value.is_kbd = true; if (is_exact) { pattern_value.cat = Cat::is_exact_str; } } else if (eq(token, cstr_array_view("regex"))) { pattern_value.cat = is_exact ? Cat::is_exact_reg : Cat::is_reg; } else if (eq(token, cstr_array_view("content"))) { pattern_value.cat = is_exact ? Cat::is_exact_str : Cat::is_str; } else { LOG(LOG_WARNING, "Unknown filter option=\"%.*s\" at char %d in \"%.*s\"", int(token.size()), token.begin(), int(token.begin() - pattern_rule.begin()), int(pattern_rule.size()), pattern_rule.begin()); return empty_pattern_value; } is_exact = false; } } if (is_exact) { pattern_value.cat = Cat::is_exact_str; } if (not pattern_value.is_ocr && not pattern_value.is_kbd) { pattern_value.is_ocr = true; } pattern_value.pattern = {end_option_list+1, av.end()}; } } else { pattern_value.pattern = av; pattern_value.is_ocr = true; } return pattern_value; }