/src/zydis/include/Zydis/Internal/String.h
Line | Count | Source |
1 | | /*************************************************************************************************** |
2 | | |
3 | | Zyan Disassembler Library (Zydis) |
4 | | |
5 | | Original Author : Florian Bernd, Joel Hoener |
6 | | |
7 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
8 | | * of this software and associated documentation files (the "Software"), to deal |
9 | | * in the Software without restriction, including without limitation the rights |
10 | | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
11 | | * copies of the Software, and to permit persons to whom the Software is |
12 | | * furnished to do so, subject to the following conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be included in all |
15 | | * copies or substantial portions of the Software. |
16 | | * |
17 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
18 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
19 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
20 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
21 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
22 | | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
23 | | * SOFTWARE. |
24 | | |
25 | | ***************************************************************************************************/ |
26 | | |
27 | | /** |
28 | | * @file |
29 | | * Provides some internal, more performant, but unsafe helper functions for the `ZyanString` |
30 | | * data-type. |
31 | | * |
32 | | * Most of these functions are very similar to the ones in `Zycore/String.h`, but inlined and |
33 | | * without optional overhead like parameter-validation checks, etc ... |
34 | | * |
35 | | * The `ZyanString` data-type is able to dynamically allocate memory on the heap, but as `Zydis` is |
36 | | * designed to be a non-'malloc'ing library, all functions in this file assume that the instances |
37 | | * they are operating on are created with a user-defined static-buffer. |
38 | | */ |
39 | | |
40 | | #ifndef ZYDIS_INTERNAL_STRING_H |
41 | | #define ZYDIS_INTERNAL_STRING_H |
42 | | |
43 | | #include <Zycore/LibC.h> |
44 | | #include <Zycore/String.h> |
45 | | #include <Zycore/Types.h> |
46 | | #include <Zycore/Format.h> |
47 | | #include <Zydis/ShortString.h> |
48 | | #include <Zycore/Defines.h> |
49 | | #include <Zycore/Status.h> |
50 | | #include <Zycore/Vector.h> |
51 | | |
52 | | #ifdef __cplusplus |
53 | | extern "C" { |
54 | | #endif |
55 | | |
56 | | /* ============================================================================================== */ |
57 | | /* Enums and types */ |
58 | | /* ============================================================================================== */ |
59 | | |
60 | | /* ---------------------------------------------------------------------------------------------- */ |
61 | | /* Letter Case */ |
62 | | /* ---------------------------------------------------------------------------------------------- */ |
63 | | |
64 | | /** |
65 | | * Defines the `ZydisLetterCase` enum. |
66 | | */ |
67 | | typedef enum ZydisLetterCase_ |
68 | | { |
69 | | /** |
70 | | * Uses the given text "as is". |
71 | | */ |
72 | | ZYDIS_LETTER_CASE_DEFAULT, |
73 | | /** |
74 | | * Converts the given text to lowercase letters. |
75 | | */ |
76 | | ZYDIS_LETTER_CASE_LOWER, |
77 | | /** |
78 | | * Converts the given text to uppercase letters. |
79 | | */ |
80 | | ZYDIS_LETTER_CASE_UPPER, |
81 | | |
82 | | /** |
83 | | * Maximum value of this enum. |
84 | | */ |
85 | | ZYDIS_LETTER_CASE_MAX_VALUE = ZYDIS_LETTER_CASE_UPPER, |
86 | | /** |
87 | | * The minimum number of bits required to represent all values of this enum. |
88 | | */ |
89 | | ZYDIS_LETTER_CASE_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_LETTER_CASE_MAX_VALUE) |
90 | | } ZydisLetterCase; |
91 | | |
92 | | /* ---------------------------------------------------------------------------------------------- */ |
93 | | |
94 | | /* ============================================================================================== */ |
95 | | /* Macros */ |
96 | | /* ============================================================================================== */ |
97 | | |
98 | | /* ---------------------------------------------------------------------------------------------- */ |
99 | | /* Internal macros */ |
100 | | /* ---------------------------------------------------------------------------------------------- */ |
101 | | |
102 | | /** |
103 | | * Checks for a terminating '\0' character at the end of the string data. |
104 | | */ |
105 | | #define ZYDIS_STRING_ASSERT_NULLTERMINATION(string) \ |
106 | 39.3k | ZYAN_ASSERT(*(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) == '\0'); |
107 | | |
108 | | /** |
109 | | * Writes a terminating '\0' character at the end of the string data. |
110 | | */ |
111 | | #define ZYDIS_STRING_NULLTERMINATE(string) \ |
112 | 10.3k | *(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) = '\0'; |
113 | | |
114 | | /* ---------------------------------------------------------------------------------------------- */ |
115 | | |
116 | | /* ============================================================================================== */ |
117 | | /* Internal Functions */ |
118 | | /* ============================================================================================== */ |
119 | | |
120 | | /* ---------------------------------------------------------------------------------------------- */ |
121 | | /* Appending */ |
122 | | /* ---------------------------------------------------------------------------------------------- */ |
123 | | |
124 | | /** |
125 | | * Appends the content of the source string to the end of the destination string. |
126 | | * |
127 | | * @param destination The destination string. |
128 | | * @param source The source string. |
129 | | * |
130 | | * @return A zyan status code. |
131 | | */ |
132 | | ZYAN_INLINE ZyanStatus ZydisStringAppend(ZyanString* destination, const ZyanStringView* source) |
133 | 6.24k | { |
134 | 6.24k | ZYAN_ASSERT(destination && source); |
135 | 6.24k | ZYAN_ASSERT(!destination->vector.allocator); |
136 | 6.24k | ZYAN_ASSERT(destination->vector.size && source->string.vector.size); |
137 | | |
138 | 6.24k | if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) |
139 | 381 | { |
140 | 381 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; |
141 | 381 | } |
142 | | |
143 | 5.85k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, |
144 | 5.85k | source->string.vector.data, source->string.vector.size - 1); |
145 | | |
146 | 5.85k | destination->vector.size += source->string.vector.size - 1; |
147 | 5.85k | ZYDIS_STRING_NULLTERMINATE(destination); |
148 | | |
149 | 5.85k | return ZYAN_STATUS_SUCCESS; |
150 | 6.24k | } Unexecuted instantiation: Formatter.c:ZydisStringAppend Unexecuted instantiation: FormatterBuffer.c:ZydisStringAppend FormatterATT.c:ZydisStringAppend Line | Count | Source | 133 | 336 | { | 134 | 336 | ZYAN_ASSERT(destination && source); | 135 | 336 | ZYAN_ASSERT(!destination->vector.allocator); | 136 | 336 | ZYAN_ASSERT(destination->vector.size && source->string.vector.size); | 137 | | | 138 | 336 | if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) | 139 | 41 | { | 140 | 41 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 141 | 41 | } | 142 | | | 143 | 295 | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, | 144 | 295 | source->string.vector.data, source->string.vector.size - 1); | 145 | | | 146 | 295 | destination->vector.size += source->string.vector.size - 1; | 147 | 295 | ZYDIS_STRING_NULLTERMINATE(destination); | 148 | | | 149 | 295 | return ZYAN_STATUS_SUCCESS; | 150 | 336 | } |
FormatterBase.c:ZydisStringAppend Line | Count | Source | 133 | 481 | { | 134 | 481 | ZYAN_ASSERT(destination && source); | 135 | 481 | ZYAN_ASSERT(!destination->vector.allocator); | 136 | 481 | ZYAN_ASSERT(destination->vector.size && source->string.vector.size); | 137 | | | 138 | 481 | if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) | 139 | 38 | { | 140 | 38 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 141 | 38 | } | 142 | | | 143 | 443 | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, | 144 | 443 | source->string.vector.data, source->string.vector.size - 1); | 145 | | | 146 | 443 | destination->vector.size += source->string.vector.size - 1; | 147 | 443 | ZYDIS_STRING_NULLTERMINATE(destination); | 148 | | | 149 | 443 | return ZYAN_STATUS_SUCCESS; | 150 | 481 | } |
FormatterIntel.c:ZydisStringAppend Line | Count | Source | 133 | 309 | { | 134 | 309 | ZYAN_ASSERT(destination && source); | 135 | 309 | ZYAN_ASSERT(!destination->vector.allocator); | 136 | 309 | ZYAN_ASSERT(destination->vector.size && source->string.vector.size); | 137 | | | 138 | 309 | if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) | 139 | 48 | { | 140 | 48 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 141 | 48 | } | 142 | | | 143 | 261 | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, | 144 | 261 | source->string.vector.data, source->string.vector.size - 1); | 145 | | | 146 | 261 | destination->vector.size += source->string.vector.size - 1; | 147 | 261 | ZYDIS_STRING_NULLTERMINATE(destination); | 148 | | | 149 | 261 | return ZYAN_STATUS_SUCCESS; | 150 | 309 | } |
String.c:ZydisStringAppend Line | Count | Source | 133 | 5.11k | { | 134 | 5.11k | ZYAN_ASSERT(destination && source); | 135 | 5.11k | ZYAN_ASSERT(!destination->vector.allocator); | 136 | 5.11k | ZYAN_ASSERT(destination->vector.size && source->string.vector.size); | 137 | | | 138 | 5.11k | if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) | 139 | 254 | { | 140 | 254 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 141 | 254 | } | 142 | | | 143 | 4.86k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, | 144 | 4.86k | source->string.vector.data, source->string.vector.size - 1); | 145 | | | 146 | 4.86k | destination->vector.size += source->string.vector.size - 1; | 147 | 4.86k | ZYDIS_STRING_NULLTERMINATE(destination); | 148 | | | 149 | 4.86k | return ZYAN_STATUS_SUCCESS; | 150 | 5.11k | } |
|
151 | | |
152 | | /** |
153 | | * Appends the content of the source string to the end of the destination |
154 | | * string, converting the characters to the specified letter-case. |
155 | | * |
156 | | * @param destination The destination string. |
157 | | * @param source The source string. |
158 | | * @param letter_case The desired letter-case. |
159 | | * |
160 | | * @return A zyan status code. |
161 | | */ |
162 | | ZYAN_INLINE ZyanStatus ZydisStringAppendCase(ZyanString* destination, const ZyanStringView* source, |
163 | | ZydisLetterCase letter_case) |
164 | 0 | { |
165 | 0 | ZYAN_ASSERT(destination && source); |
166 | 0 | ZYAN_ASSERT(!destination->vector.allocator); |
167 | 0 | ZYAN_ASSERT(destination->vector.size && source->string.vector.size); |
168 | 0 |
|
169 | 0 | if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity) |
170 | 0 | { |
171 | 0 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; |
172 | 0 | } |
173 | 0 |
|
174 | 0 | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, |
175 | 0 | source->string.vector.data, source->string.vector.size - 1); |
176 | 0 |
|
177 | 0 | switch (letter_case) |
178 | 0 | { |
179 | 0 | case ZYDIS_LETTER_CASE_DEFAULT: |
180 | 0 | break; |
181 | 0 | case ZYDIS_LETTER_CASE_LOWER: |
182 | 0 | { |
183 | 0 | const ZyanUSize index = destination->vector.size - 1; |
184 | 0 | const ZyanUSize count = source->string.vector.size - 1; |
185 | 0 | char* s = (char*)destination->vector.data + index; |
186 | 0 | for (ZyanUSize i = index; i < index + count; ++i) |
187 | 0 | { |
188 | 0 | const char c = *s; |
189 | 0 | if ((c >= 'A') && (c <= 'Z')) |
190 | 0 | { |
191 | 0 | *s = c | 32; |
192 | 0 | } |
193 | 0 | ++s; |
194 | 0 | } |
195 | 0 | break; |
196 | 0 | } |
197 | 0 | case ZYDIS_LETTER_CASE_UPPER: |
198 | 0 | { |
199 | 0 | const ZyanUSize index = destination->vector.size - 1; |
200 | 0 | const ZyanUSize count = source->string.vector.size - 1; |
201 | 0 | char* s = (char*)destination->vector.data + index; |
202 | 0 | for (ZyanUSize i = index; i < index + count; ++i) |
203 | 0 | { |
204 | 0 | const char c = *s; |
205 | 0 | if ((c >= 'a') && (c <= 'z')) |
206 | 0 | { |
207 | 0 | *s = c & ~32; |
208 | 0 | } |
209 | 0 | ++s; |
210 | 0 | } |
211 | 0 | break; |
212 | 0 | } |
213 | 0 | default: |
214 | 0 | ZYAN_UNREACHABLE; |
215 | 0 | } |
216 | 0 |
|
217 | 0 | destination->vector.size += source->string.vector.size - 1; |
218 | 0 | ZYDIS_STRING_NULLTERMINATE(destination); |
219 | 0 |
|
220 | 0 | return ZYAN_STATUS_SUCCESS; |
221 | 0 | } Unexecuted instantiation: Formatter.c:ZydisStringAppendCase Unexecuted instantiation: FormatterBuffer.c:ZydisStringAppendCase Unexecuted instantiation: FormatterATT.c:ZydisStringAppendCase Unexecuted instantiation: FormatterBase.c:ZydisStringAppendCase Unexecuted instantiation: FormatterIntel.c:ZydisStringAppendCase Unexecuted instantiation: String.c:ZydisStringAppendCase |
222 | | |
223 | | /** |
224 | | * Appends the content of the source short-string to the end of the destination string. |
225 | | * |
226 | | * @param destination The destination string. |
227 | | * @param source The source string. |
228 | | * |
229 | | * @return A zyan status code. |
230 | | */ |
231 | | ZYAN_INLINE ZyanStatus ZydisStringAppendShort(ZyanString* destination, |
232 | | const ZydisShortString* source) |
233 | 20.1k | { |
234 | 20.1k | ZYAN_ASSERT(destination && source); |
235 | 20.1k | ZYAN_ASSERT(!destination->vector.allocator); |
236 | 20.1k | ZYAN_ASSERT(destination->vector.size && source->size); |
237 | | |
238 | 20.1k | if (destination->vector.size + source->size > destination->vector.capacity) |
239 | 430 | { |
240 | 430 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; |
241 | 430 | } |
242 | | |
243 | 19.7k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, |
244 | 19.7k | (ZyanUSize)source->size + 1); |
245 | | |
246 | 19.7k | destination->vector.size += source->size; |
247 | 19.7k | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); |
248 | | |
249 | 19.7k | return ZYAN_STATUS_SUCCESS; |
250 | 19.7k | } Unexecuted instantiation: Formatter.c:ZydisStringAppendShort Unexecuted instantiation: FormatterBuffer.c:ZydisStringAppendShort FormatterATT.c:ZydisStringAppendShort Line | Count | Source | 233 | 9.65k | { | 234 | 9.65k | ZYAN_ASSERT(destination && source); | 235 | 9.65k | ZYAN_ASSERT(!destination->vector.allocator); | 236 | 9.65k | ZYAN_ASSERT(destination->vector.size && source->size); | 237 | | | 238 | 9.65k | if (destination->vector.size + source->size > destination->vector.capacity) | 239 | 183 | { | 240 | 183 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 241 | 183 | } | 242 | | | 243 | 9.47k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, | 244 | 9.47k | (ZyanUSize)source->size + 1); | 245 | | | 246 | 9.47k | destination->vector.size += source->size; | 247 | 9.47k | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); | 248 | | | 249 | 9.47k | return ZYAN_STATUS_SUCCESS; | 250 | 9.47k | } |
FormatterBase.c:ZydisStringAppendShort Line | Count | Source | 233 | 3.32k | { | 234 | 3.32k | ZYAN_ASSERT(destination && source); | 235 | 3.32k | ZYAN_ASSERT(!destination->vector.allocator); | 236 | 3.32k | ZYAN_ASSERT(destination->vector.size && source->size); | 237 | | | 238 | 3.32k | if (destination->vector.size + source->size > destination->vector.capacity) | 239 | 72 | { | 240 | 72 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 241 | 72 | } | 242 | | | 243 | 3.25k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, | 244 | 3.25k | (ZyanUSize)source->size + 1); | 245 | | | 246 | 3.25k | destination->vector.size += source->size; | 247 | 3.25k | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); | 248 | | | 249 | 3.25k | return ZYAN_STATUS_SUCCESS; | 250 | 3.25k | } |
FormatterIntel.c:ZydisStringAppendShort Line | Count | Source | 233 | 7.17k | { | 234 | 7.17k | ZYAN_ASSERT(destination && source); | 235 | 7.17k | ZYAN_ASSERT(!destination->vector.allocator); | 236 | 7.17k | ZYAN_ASSERT(destination->vector.size && source->size); | 237 | | | 238 | 7.17k | if (destination->vector.size + source->size > destination->vector.capacity) | 239 | 175 | { | 240 | 175 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 241 | 175 | } | 242 | | | 243 | 6.99k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, | 244 | 6.99k | (ZyanUSize)source->size + 1); | 245 | | | 246 | 6.99k | destination->vector.size += source->size; | 247 | 6.99k | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); | 248 | | | 249 | 6.99k | return ZYAN_STATUS_SUCCESS; | 250 | 6.99k | } |
Unexecuted instantiation: String.c:ZydisStringAppendShort |
251 | | |
252 | | /** |
253 | | * Appends the content of the source short-string to the end of the destination string, |
254 | | * converting the characters to the specified letter-case. |
255 | | * |
256 | | * @param destination The destination string. |
257 | | * @param source The source string. |
258 | | * @param letter_case The desired letter-case. |
259 | | * |
260 | | * @return A zyan status code. |
261 | | */ |
262 | | ZYAN_INLINE ZyanStatus ZydisStringAppendShortCase(ZyanString* destination, |
263 | | const ZydisShortString* source, ZydisLetterCase letter_case) |
264 | 20.4k | { |
265 | 20.4k | ZYAN_ASSERT(destination && source); |
266 | 20.4k | ZYAN_ASSERT(!destination->vector.allocator); |
267 | 20.4k | ZYAN_ASSERT(destination->vector.size && source->size); |
268 | | |
269 | 20.4k | if (destination->vector.size + source->size > destination->vector.capacity) |
270 | 816 | { |
271 | 816 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; |
272 | 816 | } |
273 | | |
274 | 19.5k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, |
275 | 19.5k | (ZyanUSize)source->size + 1); |
276 | | |
277 | 19.5k | switch (letter_case) |
278 | 19.5k | { |
279 | 5.50k | case ZYDIS_LETTER_CASE_DEFAULT: |
280 | 5.50k | break; |
281 | 0 | case ZYDIS_LETTER_CASE_LOWER: |
282 | 0 | { |
283 | 0 | const ZyanUSize index = destination->vector.size - 1; |
284 | 0 | const ZyanUSize count = source->size; |
285 | 0 | char* s = (char*)destination->vector.data + index; |
286 | 0 | for (ZyanUSize i = index; i < index + count; ++i) |
287 | 0 | { |
288 | 0 | const char c = *s; |
289 | 0 | if ((c >= 'A') && (c <= 'Z')) |
290 | 0 | { |
291 | 0 | *s = c | 32; |
292 | 0 | } |
293 | 0 | ++s; |
294 | 0 | } |
295 | 0 | break; |
296 | 0 | } |
297 | 14.0k | case ZYDIS_LETTER_CASE_UPPER: |
298 | 14.0k | { |
299 | 14.0k | const ZyanUSize index = destination->vector.size - 1; |
300 | 14.0k | const ZyanUSize count = source->size; |
301 | 14.0k | char* s = (char*)destination->vector.data + index; |
302 | 59.4k | for (ZyanUSize i = index; i < index + count; ++i) |
303 | 45.4k | { |
304 | 45.4k | const char c = *s; |
305 | 45.4k | if ((c >= 'a') && (c <= 'z')) |
306 | 40.6k | { |
307 | 40.6k | *s = c & ~32; |
308 | 40.6k | } |
309 | 45.4k | ++s; |
310 | 45.4k | } |
311 | 14.0k | break; |
312 | 0 | } |
313 | 0 | default: |
314 | 0 | ZYAN_UNREACHABLE; |
315 | 19.5k | } |
316 | | |
317 | 19.5k | destination->vector.size += source->size; |
318 | 19.5k | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); |
319 | | |
320 | 19.5k | return ZYAN_STATUS_SUCCESS; |
321 | 19.5k | } Unexecuted instantiation: Formatter.c:ZydisStringAppendShortCase Unexecuted instantiation: FormatterBuffer.c:ZydisStringAppendShortCase FormatterATT.c:ZydisStringAppendShortCase Line | Count | Source | 264 | 9.92k | { | 265 | 9.92k | ZYAN_ASSERT(destination && source); | 266 | 9.92k | ZYAN_ASSERT(!destination->vector.allocator); | 267 | 9.92k | ZYAN_ASSERT(destination->vector.size && source->size); | 268 | | | 269 | 9.92k | if (destination->vector.size + source->size > destination->vector.capacity) | 270 | 405 | { | 271 | 405 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 272 | 405 | } | 273 | | | 274 | 9.52k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, | 275 | 9.52k | (ZyanUSize)source->size + 1); | 276 | | | 277 | 9.52k | switch (letter_case) | 278 | 9.52k | { | 279 | 2.60k | case ZYDIS_LETTER_CASE_DEFAULT: | 280 | 2.60k | break; | 281 | 0 | case ZYDIS_LETTER_CASE_LOWER: | 282 | 0 | { | 283 | 0 | const ZyanUSize index = destination->vector.size - 1; | 284 | 0 | const ZyanUSize count = source->size; | 285 | 0 | char* s = (char*)destination->vector.data + index; | 286 | 0 | for (ZyanUSize i = index; i < index + count; ++i) | 287 | 0 | { | 288 | 0 | const char c = *s; | 289 | 0 | if ((c >= 'A') && (c <= 'Z')) | 290 | 0 | { | 291 | 0 | *s = c | 32; | 292 | 0 | } | 293 | 0 | ++s; | 294 | 0 | } | 295 | 0 | break; | 296 | 0 | } | 297 | 6.91k | case ZYDIS_LETTER_CASE_UPPER: | 298 | 6.91k | { | 299 | 6.91k | const ZyanUSize index = destination->vector.size - 1; | 300 | 6.91k | const ZyanUSize count = source->size; | 301 | 6.91k | char* s = (char*)destination->vector.data + index; | 302 | 28.2k | for (ZyanUSize i = index; i < index + count; ++i) | 303 | 21.3k | { | 304 | 21.3k | const char c = *s; | 305 | 21.3k | if ((c >= 'a') && (c <= 'z')) | 306 | 19.5k | { | 307 | 19.5k | *s = c & ~32; | 308 | 19.5k | } | 309 | 21.3k | ++s; | 310 | 21.3k | } | 311 | 6.91k | break; | 312 | 0 | } | 313 | 0 | default: | 314 | 0 | ZYAN_UNREACHABLE; | 315 | 9.52k | } | 316 | | | 317 | 9.52k | destination->vector.size += source->size; | 318 | 9.52k | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); | 319 | | | 320 | 9.52k | return ZYAN_STATUS_SUCCESS; | 321 | 9.52k | } |
FormatterBase.c:ZydisStringAppendShortCase Line | Count | Source | 264 | 893 | { | 265 | 893 | ZYAN_ASSERT(destination && source); | 266 | 893 | ZYAN_ASSERT(!destination->vector.allocator); | 267 | 893 | ZYAN_ASSERT(destination->vector.size && source->size); | 268 | | | 269 | 893 | if (destination->vector.size + source->size > destination->vector.capacity) | 270 | 84 | { | 271 | 84 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 272 | 84 | } | 273 | | | 274 | 809 | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, | 275 | 809 | (ZyanUSize)source->size + 1); | 276 | | | 277 | 809 | switch (letter_case) | 278 | 809 | { | 279 | 291 | case ZYDIS_LETTER_CASE_DEFAULT: | 280 | 291 | break; | 281 | 0 | case ZYDIS_LETTER_CASE_LOWER: | 282 | 0 | { | 283 | 0 | const ZyanUSize index = destination->vector.size - 1; | 284 | 0 | const ZyanUSize count = source->size; | 285 | 0 | char* s = (char*)destination->vector.data + index; | 286 | 0 | for (ZyanUSize i = index; i < index + count; ++i) | 287 | 0 | { | 288 | 0 | const char c = *s; | 289 | 0 | if ((c >= 'A') && (c <= 'Z')) | 290 | 0 | { | 291 | 0 | *s = c | 32; | 292 | 0 | } | 293 | 0 | ++s; | 294 | 0 | } | 295 | 0 | break; | 296 | 0 | } | 297 | 518 | case ZYDIS_LETTER_CASE_UPPER: | 298 | 518 | { | 299 | 518 | const ZyanUSize index = destination->vector.size - 1; | 300 | 518 | const ZyanUSize count = source->size; | 301 | 518 | char* s = (char*)destination->vector.data + index; | 302 | 3.79k | for (ZyanUSize i = index; i < index + count; ++i) | 303 | 3.27k | { | 304 | 3.27k | const char c = *s; | 305 | 3.27k | if ((c >= 'a') && (c <= 'z')) | 306 | 2.19k | { | 307 | 2.19k | *s = c & ~32; | 308 | 2.19k | } | 309 | 3.27k | ++s; | 310 | 3.27k | } | 311 | 518 | break; | 312 | 0 | } | 313 | 0 | default: | 314 | 0 | ZYAN_UNREACHABLE; | 315 | 809 | } | 316 | | | 317 | 809 | destination->vector.size += source->size; | 318 | 809 | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); | 319 | | | 320 | 809 | return ZYAN_STATUS_SUCCESS; | 321 | 809 | } |
FormatterIntel.c:ZydisStringAppendShortCase Line | Count | Source | 264 | 9.59k | { | 265 | 9.59k | ZYAN_ASSERT(destination && source); | 266 | 9.59k | ZYAN_ASSERT(!destination->vector.allocator); | 267 | 9.59k | ZYAN_ASSERT(destination->vector.size && source->size); | 268 | | | 269 | 9.59k | if (destination->vector.size + source->size > destination->vector.capacity) | 270 | 327 | { | 271 | 327 | return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE; | 272 | 327 | } | 273 | | | 274 | 9.26k | ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data, | 275 | 9.26k | (ZyanUSize)source->size + 1); | 276 | | | 277 | 9.26k | switch (letter_case) | 278 | 9.26k | { | 279 | 2.60k | case ZYDIS_LETTER_CASE_DEFAULT: | 280 | 2.60k | break; | 281 | 0 | case ZYDIS_LETTER_CASE_LOWER: | 282 | 0 | { | 283 | 0 | const ZyanUSize index = destination->vector.size - 1; | 284 | 0 | const ZyanUSize count = source->size; | 285 | 0 | char* s = (char*)destination->vector.data + index; | 286 | 0 | for (ZyanUSize i = index; i < index + count; ++i) | 287 | 0 | { | 288 | 0 | const char c = *s; | 289 | 0 | if ((c >= 'A') && (c <= 'Z')) | 290 | 0 | { | 291 | 0 | *s = c | 32; | 292 | 0 | } | 293 | 0 | ++s; | 294 | 0 | } | 295 | 0 | break; | 296 | 0 | } | 297 | 6.66k | case ZYDIS_LETTER_CASE_UPPER: | 298 | 6.66k | { | 299 | 6.66k | const ZyanUSize index = destination->vector.size - 1; | 300 | 6.66k | const ZyanUSize count = source->size; | 301 | 6.66k | char* s = (char*)destination->vector.data + index; | 302 | 27.4k | for (ZyanUSize i = index; i < index + count; ++i) | 303 | 20.7k | { | 304 | 20.7k | const char c = *s; | 305 | 20.7k | if ((c >= 'a') && (c <= 'z')) | 306 | 18.8k | { | 307 | 18.8k | *s = c & ~32; | 308 | 18.8k | } | 309 | 20.7k | ++s; | 310 | 20.7k | } | 311 | 6.66k | break; | 312 | 0 | } | 313 | 0 | default: | 314 | 0 | ZYAN_UNREACHABLE; | 315 | 9.26k | } | 316 | | | 317 | 9.26k | destination->vector.size += source->size; | 318 | 9.26k | ZYDIS_STRING_ASSERT_NULLTERMINATION(destination); | 319 | | | 320 | 9.26k | return ZYAN_STATUS_SUCCESS; | 321 | 9.26k | } |
Unexecuted instantiation: String.c:ZydisStringAppendShortCase |
322 | | |
323 | | /* ---------------------------------------------------------------------------------------------- */ |
324 | | /* Formatting */ |
325 | | /* ---------------------------------------------------------------------------------------------- */ |
326 | | |
327 | | /** |
328 | | * Formats the given unsigned ordinal `value` to its decimal text-representation and |
329 | | * appends it to the `string`. |
330 | | * |
331 | | * @param string A pointer to the `ZyanString` instance. |
332 | | * @param value The value to append. |
333 | | * @param padding_length Padds the converted value with leading zeros, if the number of chars is |
334 | | * less than the `padding_length`. |
335 | | * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. |
336 | | * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. |
337 | | * |
338 | | * @return A zyan status code. |
339 | | * |
340 | | * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified |
341 | | * `ZyanString` instance. |
342 | | */ |
343 | | ZyanStatus ZydisStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length, |
344 | | const ZyanStringView* prefix, const ZyanStringView* suffix); |
345 | | |
346 | | /** |
347 | | * Formats the given signed ordinal `value` to its decimal text-representation and |
348 | | * appends it to the `string`. |
349 | | * |
350 | | * @param string A pointer to the `ZyanString` instance. |
351 | | * @param value The value to append. |
352 | | * @param padding_length Padds the converted value with leading zeros, if the number of chars is |
353 | | * less than the `padding_length`. |
354 | | * @param force_sign Enable this option to print the `+` sign for positive numbers. |
355 | | * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. |
356 | | * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. |
357 | | * |
358 | | * @return A zyan status code. |
359 | | * |
360 | | * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified |
361 | | * `ZyanString` instance. |
362 | | */ |
363 | | ZYAN_INLINE ZyanStatus ZydisStringAppendDecS(ZyanString* string, ZyanI64 value, |
364 | | ZyanU8 padding_length, ZyanBool force_sign, const ZyanStringView* prefix, |
365 | | const ZyanStringView* suffix) |
366 | 1.29k | { |
367 | 1.29k | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); |
368 | 1.29k | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); |
369 | | |
370 | 1.29k | if (value < 0) |
371 | 916 | { |
372 | 916 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); |
373 | 890 | if (prefix) |
374 | 631 | { |
375 | 631 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); |
376 | 631 | } |
377 | 821 | return ZydisStringAppendDecU(string, ZyanAbsI64(value), padding_length, |
378 | 821 | (const ZyanStringView*)ZYAN_NULL, suffix); |
379 | 890 | } |
380 | | |
381 | 375 | if (force_sign) |
382 | 281 | { |
383 | 281 | ZYAN_ASSERT(value >= 0); |
384 | 281 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); |
385 | 281 | } |
386 | 364 | return ZydisStringAppendDecU(string, value, padding_length, prefix, suffix); |
387 | 375 | } Unexecuted instantiation: Formatter.c:ZydisStringAppendDecS Unexecuted instantiation: FormatterBuffer.c:ZydisStringAppendDecS FormatterATT.c:ZydisStringAppendDecS Line | Count | Source | 366 | 298 | { | 367 | 298 | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); | 368 | 298 | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); | 369 | | | 370 | 298 | if (value < 0) | 371 | 204 | { | 372 | 204 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); | 373 | 194 | if (prefix) | 374 | 144 | { | 375 | 144 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); | 376 | 144 | } | 377 | 177 | return ZydisStringAppendDecU(string, ZyanAbsI64(value), padding_length, | 378 | 177 | (const ZyanStringView*)ZYAN_NULL, suffix); | 379 | 194 | } | 380 | | | 381 | 94 | if (force_sign) | 382 | 0 | { | 383 | 0 | ZYAN_ASSERT(value >= 0); | 384 | 0 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); | 385 | 0 | } | 386 | 94 | return ZydisStringAppendDecU(string, value, padding_length, prefix, suffix); | 387 | 94 | } |
FormatterBase.c:ZydisStringAppendDecS Line | Count | Source | 366 | 493 | { | 367 | 493 | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); | 368 | 493 | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); | 369 | | | 370 | 493 | if (value < 0) | 371 | 357 | { | 372 | 357 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); | 373 | 345 | if (prefix) | 374 | 232 | { | 375 | 232 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); | 376 | 232 | } | 377 | 327 | return ZydisStringAppendDecU(string, ZyanAbsI64(value), padding_length, | 378 | 327 | (const ZyanStringView*)ZYAN_NULL, suffix); | 379 | 345 | } | 380 | | | 381 | 136 | if (force_sign) | 382 | 136 | { | 383 | 136 | ZYAN_ASSERT(value >= 0); | 384 | 136 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); | 385 | 136 | } | 386 | 129 | return ZydisStringAppendDecU(string, value, padding_length, prefix, suffix); | 387 | 136 | } |
FormatterIntel.c:ZydisStringAppendDecS Line | Count | Source | 366 | 500 | { | 367 | 500 | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); | 368 | 500 | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); | 369 | | | 370 | 500 | if (value < 0) | 371 | 355 | { | 372 | 355 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); | 373 | 351 | if (prefix) | 374 | 255 | { | 375 | 255 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); | 376 | 255 | } | 377 | 317 | return ZydisStringAppendDecU(string, ZyanAbsI64(value), padding_length, | 378 | 317 | (const ZyanStringView*)ZYAN_NULL, suffix); | 379 | 351 | } | 380 | | | 381 | 145 | if (force_sign) | 382 | 145 | { | 383 | 145 | ZYAN_ASSERT(value >= 0); | 384 | 145 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); | 385 | 145 | } | 386 | 141 | return ZydisStringAppendDecU(string, value, padding_length, prefix, suffix); | 387 | 145 | } |
Unexecuted instantiation: String.c:ZydisStringAppendDecS |
388 | | |
389 | | /** |
390 | | * Formats the given unsigned ordinal `value` to its hexadecimal text-representation and |
391 | | * appends it to the `string`. |
392 | | * |
393 | | * @param string A pointer to the `ZyanString` instance. |
394 | | * @param value The value to append. |
395 | | * @param padding_length Pads the converted value with leading zeros if the number of |
396 | | * chars is less than the `padding_length`. |
397 | | * @param force_leading_number Enable this option to prepend a leading `0` if the first |
398 | | * character is non-numeric. |
399 | | * @param uppercase Enable this option to use uppercase letters ('A'-'F') instead |
400 | | * of lowercase ones ('a'-'f'). |
401 | | * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. |
402 | | * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. |
403 | | * |
404 | | * @return A zyan status code. |
405 | | * |
406 | | * This function will fail, if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified |
407 | | * `ZyanString` instance. |
408 | | */ |
409 | | ZyanStatus ZydisStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length, |
410 | | ZyanBool force_leading_number, ZyanBool uppercase, const ZyanStringView* prefix, |
411 | | const ZyanStringView* suffix); |
412 | | |
413 | | /** |
414 | | * Formats the given signed ordinal `value` to its hexadecimal text-representation and |
415 | | * appends it to the `string`. |
416 | | * |
417 | | * @param string A pointer to the `ZyanString` instance. |
418 | | * @param value The value to append. |
419 | | * @param padding_length Padds the converted value with leading zeros, if the number of |
420 | | * chars is less than the `padding_length` (the sign char does not |
421 | | * count). |
422 | | * @param force_leading_number Enable this option to prepend a leading `0`, if the first |
423 | | * character is non-numeric. |
424 | | * @param uppercase Enable this option to use uppercase letters ('A'-'F') instead |
425 | | * of lowercase ones ('a'-'f'). |
426 | | * @param force_sign Enable this option to print the `+` sign for positive numbers. |
427 | | * @param prefix The string to use as prefix or `ZYAN_NULL`, if not needed. |
428 | | * @param suffix The string to use as suffix or `ZYAN_NULL`, if not needed. |
429 | | * |
430 | | * @return A zyan status code. |
431 | | * |
432 | | * This function will fail if the `ZYAN_STRING_IS_IMMUTABLE` flag is set for the specified |
433 | | * `ZyanString` instance. |
434 | | */ |
435 | | ZYAN_INLINE ZyanStatus ZydisStringAppendHexS(ZyanString* string, ZyanI64 value, |
436 | | ZyanU8 padding_length, ZyanBool force_leading_number, ZyanBool uppercase, ZyanBool force_sign, |
437 | | const ZyanStringView* prefix, const ZyanStringView* suffix) |
438 | 1.02k | { |
439 | 1.02k | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); |
440 | 1.02k | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); |
441 | | |
442 | 1.02k | if (value < 0) |
443 | 712 | { |
444 | 712 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); |
445 | 686 | if (prefix) |
446 | 495 | { |
447 | 495 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); |
448 | 495 | } |
449 | 628 | return ZydisStringAppendHexU(string, ZyanAbsI64(value), padding_length, |
450 | 628 | force_leading_number, uppercase, (const ZyanStringView*)ZYAN_NULL, suffix); |
451 | 686 | } |
452 | | |
453 | 317 | if (force_sign) |
454 | 208 | { |
455 | 208 | ZYAN_ASSERT(value >= 0); |
456 | 208 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); |
457 | 208 | } |
458 | 312 | return ZydisStringAppendHexU(string, value, padding_length, force_leading_number, uppercase, |
459 | 312 | prefix, suffix); |
460 | 317 | } Unexecuted instantiation: Formatter.c:ZydisStringAppendHexS Unexecuted instantiation: FormatterBuffer.c:ZydisStringAppendHexS FormatterATT.c:ZydisStringAppendHexS Line | Count | Source | 438 | 353 | { | 439 | 353 | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); | 440 | 353 | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); | 441 | | | 442 | 353 | if (value < 0) | 443 | 244 | { | 444 | 244 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); | 445 | 231 | if (prefix) | 446 | 192 | { | 447 | 192 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); | 448 | 192 | } | 449 | 207 | return ZydisStringAppendHexU(string, ZyanAbsI64(value), padding_length, | 450 | 207 | force_leading_number, uppercase, (const ZyanStringView*)ZYAN_NULL, suffix); | 451 | 231 | } | 452 | | | 453 | 109 | if (force_sign) | 454 | 0 | { | 455 | 0 | ZYAN_ASSERT(value >= 0); | 456 | 0 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); | 457 | 0 | } | 458 | 109 | return ZydisStringAppendHexU(string, value, padding_length, force_leading_number, uppercase, | 459 | 109 | prefix, suffix); | 460 | 109 | } |
FormatterBase.c:ZydisStringAppendHexS Line | Count | Source | 438 | 510 | { | 439 | 510 | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); | 440 | 510 | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); | 441 | | | 442 | 510 | if (value < 0) | 443 | 388 | { | 444 | 388 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); | 445 | 378 | if (prefix) | 446 | 249 | { | 447 | 249 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); | 448 | 249 | } | 449 | 358 | return ZydisStringAppendHexU(string, ZyanAbsI64(value), padding_length, | 450 | 358 | force_leading_number, uppercase, (const ZyanStringView*)ZYAN_NULL, suffix); | 451 | 378 | } | 452 | | | 453 | 122 | if (force_sign) | 454 | 122 | { | 455 | 122 | ZYAN_ASSERT(value >= 0); | 456 | 122 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); | 457 | 122 | } | 458 | 118 | return ZydisStringAppendHexU(string, value, padding_length, force_leading_number, uppercase, | 459 | 118 | prefix, suffix); | 460 | 122 | } |
FormatterIntel.c:ZydisStringAppendHexS Line | Count | Source | 438 | 166 | { | 439 | 166 | static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+"); | 440 | 166 | static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-"); | 441 | | | 442 | 166 | if (value < 0) | 443 | 80 | { | 444 | 80 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub)); | 445 | 77 | if (prefix) | 446 | 54 | { | 447 | 54 | ZYAN_CHECK(ZydisStringAppend(string, prefix)); | 448 | 54 | } | 449 | 63 | return ZydisStringAppendHexU(string, ZyanAbsI64(value), padding_length, | 450 | 63 | force_leading_number, uppercase, (const ZyanStringView*)ZYAN_NULL, suffix); | 451 | 77 | } | 452 | | | 453 | 86 | if (force_sign) | 454 | 86 | { | 455 | 86 | ZYAN_ASSERT(value >= 0); | 456 | 86 | ZYAN_CHECK(ZydisStringAppendShort(string, &str_add)); | 457 | 86 | } | 458 | 85 | return ZydisStringAppendHexU(string, value, padding_length, force_leading_number, uppercase, | 459 | 85 | prefix, suffix); | 460 | 86 | } |
Unexecuted instantiation: String.c:ZydisStringAppendHexS |
461 | | |
462 | | /* ---------------------------------------------------------------------------------------------- */ |
463 | | |
464 | | /* ============================================================================================== */ |
465 | | |
466 | | #ifdef __cplusplus |
467 | | } |
468 | | #endif |
469 | | |
470 | | #endif // ZYDIS_INTERNAL_STRING_H |