dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 100.0% 38 / 0 / 38
Functions: 100.0% 7 / 0 / 7
Branches: 95.8% 23 / 4 / 28

src/encoding.c
Line Branch Exec Source
1 #include "encoding.h"
2 #include "util/ascii.h"
3 #include "util/bsearch.h"
4 #include "util/debug.h"
5 #include "util/intern.h"
6
7 typedef struct {
8 const char alias[8];
9 EncodingType encoding;
10 } EncodingAlias;
11
12 static const char encoding_names[][16] = {
13 [UTF8] = "UTF-8",
14 [UTF16BE] = "UTF-16BE",
15 [UTF16LE] = "UTF-16LE",
16 [UTF32BE] = "UTF-32BE",
17 [UTF32LE] = "UTF-32LE",
18 };
19
20 static const EncodingAlias encoding_aliases[] = {
21 {"UCS-2", UTF16BE},
22 {"UCS-2BE", UTF16BE},
23 {"UCS-2LE", UTF16LE},
24 {"UCS-4", UTF32BE},
25 {"UCS-4BE", UTF32BE},
26 {"UCS-4LE", UTF32LE},
27 {"UCS2", UTF16BE},
28 {"UCS4", UTF32BE},
29 {"UTF-16", UTF16BE},
30 {"UTF-32", UTF32BE},
31 {"UTF16", UTF16BE},
32 {"UTF16BE", UTF16BE},
33 {"UTF16LE", UTF16LE},
34 {"UTF32", UTF32BE},
35 {"UTF32BE", UTF32BE},
36 {"UTF32LE", UTF32LE},
37 {"UTF8", UTF8},
38 };
39
40 static const ByteOrderMark boms[] = {
41 [UTF8] = {{0xef, 0xbb, 0xbf}, 3},
42 [UTF16BE] = {{0xfe, 0xff}, 2},
43 [UTF16LE] = {{0xff, 0xfe}, 2},
44 [UTF32BE] = {{0x00, 0x00, 0xfe, 0xff}, 4},
45 [UTF32LE] = {{0xff, 0xfe, 0x00, 0x00}, 4},
46 };
47
48 24 UNITTEST {
49 24 CHECK_BSEARCH_ARRAY_ICASE(encoding_aliases, alias);
50 24 CHECK_STRING_ARRAY(encoding_names);
51 24 static_assert(ARRAYLEN(encoding_names) == UNKNOWN_ENCODING);
52 24 static_assert(ARRAYLEN(boms) == UNKNOWN_ENCODING);
53 24 }
54
55 70 static int enc_alias_cmp(const void *key, const void *elem)
56 {
57 70 const EncodingAlias *a = key;
58 70 const char *name = elem;
59 70 return ascii_strcmp_icase(a->alias, name);
60 }
61
62 248 EncodingType lookup_encoding(const char *name)
63 {
64
2/2
✓ Branch 2 → 7 taken 36 times.
✓ Branch 2 → 11 taken 212 times.
248 if (likely(name == encoding_names[UTF8])) {
65 return UTF8;
66 }
67
68
2/2
✓ Branch 7 → 3 taken 112 times.
✓ Branch 7 → 8 taken 18 times.
130 for (size_t i = 0; i < ARRAYLEN(encoding_names); i++) {
69
2/2
✓ Branch 4 → 5 taken 18 times.
✓ Branch 4 → 6 taken 94 times.
112 if (ascii_streq_icase(name, encoding_names[i])) {
70 18 return (EncodingType) i;
71 }
72 }
73
74 18 const EncodingAlias *a = BSEARCH(name, encoding_aliases, enc_alias_cmp);
75
2/2
✓ Branch 9 → 10 taken 12 times.
✓ Branch 9 → 11 taken 6 times.
18 return a ? a->encoding : UNKNOWN_ENCODING;
76 }
77
78 154 const char *encoding_from_type(EncodingType type)
79 {
80 154 BUG_ON(type >= UNKNOWN_ENCODING);
81
82 // There's no need to call str_intern() here; the names in the array
83 // can be considered static interns
84 154 return encoding_names[type];
85 }
86
87 64 const char *encoding_normalize(const char *name)
88 {
89 64 EncodingType type = lookup_encoding(name);
90
2/2
✓ Branch 3 → 4 taken 63 times.
✓ Branch 3 → 6 taken 1 time.
64 if (type != UNKNOWN_ENCODING) {
91 63 return encoding_from_type(type);
92 }
93
94 char upper[256];
95 size_t n;
96
3/4
✓ Branch 6 → 7 taken 8 times.
✗ Branch 6 → 8 not taken.
✓ Branch 7 → 5 taken 7 times.
✓ Branch 7 → 8 taken 1 time.
8 for (n = 0; n < sizeof(upper) && name[n]; n++) {
97 7 upper[n] = ascii_toupper(name[n]);
98 }
99
100 1 return mem_intern(upper, n);
101 }
102
103 51 EncodingType detect_encoding_from_bom(StringView text)
104 {
105 // Skip exhaustive checks if there's clearly no BOM
106 51 if (
107
2/2
✓ Branch 2 → 3 taken 42 times.
✓ Branch 2 → 11 taken 9 times.
51 text.length < 2
108
2/2
✓ Branch 3 → 10 taken 13 times.
✓ Branch 3 → 11 taken 29 times.
42 || ((unsigned int)(unsigned char)text.data[0]) - 1 < 0xEE
109 ) {
110 return UNKNOWN_ENCODING;
111 }
112
113 // Iterate array backwards to ensure UTF32LE is checked before UTF16LE
114
2/2
✓ Branch 10 → 4 taken 53 times.
✓ Branch 10 → 11 taken 7 times.
60 for (size_t n = ARRAYLEN(boms), i = n - 1; i < n; i--) {
115 53 StringView bom = string_view((const char*)boms[i].bytes, boms[i].len);
116 53 BUG_ON(bom.length == 0);
117
2/2
✓ Branch 7 → 8 taken 6 times.
✓ Branch 7 → 9 taken 47 times.
53 if (strview_has_sv_prefix(text, bom)) {
118 6 return (EncodingType)i;
119 }
120 }
121
122 return UNKNOWN_ENCODING;
123 }
124
125 5 const ByteOrderMark *get_bom_for_encoding(EncodingType type)
126 {
127
2/2
✓ Branch 2 → 3 taken 3 times.
✓ Branch 2 → 4 taken 2 times.
5 return encoding_type_has_bom(type) ? &boms[type] : NULL;
128 }
129