ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
mdl_search.c
Go to the documentation of this file.
1
13#include "mdl_search.h"
14
15#include <string.h>
16
17#include "ra8_attributes.h"
18
20typedef enum : uint8_t {
22 k_nibble_mask = 0x0FU,
25
27static const char s_placeholder[] = "{q}";
28
29const char* mdl_search_placeholder(void)
30{
31 return s_placeholder;
32}
33
48RA8_INTERNAL static bool internal_is_unreserved(unsigned char c)
49{
50 const bool alpha = ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'));
51 const bool digit = (c >= '0') && (c <= '9');
52 const bool mark = (c == '-') || (c == '.') || (c == '_') || (c == '~');
53 return alpha || digit || mark;
54}
55
69RA8_INTERNAL static char internal_hex_digit(unsigned nibble)
70{
71 static const char digits[] = "0123456789ABCDEF";
72 return digits[nibble & (unsigned)k_nibble_mask];
73}
74
75bool mdl_query_encode(const char* term, char* out, size_t cap)
76{
77 if ((term == nullptr) || (out == nullptr) || (cap == 0U)) {
78 if ((out != nullptr) && (cap > 0U)) {
79 out[0] = '\0';
80 }
81 return false;
82 }
83 size_t n = 0U;
84 for (size_t i = 0U; term[i] != '\0'; ++i) {
85 const unsigned char c = (unsigned char)term[i];
87 if ((n + 1U) >= cap) {
88 out[0] = '\0';
89 return false;
90 }
91 out[n] = (char)c;
92 ++n;
93 } else {
94 if ((n + (size_t)k_triplet_len) >= cap) {
95 out[0] = '\0';
96 return false;
97 }
98 out[n] = '%';
99 out[n + 1U] = internal_hex_digit((unsigned)c >> (unsigned)k_hi_nibble_shift);
100 out[n + 2U] = internal_hex_digit((unsigned)c);
101 n += (size_t)k_triplet_len;
102 }
103 }
104 out[n] = '\0';
105 return true;
106}
107
108bool mdl_search_build_url(const char* tmpl, const char* encoded_term, char* out, size_t cap)
109{
110 if ((tmpl == nullptr) || (encoded_term == nullptr) || (out == nullptr) || (cap == 0U)) {
111 if ((out != nullptr) && (cap > 0U)) {
112 out[0] = '\0';
113 }
114 return false;
115 }
116 const size_t plen = strlen(s_placeholder);
117 const size_t tlen = strlen(encoded_term);
118 size_t n = 0U;
119 bool hit = false;
120 size_t i = 0U;
121 while (tmpl[i] != '\0') {
122 if (strncmp(tmpl + i, s_placeholder, plen) == 0) {
123 if ((n + tlen) >= cap) {
124 out[0] = '\0';
125 return false;
126 }
127 memcpy(out + n, encoded_term, tlen);
128 n += tlen;
129 i += plen;
130 hit = true;
131 } else {
132 if ((n + 1U) >= cap) {
133 out[0] = '\0';
134 return false;
135 }
136 out[n] = tmpl[i];
137 ++n;
138 ++i;
139 }
140 }
141 if (!hit) {
142 out[0] = '\0';
143 return false; /* a template with no {q} could never carry the term */
144 }
145 out[n] = '\0';
146 return true;
147}
148
150{
151 if (hits == nullptr) {
153 }
154 if (hits->count > 0U) {
156 }
157 if (hits->anchors_seen == 0U) {
159 }
161}
162
163size_t mdl_search_filter_series_hits(mdl_hit_list_t* hits, const char* chapter_marker)
164{
165 if ((hits == nullptr) || (chapter_marker == nullptr)) {
166 return 0U;
167 }
168 const size_t before = hits->count;
169 size_t kept = 0U;
170 for (size_t i = 0U; i < before; ++i) {
171 const mdl_hit_t* candidate = &hits->hits[i];
172 bool reject = false;
173 if ((chapter_marker[0] != '\0') && (strstr(candidate->url, chapter_marker) != nullptr)) {
174 reject = true;
175 }
176 for (size_t j = 0U; (!reject) && (j < kept); ++j) {
177 if (strcmp(candidate->url, hits->hits[j].url) == 0) {
178 reject = true;
179 }
180 }
181 if (!reject) {
182 if (kept != i) {
183 hits->hits[kept] = *candidate;
184 }
185 ++kept;
186 }
187 }
188 hits->count = (uint16_t)kept;
189 return before - kept;
190}
const char * mdl_search_placeholder(void)
The {q} placeholder a search-URL template must contain.
Definition mdl_search.c:29
mdl_search_const_t
Query-encoding constants.
Definition mdl_search.c:20
@ k_triplet_len
Bytes a HH escape occupies.
Definition mdl_search.c:23
@ k_hi_nibble_shift
Bits to shift for the high hex nibble.
Definition mdl_search.c:21
static char internal_hex_digit(unsigned nibble)
Upper-case hex digit for a 0..15 nibble.
Definition mdl_search.c:69
size_t mdl_search_filter_series_hits(mdl_hit_list_t *hits, const char *chapter_marker)
Remove chapter links and duplicate series URLs from discovery hits.
Definition mdl_search.c:163
bool mdl_query_encode(const char *term, char *out, size_t cap)
Percent-encode a raw query term for safe inclusion in a URL.
Definition mdl_search.c:75
mdl_search_outcome_t mdl_search_classify(const mdl_hit_list_t *hits)
Classify a parsed results page into an honest search outcome.
Definition mdl_search.c:149
bool mdl_search_build_url(const char *tmpl, const char *encoded_term, char *out, size_t cap)
Expand a query-URL template by substituting the encoded term for {q}.
Definition mdl_search.c:108
static bool internal_is_unreserved(unsigned char c)
True for an RFC 3986 unreserved byte (copied verbatim).
Definition mdl_search.c:48
static const char s_placeholder[]
The {q} placeholder token, kept in one place.
Definition mdl_search.c:27
Pure search/discovery policy: query encoding, URL templating, and the honest zero-vs-broken result cl...
mdl_search_outcome_t
The honest outcome of a parsed search/browse results page.
Definition mdl_search.h:57
@ k_mdl_search_markup_changed
No links at all: the page could not be read.
Definition mdl_search.h:60
@ k_mdl_search_have_results
One or more hits matched; print them.
Definition mdl_search.h:58
@ k_mdl_search_zero_results
Links present, none matched: a real no-hit.
Definition mdl_search.h:59
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
int strncmp(const char *s1, const char *s2, size_t n)
Compare two strings up to a specified length.
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
size_t strlen(const char *s)
Calculate string length.
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
char * strstr(const char *haystack, const char *needle)
Locate substring in string.
@ k_nibble_mask
Nibble mask.
Bounded list of titled hits plus the raw anchor tally.
Definition mdl_extract.h:68
mdl_hit_t hits[k_mdl_max_hits]
Deduplicated titled hits.
Definition mdl_extract.h:69
size_t count
Number of valid hits.
Definition mdl_extract.h:70
size_t anchors_seen
Total resolvable <a href> anchors.
Definition mdl_extract.h:71
One discovery hit: a human-facing title paired with a series URL.
Definition mdl_extract.h:50
char url[k_mdl_url_max]
Absolute series URL, NUL-terminated.
Definition mdl_extract.h:52