1 #include <assert.h>
2 #include <stdint.h>
3
4 #include "libmy/ubuf.h"
5
6 static inline void
bytes_shortest_separator(ubuf * start,const uint8_t * limit,size_t len_limit)7 bytes_shortest_separator(ubuf *start, const uint8_t *limit, size_t len_limit)
8 {
9
10 size_t min_length = ubuf_size(start) < len_limit ? ubuf_size(start) : len_limit;
11 size_t diff_index = 0;
12 while ((diff_index < min_length) &&
13 (ubuf_data(start)[diff_index] == limit[diff_index]))
14 {
15 diff_index++;
16 }
17
18 if (diff_index >= min_length)
19 return;
20
21 uint8_t diff_byte = ubuf_data(start)[diff_index];
22 if (diff_byte < 0xFF && diff_byte + 1 < limit[diff_index]) {
23 ubuf_data(start)[diff_index]++;
24 ubuf_clip(start, diff_index + 1);
25 } else if (diff_index < min_length - sizeof(uint16_t)) {
26 /* awww yeah, big endian arithmetic on strings */
27 uint16_t u_start, u_limit, u_between;
28 memcpy(&u_start, &ubuf_data(start)[diff_index], sizeof(u_start));
29 memcpy(&u_limit, &limit[diff_index], sizeof(u_limit));
30 u_start = be16toh(u_start);
31 u_limit = be16toh(u_limit);
32 u_between = u_start + 1;
33 if (u_start <= u_between && u_between <= u_limit) {
34 u_between = htobe16(u_between);
35 memcpy(&ubuf_data(start)[diff_index], &u_between, sizeof(u_between));
36 ubuf_clip(start, diff_index + sizeof(uint16_t));
37 }
38 }
39
40 assert(bytes_compare(ubuf_data(start), ubuf_size(start), limit, len_limit) < 0);
41 }
42