Zydis  v3.2.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
51 extern "C" {
52 #endif
53 
54 /* ============================================================================================== */
55 /* Enums and types */
56 /* ============================================================================================== */
57 
58 /* ---------------------------------------------------------------------------------------------- */
59 /* Letter Case */
60 /* ---------------------------------------------------------------------------------------------- */
61 
65 typedef 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 
130 ZYAN_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 
160 ZYAN_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 
229 ZYAN_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 
260 ZYAN_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 
341 ZyanStatus ZydisStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
342  const ZyanStringView* prefix, const ZyanStringView* suffix);
343 
361 ZYAN_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 
405 ZyanStatus ZydisStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
406  ZyanBool uppercase, const ZyanStringView* prefix, const ZyanStringView* suffix);
407 
430 ZYAN_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