Zydis  v3.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 <Zydis/ShortString.h>
47 #include <Zydis/Status.h>
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 
53 /* ============================================================================================== */
54 /* Enums and types */
55 /* ============================================================================================== */
56 
57 /* ---------------------------------------------------------------------------------------------- */
58 /* Letter Case */
59 /* ---------------------------------------------------------------------------------------------- */
60 
64 typedef enum ZydisLetterCase_
65 {
78 
88 
89 /* ---------------------------------------------------------------------------------------------- */
90 
91 /* ============================================================================================== */
92 /* Macros */
93 /* ============================================================================================== */
94 
95 /* ---------------------------------------------------------------------------------------------- */
96 /* Internal macros */
97 /* ---------------------------------------------------------------------------------------------- */
98 
102 #define ZYDIS_STRING_ASSERT_NULLTERMINATION(string) \
103  ZYAN_ASSERT(*(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) == '\0');
104 
108 #define ZYDIS_STRING_NULLTERMINATE(string) \
109  *(char*)((ZyanU8*)(string)->vector.data + (string)->vector.size - 1) = '\0';
110 
111 /* ---------------------------------------------------------------------------------------------- */
112 
113 /* ============================================================================================== */
114 /* Internal Functions */
115 /* ============================================================================================== */
116 
117 /* ---------------------------------------------------------------------------------------------- */
118 /* Appending */
119 /* ---------------------------------------------------------------------------------------------- */
120 
129 ZYAN_INLINE ZyanStatus ZydisStringAppend(ZyanString* destination, const ZyanStringView* source)
130 {
131  ZYAN_ASSERT(destination && source);
132  ZYAN_ASSERT(!destination->vector.allocator);
133  ZYAN_ASSERT(destination->vector.size && source->string.vector.size);
134 
135  if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity)
136  {
137  return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
138  }
139 
140  ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1,
141  source->string.vector.data, source->string.vector.size - 1);
142 
143  destination->vector.size += source->string.vector.size - 1;
144  ZYDIS_STRING_NULLTERMINATE(destination);
145 
146  return ZYAN_STATUS_SUCCESS;
147 }
148 
159 ZYAN_INLINE ZyanStatus ZydisStringAppendCase(ZyanString* destination, const ZyanStringView* source,
160  ZydisLetterCase letter_case)
161 {
162  ZYAN_ASSERT(destination && source);
163  ZYAN_ASSERT(!destination->vector.allocator);
164  ZYAN_ASSERT(destination->vector.size && source->string.vector.size);
165 
166  if (destination->vector.size + source->string.vector.size - 1 > destination->vector.capacity)
167  {
168  return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
169  }
170 
171  ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1,
172  source->string.vector.data, source->string.vector.size - 1);
173 
174  switch (letter_case)
175  {
177  break;
179  {
180  const ZyanUSize index = destination->vector.size - 1;
181  const ZyanUSize count = source->string.vector.size - 1;
182  char* s = (char*)destination->vector.data + index;
183  for (ZyanUSize i = index; i < index + count; ++i)
184  {
185  const char c = *s;
186  if ((c >= 'A') && (c <= 'Z'))
187  {
188  *s = c | 32;
189  }
190  ++s;
191  }
192  break;
193  }
195  {
196  const ZyanUSize index = destination->vector.size - 1;
197  const ZyanUSize count = source->string.vector.size - 1;
198  char* s = (char*)destination->vector.data + index;
199  for (ZyanUSize i = index; i < index + count; ++i)
200  {
201  const char c = *s;
202  if ((c >= 'a') && (c <= 'z'))
203  {
204  *s = c & ~32;
205  }
206  ++s;
207  }
208  break;
209  }
210  default:
211  ZYAN_UNREACHABLE;
212  }
213 
214  destination->vector.size += source->string.vector.size - 1;
215  ZYDIS_STRING_NULLTERMINATE(destination);
216 
217  return ZYAN_STATUS_SUCCESS;
218 }
219 
228 ZYAN_INLINE ZyanStatus ZydisStringAppendShort(ZyanString* destination,
229  const ZydisShortString* source)
230 {
231  ZYAN_ASSERT(destination && source);
232  ZYAN_ASSERT(!destination->vector.allocator);
233  ZYAN_ASSERT(destination->vector.size && source->size);
234 
235  if (destination->vector.size + source->size > destination->vector.capacity)
236  {
237  return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
238  }
239 
240  ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data,
241  (ZyanUSize)source->size + 1);
242 
243  destination->vector.size += source->size;
245 
246  return ZYAN_STATUS_SUCCESS;
247 }
248 
259 ZYAN_INLINE ZyanStatus ZydisStringAppendShortCase(ZyanString* destination,
260  const ZydisShortString* source, ZydisLetterCase letter_case)
261 {
262  ZYAN_ASSERT(destination && source);
263  ZYAN_ASSERT(!destination->vector.allocator);
264  ZYAN_ASSERT(destination->vector.size && source->size);
265 
266  if (destination->vector.size + source->size > destination->vector.capacity)
267  {
268  return ZYAN_STATUS_INSUFFICIENT_BUFFER_SIZE;
269  }
270 
271  ZYAN_MEMCPY((char*)destination->vector.data + destination->vector.size - 1, source->data,
272  (ZyanUSize)source->size + 1);
273 
274  switch (letter_case)
275  {
277  break;
279  {
280  const ZyanUSize index = destination->vector.size - 1;
281  const ZyanUSize count = source->size;
282  char* s = (char*)destination->vector.data + index;
283  for (ZyanUSize i = index; i < index + count; ++i)
284  {
285  const char c = *s;
286  if ((c >= 'A') && (c <= 'Z'))
287  {
288  *s = c | 32;
289  }
290  ++s;
291  }
292  break;
293  }
295  {
296  const ZyanUSize index = destination->vector.size - 1;
297  const ZyanUSize count = source->size;
298  char* s = (char*)destination->vector.data + index;
299  for (ZyanUSize i = index; i < index + count; ++i)
300  {
301  const char c = *s;
302  if ((c >= 'a') && (c <= 'z'))
303  {
304  *s = c & ~32;
305  }
306  ++s;
307  }
308  break;
309  }
310  default:
311  ZYAN_UNREACHABLE;
312  }
313 
314  destination->vector.size += source->size;
316 
317  return ZYAN_STATUS_SUCCESS;
318 }
319 
320 /* ---------------------------------------------------------------------------------------------- */
321 /* Formatting */
322 /* ---------------------------------------------------------------------------------------------- */
323 
340 ZyanStatus ZydisStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
341  const ZyanStringView* prefix, const ZyanStringView* suffix);
342 
360 ZYAN_INLINE ZyanStatus ZydisStringAppendDecS(ZyanString* string, ZyanI64 value,
361  ZyanU8 padding_length, ZyanBool force_sign, const ZyanStringView* prefix,
362  const ZyanStringView* suffix)
363 {
364  static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+");
365  static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-");
366 
367  if (value < 0)
368  {
369  ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub));
370  if (prefix)
371  {
372  ZYAN_CHECK(ZydisStringAppend(string, prefix));
373  }
374  return ZydisStringAppendDecU(string, -value, padding_length,
375  (const ZyanStringView*)ZYAN_NULL, suffix);
376  }
377 
378  if (force_sign)
379  {
380  ZYAN_ASSERT(value >= 0);
381  ZYAN_CHECK(ZydisStringAppendShort(string, &str_add));
382  }
383  return ZydisStringAppendDecU(string, value, padding_length, prefix, suffix);
384 }
385 
404 ZyanStatus ZydisStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
405  ZyanBool uppercase, const ZyanStringView* prefix, const ZyanStringView* suffix);
406 
429 ZYAN_INLINE ZyanStatus ZydisStringAppendHexS(ZyanString* string, ZyanI64 value,
430  ZyanU8 padding_length, ZyanBool uppercase, ZyanBool force_sign, const ZyanStringView* prefix,
431  const ZyanStringView* suffix)
432 {
433  static const ZydisShortString str_add = ZYDIS_MAKE_SHORTSTRING("+");
434  static const ZydisShortString str_sub = ZYDIS_MAKE_SHORTSTRING("-");
435 
436  if (value < 0)
437  {
438  ZYAN_CHECK(ZydisStringAppendShort(string, &str_sub));
439  if (prefix)
440  {
441  ZYAN_CHECK(ZydisStringAppend(string, prefix));
442  }
443  return ZydisStringAppendHexU(string, -value, padding_length, uppercase,
444  (const ZyanStringView*)ZYAN_NULL, suffix);
445  }
446 
447  if (force_sign)
448  {
449  ZYAN_ASSERT(value >= 0);
450  ZYAN_CHECK(ZydisStringAppendShort(string, &str_add));
451  }
452  return ZydisStringAppendHexU(string, value, padding_length, uppercase, prefix, suffix);
453 }
454 
455 /* ---------------------------------------------------------------------------------------------- */
456 
457 /* ============================================================================================== */
458 
459 #ifdef __cplusplus
460 }
461 #endif
462 
463 #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:65
@ ZYDIS_LETTER_CASE_UPPER
Converts the given text to uppercase letters.
Definition: String.h:77
@ ZYDIS_LETTER_CASE_REQUIRED_BITS
The minimum number of bits required to represent all values of this enum.
Definition: String.h:86
@ ZYDIS_LETTER_CASE_MAX_VALUE
Maximum value of this enum.
Definition: String.h:82
@ ZYDIS_LETTER_CASE_DEFAULT
Uses the given text "as is".
Definition: String.h:69
@ ZYDIS_LETTER_CASE_LOWER
Converts the given text to lowercase letters.
Definition: String.h:73
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:360
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:159
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:259
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:228
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:429
#define ZYDIS_STRING_NULLTERMINATE(string)
Writes a terminating '\0' character at the end of the string data.
Definition: String.h:108
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:129
#define ZYDIS_STRING_ASSERT_NULLTERMINATION(string)
Checks for a terminating '\0' character at the end of the string data.
Definition: String.h:102
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