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