Zydis 3.2.1.0
String.h
Go to the documentation of this file.
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
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 <Zydis/Status.h>
49
50#ifdef __cplusplus
51extern "C" {
52#endif
53
54/* ============================================================================================== */
55/* Enums and types */
56/* ============================================================================================== */
57
58/* ---------------------------------------------------------------------------------------------- */
59/* Letter Case */
60/* ---------------------------------------------------------------------------------------------- */
61
65typedef enum ZydisLetterCase_
66{
79
89
90/* ---------------------------------------------------------------------------------------------- */
91
92/* ============================================================================================== */
93/* Macros */
94/* ============================================================================================== */
95
96/* ---------------------------------------------------------------------------------------------- */
97/* Internal macros */
98/* ---------------------------------------------------------------------------------------------- */
99
103#define ZYDIS_STRING_ASSERT_NULLTERMINATION(string) \
104 ZYAN_ASSERT(*(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) == '\0');
105
109#define ZYDIS_STRING_NULLTERMINATE(string) \
110 *(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) = '\0';
111
112/* ---------------------------------------------------------------------------------------------- */
113
114/* ============================================================================================== */
115/* Internal Functions */
116/* ============================================================================================== */
117
118/* ---------------------------------------------------------------------------------------------- */
119/* Appending */
120/* ---------------------------------------------------------------------------------------------- */
121
130ZYAN_INLINE ZyanStatus ZydisStringAppend(ZyanString* destination, const ZyanStringView* source)
131{
132 ZYAN_ASSERT(destination && source);
133 ZYAN_ASSERT(!destination->vector.allocator);
134 ZYAN_ASSERT(destination->vector.size && source->string.vector.size);
135
136 if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity)
137 {
138 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
139 }
140
141 ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1,
142 source->string.vector.data, source->string.vector.size - 1);
143
144 destination->vector.size += source->string.vector.size - 1;
145 ZYDIS_STRING_NULLTERMINATE(destination);
146
147 return ZYAN_STATUS_SUCCESS;
148}
149
160ZYAN_INLINE ZyanStatus ZydisStringAppendCase(ZyanString* destination, const ZyanStringView* source,
161 ZydisLetterCase letter_case)
162{
163 ZYAN_ASSERT(destination && source);
164 ZYAN_ASSERT(!destination->vector.allocator);
165 ZYAN_ASSERT(destination->vector.size && source->string.vector.size);
166
167 if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity)
168 {
169 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
170 }
171
172 ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1,
173 source->string.vector.data, source->string.vector.size - 1);
174
175 switch (letter_case)
176 {
178 break;
180 {
181 const ZyanUSize index = destination->vector.size - 1;
182 const ZyanUSize count = source->string.vector.size - 1;
183 char* s = (char*)destination->vector.data + index;
184 for (ZyanUSize i = index; i < index + count; ++i)
185 {
186 const char c = *s;
187 if ((c >= 'A') && (c <= 'Z'))
188 {
189 *s = c | 32;
190 }
191 ++s;
192 }
193 break;
194 }
196 {
197 const ZyanUSize index = destination->vector.size - 1;
198 const ZyanUSize count = source->string.vector.size - 1;
199 char* s = (char*)destination->vector.data + index;
200 for (ZyanUSize i = index; i < index + count; ++i)
201 {
202 const char c = *s;
203 if ((c >= 'a') && (c <= 'z'))
204 {
205 *s = c & ~32;
206 }
207 ++s;
208 }
209 break;
210 }
211 default:
212 ZYAN_UNREACHABLE;
213 }
214
215 destination->vector.size += source->string.vector.size - 1;
216 ZYDIS_STRING_NULLTERMINATE(destination);
217
218 return ZYAN_STATUS_SUCCESS;
219}
220
229ZYAN_INLINE ZyanStatus ZydisStringAppendShort(ZyanString* destination,
230 const ZydisShortString* source)
231{
232 ZYAN_ASSERT(destination && source);
233 ZYAN_ASSERT(!destination->vector.allocator);
234 ZYAN_ASSERT(destination->vector.size && source->size);
235
236 if (destination->vector.size + source->size > destination->vector.capacity)
237 {
238 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
239 }
240
241 ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data,
242 (ZyanUSize)source->size + 1);
243
244 destination->vector.size += source->size;
246
247 return ZYAN_STATUS_SUCCESS;
248}
249
260ZYAN_INLINE ZyanStatus ZydisStringAppendShortCase(ZyanString* destination,
261 const ZydisShortString* source, ZydisLetterCase letter_case)
262{
263 ZYAN_ASSERT(destination && source);
264 ZYAN_ASSERT(!destination->vector.allocator);
265 ZYAN_ASSERT(destination->vector.size && source->size);
266
267 if (destination->vector.size + source->size > destination->vector.capacity)
268 {
269 return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
270 }
271
272 ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data,
273 (ZyanUSize)source->size + 1);
274
275 switch (letter_case)
276 {
278 break;
280 {
281 const ZyanUSize index = destination->vector.size - 1;
282 const ZyanUSize count = source->size;
283 char* s = (char*)destination->vector.data + index;
284 for (ZyanUSize i = index; i < index + count; ++i)
285 {
286 const char c = *s;
287 if ((c >= 'A') && (c <= 'Z'))
288 {
289 *s = c | 32;
290 }
291 ++s;
292 }
293 break;
294 }
296 {
297 const ZyanUSize index = destination->vector.size - 1;
298 const ZyanUSize count = source->size;
299 char* s = (char*)destination->vector.data + index;
300 for (ZyanUSize i = index; i < index + count; ++i)
301 {
302 const char c = *s;
303 if ((c >= 'a') && (c <= 'z'))
304 {
305 *s = c & ~32;
306 }
307 ++s;
308 }
309 break;
310 }
311 default:
312 ZYAN_UNREACHABLE;
313 }
314
315 destination->vector.size += source->size;
317
318 return ZYAN_STATUS_SUCCESS;
319}
320
321/* ---------------------------------------------------------------------------------------------- */
322/* Formatting */
323/* ---------------------------------------------------------------------------------------------- */
324
341ZyanStatus ZydisStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
342 const ZyanStringView* prefix, const ZyanStringView* suffix);
343
361ZYAN_INLINE ZyanStatus ZydisStringAppendDecS(ZyanString* string, ZyanI64 value,
362 ZyanU8 padding_length, ZyanBool force_sign, const ZyanStringView* prefix,
363 const ZyanStringView* suffix)
364{
365 static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+");
366 static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-");
367
368 if (value < 0)
369 {
370 ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub));
371 if (prefix)
372 {
373 ZYAN_CHECK(ZydisStringAppend(string, prefix));
374 }
375 return ZydisStringAppendDecU(string, ZyanAbsI64(value), padding_length,
376 (const ZyanStringView*)ZYAN_NULL, suffix);
377 }
378
379 if (force_sign)
380 {
381 ZYAN_ASSERT(value >= 0);
382 ZYAN_CHECK(ZydisStringAppendShort(string, &str_add));
383 }
384 return ZydisStringAppendDecU(string, value, padding_length, prefix, suffix);
385}
386
405ZyanStatus ZydisStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
406 ZyanBool uppercase, const ZyanStringView* prefix, const ZyanStringView* suffix);
407
430ZYAN_INLINE ZyanStatus ZydisStringAppendHexS(ZyanString* string, ZyanI64 value,
431 ZyanU8 padding_length, ZyanBool uppercase, ZyanBool force_sign, const ZyanStringView* prefix,
432 const ZyanStringView* suffix)
433{
434 static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+");
435 static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-");
436
437 if (value < 0)
438 {
439 ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub));
440 if (prefix)
441 {
442 ZYAN_CHECK(ZydisStringAppend(string, prefix));
443 }
444 return ZydisStringAppendHexU(string, ZyanAbsI64(value), padding_length, uppercase,
445 (const ZyanStringView*)ZYAN_NULL, suffix);
446 }
447
448 if (force_sign)
449 {
450 ZYAN_ASSERT(value >= 0);
451 ZYAN_CHECK(ZydisStringAppendShort(string, &str_add));
452 }
453 return ZydisStringAppendHexU(string, value, padding_length, uppercase, prefix, suffix);
454}
455
456/* ---------------------------------------------------------------------------------------------- */
457
458/* ============================================================================================== */
459
460#ifdef __cplusplus
461}
462#endif
463
464#endif // ZYDIS_INTERNAL_STRING_H
Defines the immutable and storage-efficient ZydisShortString struct, which is used to store strings i...
#define ZYDIS_MAKE_SHORTSTRING(string)
Declares a ZydisShortString from a static C-style string.
Definition: ShortString.h:81
Status code definitions and check macros.
ZyanStatus ZydisStringAppendHexU(ZyanString *string, ZyanU64 value, ZyanU8 padding_length, ZyanBool uppercase, const ZyanStringView *prefix, const ZyanStringView *suffix)
Formats the given unsigned ordinal value to its hexadecimal text-representation and appends it to the...
ZydisLetterCase_
Defines the ZydisLetterCase enum.
Definition: String.h:66
@ ZYDIS_LETTER_CASE_UPPER
Converts the given text to uppercase letters.
Definition: String.h:78
@ ZYDIS_LETTER_CASE_REQUIRED_BITS
The minimum number of bits required to represent all values of this enum.
Definition: String.h:87
@ ZYDIS_LETTER_CASE_MAX_VALUE
Maximum value of this enum.
Definition: String.h:83
@ ZYDIS_LETTER_CASE_DEFAULT
Uses the given text "as is".
Definition: String.h:70
@ ZYDIS_LETTER_CASE_LOWER
Converts the given text to lowercase letters.
Definition: String.h:74
ZYAN_INLINE ZyanStatus ZydisStringAppendDecS(ZyanString *string, ZyanI64 value, ZyanU8 padding_length, ZyanBool force_sign, const ZyanStringView *prefix, const ZyanStringView *suffix)
Formats the given signed ordinal value to its decimal text-representation and appends it to the strin...
Definition: String.h:361
ZYAN_INLINE ZyanStatus ZydisStringAppendCase(ZyanString *destination, const ZyanStringView *source, ZydisLetterCase letter_case)
Appends the content of the source string to the end of the destination string, converting the charact...
Definition: String.h:160
ZYAN_INLINE ZyanStatus ZydisStringAppendShortCase(ZyanString *destination, const ZydisShortString *source, ZydisLetterCase letter_case)
Appends the content of the source short-string to the end of the destination string,...
Definition: String.h:260
enum ZydisLetterCase_ ZydisLetterCase
Defines the ZydisLetterCase enum.
ZyanStatus ZydisStringAppendDecU(ZyanString *string, ZyanU64 value, ZyanU8 padding_length, const ZyanStringView *prefix, const ZyanStringView *suffix)
Formats the given unsigned ordinal value to its decimal text-representation and appends it to the str...
ZYAN_INLINE ZyanStatus ZydisStringAppendShort(ZyanString *destination, const ZydisShortString *source)
Appends the content of the source short-string to the end of the destination string.
Definition: String.h:229
ZYAN_INLINE ZyanStatus ZydisStringAppendHexS(ZyanString *string, ZyanI64 value, ZyanU8 padding_length, ZyanBool uppercase, ZyanBool force_sign, const ZyanStringView *prefix, const ZyanStringView *suffix)
Formats the given signed ordinal value to its hexadecimal text-representation and appends it to the s...
Definition: String.h:430
#define ZYDIS_STRING_NULLTERMINATE(string)
Writes a terminating '\0' character at the end of the string data.
Definition: String.h:109
ZYAN_INLINE ZyanStatus ZydisStringAppend(ZyanString *destination, const ZyanStringView *source)
Appends the content of the source string to the end of the destination string.
Definition: String.h:130
#define ZYDIS_STRING_ASSERT_NULLTERMINATION(string)
Checks for a terminating '\0' character at the end of the string data.
Definition: String.h:103
Defines the ZydisShortString struct.
Definition: ShortString.h:59
ZyanU8 size
The length (number of characters) of the string (without 0-termination).
Definition: ShortString.h:67
const char * data
The buffer that contains the actual (null-terminated) string.
Definition: ShortString.h:63