Coverage Report

Created: 2025-10-28 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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