MySQL 9.6.0
Source Code Documentation
text_parser.h
Go to the documentation of this file.
1// Copyright (c) 2025, Oracle and/or its affiliates.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License, version 2.0,
5// as published by the Free Software Foundation.
6//
7// This program is designed to work with certain software (including
8// but not limited to OpenSSL) that is licensed under separate terms,
9// as designated in a particular file or component or in included license
10// documentation. The authors of MySQL hereby grant you an additional
11// permission to link the program and your derivative works with the
12// separately licensed software that they have either included with
13// the program or referenced in the documentation.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License, version 2.0, for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
24#ifndef MYSQL_STRCONV_CONV_TEXT_PARSER_H
25#define MYSQL_STRCONV_CONV_TEXT_PARSER_H
26
27/// @file
28/// Experimental API header
29
30#include <cstddef> // std::size_t
31#include <string_view> // string_view
32#include "mysql/strconv/decode/parser.h" // Parser
33#include "mysql/strconv/encode/string_target.h" // Is_string_target
34#include "mysql/strconv/formats/escaped_format.h" // Escaped_format
35#include "mysql/strconv/formats/text_format.h" // Text_format
36
37/// @addtogroup GroupLibsMysqlStrconv
38/// @{
39
40namespace mysql::strconv {
41
42// ==== Format Parser into text format ====
43
44/// Enable encode(Text_format, Parse_result). This produces an error message
45/// that describes the Parse_result object to humans.
46///
47/// @param format Type tag to identify that this relates to text format.
48///
49/// @param target String target to which the string will be appended.
50///
51/// @param obj Object to write.
53 const Parser &obj) {
54 // For errors, we include a quote of up to 48 characters, of which 6 are
55 // "[HERE]". Of the remaining ones, 1/3 are the prefix and 2/3 are the suffix.
56 static constexpr std::size_t max_len = 48;
57 static constexpr std::string_view here("[HERE]");
58 static constexpr std::size_t max_prefix_len = (max_len - here.size()) / 3;
59 static constexpr std::size_t max_suffix_len =
60 max_len - max_prefix_len - here.size();
61 static constexpr std::string_view ellipsis("...");
62 detail::Parse_result_internals internals(obj);
63
64 // Generate the string
65 // "after N characters, up to [HERE] in \"...prefix[HERE]".
66 // (Without the ellipsis, in case prefix is short.)
67 auto prefix = [&](std::size_t position) {
68 // Use the text "after N characters" since it is non-ambiguous. The
69 // alternative "at position N" may be ambiguous since some software uses
70 // 0-based positions and some uses 1-based positions.
71 target.concat(format, " after ", position, " characters, marked by ", here,
72 " in: \"");
73 // Prefix
74 if (position > max_prefix_len) {
75 // Truncate to the left
76 std::size_t length = max_prefix_len - ellipsis.size();
77 target.write(format, ellipsis);
78 target.write(Escaped_format{}, {obj.begin() + position - length, length});
79 } else {
80 target.write(Escaped_format{}, {obj.begin(), position});
81 }
82 // "[HERE]"
83 target.write(format, here);
84 };
85
86 // Generate the string "suffix...\"". (Without the ellipsis, in case the
87 // suffix is short.)
88 auto suffix = [&](const char *position) {
89 std::size_t remaining_size = obj.end() - position;
90 if (remaining_size > max_suffix_len) {
91 // Truncate to the right
92 target.write(Escaped_format{},
93 {position, max_suffix_len - ellipsis.size()});
94 target.write(format, ellipsis);
95 } else {
96 target.write(Escaped_format{}, {position, remaining_size});
97 }
98 target.write(format, "\"");
99 };
100
101 if (obj.is_ok()) {
102 target.write(format, "OK");
103 } else if (obj.is_store_error()) {
104 // There was an error storing the object. Just print the message, no
105 // position.
106 target.write(format, internals.message());
107 } else {
108 // There was a parse error. Print the message, the position, and some
109 // context from the string.
110 // First say what is wrong.
111 std::size_t position{0};
112 if (obj.is_fullmatch_error() &&
113 internals.parse_error_position() < std::ptrdiff_t(obj.int_pos())) {
114 target.write(format, "Expected end of string");
115 position = obj.int_pos();
116 } else {
117 if (internals.message_form() ==
119 target.write(format, "Expected ");
120 target.write(Escaped_format(With_quotes::yes), internals.message());
121 } else {
122 target.write(format, internals.message());
123 }
124 position = internals.parse_error_position();
125 }
126 // Then say where it is wrong.
127 if (position == 0) {
128 target.write(format, " at the beginning of the string: \"");
129 } else {
130 // " after N characters, up to [HERE] in \"...prefix[HERE]"
131 prefix(position);
132 }
133 // "suffix...\""
134 suffix(obj.begin() + position);
135 }
136}
137
138} // namespace mysql::strconv
139
140// addtogroup GroupLibsMysqlStrconv
141/// @}
142
143#endif // ifndef MYSQL_STRCONV_CONV_TEXT_PARSER_H
Format class to encode ascii strings.
Definition: escaped_format.h:79
Object used to parse strings.
Definition: parser.h:69
const char * end() const
Return pointer to the end of the underlying string.
Definition: parse_position.h:138
std::size_t int_pos() const
Return the current position as an integer.
Definition: parse_position.h:107
const char * begin() const
Return pointer to the beginning of the underlying string.
Definition: parse_position.h:125
Helper class that exports the internals from Parse_result.
Definition: parse_result.h:212
std::ptrdiff_t parse_error_position() const
Definition: parse_result.h:219
auto message_form() const
Definition: parse_result.h:225
std::string_view message() const
Definition: parse_result.h:229
bool is_fullmatch_error() const
Return true if the object was parsed successfully, but there were more characters after the end.
Definition: parse_result.h:133
@ expected_string
The message is a string that was expected but not found at the current position.
bool is_ok() const
Return true if the last operation succeeded, i.e., either a full match was requested and an object wa...
Definition: parse_result.h:97
bool is_store_error() const
Return true if an environment error occurred.
Definition: parse_result.h:121
Concept that holds for String_counter and String_writer.
Definition: string_target.h:111
Experimental API header.
std::string format(const routing_guidelines::Session_info &session_info, bool extended_session_info)
Definition: dest_metadata_cache.cc:170
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
Definition: gtid_binary_format.h:41
void encode_impl(const Gtid_binary_format &format, Is_string_target auto &target, const mysql::gtids::Is_tag auto &tag)
Definition: gtid_binary_format_conv.h:48
Experimental API header.
Experimental API header.
Format tag to identify text format.
Definition: text_format.h:38
Experimental API header.