"libraries/vscode:/vscode.git/clone" did not exist on "0fba96e76efc1164777f47492de4ab33c42c53e8"
string.h 11.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
// [AsmJit]
// Complete x86/x64 JIT and Remote Assembler for C++.
//
// [License]
// Zlib - See LICENSE.md file in the package.

// [Guard]
#ifndef _ASMJIT_BASE_STRING_H
#define _ASMJIT_BASE_STRING_H

// [Dependencies - AsmJit]
#include "../base/globals.h"

// [Dependencies - C]
#include <stdarg.h>

// [Api-Begin]
#include "../apibegin.h"

namespace asmjit {

//! \addtogroup asmjit_base_util
//! \{

// ============================================================================
// [asmjit::kStringOp]
// ============================================================================

//! \internal
//!
//! String operation.
ASMJIT_ENUM(kStringOp) {
  //! Replace the current string by a given content.
  kStringOpSet = 0,
  //! Append a given content to the current string.
  kStringOpAppend = 1
};

// ============================================================================
// [asmjit::kStringFormat]
// ============================================================================

//! \internal
//!
//! String format flags.
ASMJIT_ENUM(kStringFormat) {
  kStringFormatShowSign  = 0x00000001,
  kStringFormatShowSpace = 0x00000002,
  kStringFormatAlternate = 0x00000004,
  kStringFormatSigned    = 0x80000000
};

// ============================================================================
// [asmjit::StringUtil]
// ============================================================================

//! String utilities.
struct StringUtil {
  static ASMJIT_INLINE size_t nlen(const char* s, size_t maxlen) {
    size_t i;
    for (i = 0; i < maxlen; i++)
      if (!s[i])
        break;
    return i;
  }
};

// ============================================================================
// [asmjit::StringBuilder]
// ============================================================================

//! String builder.
//!
//! String builder was designed to be able to build a string using append like
//! operation to append numbers, other strings, or signle characters. It can
//! allocate it's own buffer or use a buffer created on the stack.
//!
//! String builder contains method specific to AsmJit functionality, used for
//! logging or HTML output.
struct StringBuilder {
  ASMJIT_NO_COPY(StringBuilder)

  // --------------------------------------------------------------------------
  // [Construction / Destruction]
  // --------------------------------------------------------------------------

  ASMJIT_API StringBuilder();
  ASMJIT_API ~StringBuilder();

  ASMJIT_INLINE StringBuilder(const _NoInit&) {}

  // --------------------------------------------------------------------------
  // [Accessors]
  // --------------------------------------------------------------------------

  //! Get string builder capacity.
  ASMJIT_INLINE size_t getCapacity() const { return _capacity; }
  //! Get length.
  ASMJIT_INLINE size_t getLength() const { return _length; }

  //! Get null-terminated string data.
  ASMJIT_INLINE char* getData() { return _data; }
  //! Get null-terminated string data (const).
  ASMJIT_INLINE const char* getData() const { return _data; }

  // --------------------------------------------------------------------------
  // [Prepare / Reserve]
  // --------------------------------------------------------------------------

  //! Prepare to set/append.
  ASMJIT_API char* prepare(uint32_t op, size_t len);

  //! Reserve `to` bytes in string builder.
  ASMJIT_API bool reserve(size_t to);

  // --------------------------------------------------------------------------
  // [Clear]
  // --------------------------------------------------------------------------

  //! Clear the content in String builder.
  ASMJIT_API void clear();

  // --------------------------------------------------------------------------
  // [Op]
  // --------------------------------------------------------------------------

  ASMJIT_API bool _opString(uint32_t op, const char* str, size_t len = kInvalidIndex);
  ASMJIT_API bool _opVFormat(uint32_t op, const char* fmt, va_list ap);
  ASMJIT_API bool _opChar(uint32_t op, char c);
  ASMJIT_API bool _opChars(uint32_t op, char c, size_t len);
  ASMJIT_API bool _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0);
  ASMJIT_API bool _opHex(uint32_t op, const void* data, size_t len);

  // --------------------------------------------------------------------------
  // [Set]
  // --------------------------------------------------------------------------

  //! Replace the current content by `str` of `len`.
  ASMJIT_INLINE bool setString(const char* str, size_t len = kInvalidIndex) {
    return _opString(kStringOpSet, str, len);
  }

  //! Replace the current content by formatted string `fmt`.
  ASMJIT_INLINE bool setVFormat(const char* fmt, va_list ap) {
    return _opVFormat(kStringOpSet, fmt, ap);
  }

  //! Replace the current content by formatted string `fmt`.
  ASMJIT_API bool setFormat(const char* fmt, ...);

  //! Replace the current content by `c` character.
  ASMJIT_INLINE bool setChar(char c) {
    return _opChar(kStringOpSet, c);
  }

  //! Replace the current content by `c` of `len`.
  ASMJIT_INLINE bool setChars(char c, size_t len) {
    return _opChars(kStringOpSet, c, len);
  }

  //! Replace the current content by formatted integer `i`.
  ASMJIT_INLINE bool setInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
    return _opNumber(kStringOpSet, i, base, width, flags | kStringFormatSigned);
  }

  //! Replace the current content by formatted integer `i`.
  ASMJIT_INLINE bool setUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
    return _opNumber(kStringOpSet, i, base, width, flags);
  }

  //! Replace the current content by the given `data` converted to a HEX string.
  ASMJIT_INLINE bool setHex(const void* data, size_t len) {
    return _opHex(kStringOpSet, data, len);
  }

  // --------------------------------------------------------------------------
  // [Append]
  // --------------------------------------------------------------------------

  //! Append `str` of `len`.
  ASMJIT_INLINE bool appendString(const char* str, size_t len = kInvalidIndex) {
    return _opString(kStringOpAppend, str, len);
  }

  //! Append a formatted string `fmt` to the current content.
  ASMJIT_INLINE bool appendVFormat(const char* fmt, va_list ap) {
    return _opVFormat(kStringOpAppend, fmt, ap);
  }

  //! Append a formatted string `fmt` to the current content.
  ASMJIT_API bool appendFormat(const char* fmt, ...);

  //! Append `c` character.
  ASMJIT_INLINE bool appendChar(char c) {
    return _opChar(kStringOpAppend, c);
  }

  //! Append `c` of `len`.
  ASMJIT_INLINE bool appendChars(char c, size_t len) {
    return _opChars(kStringOpAppend, c, len);
  }

  //! Append `i`.
  ASMJIT_INLINE bool appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
    return _opNumber(kStringOpAppend, static_cast<uint64_t>(i), base, width, flags | kStringFormatSigned);
  }

  //! Append `i`.
  ASMJIT_INLINE bool appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) {
    return _opNumber(kStringOpAppend, i, base, width, flags);
  }

  //! Append the given `data` converted to a HEX string.
  ASMJIT_INLINE bool appendHex(const void* data, size_t len) {
    return _opHex(kStringOpAppend, data, len);
  }

  // --------------------------------------------------------------------------
  // [_Append]
  // --------------------------------------------------------------------------

  //! Append `str` of `len`, inlined, without buffer overflow check.
  ASMJIT_INLINE void _appendString(const char* str, size_t len = kInvalidIndex) {
    // len should be a constant if we are inlining.
    if (len == kInvalidIndex) {
      char* p = &_data[_length];

      while (*str) {
        ASMJIT_ASSERT(p < _data + _capacity);
        *p++ = *str++;
      }

      *p = '\0';
      _length = (size_t)(p - _data);
    }
    else {
      ASMJIT_ASSERT(_capacity - _length >= len);

      char* p = &_data[_length];
      char* pEnd = p + len;

      while (p < pEnd)
        *p++ = *str++;

      *p = '\0';
      _length += len;
    }
  }

  //! Append `c` character, inlined, without buffer overflow check.
  ASMJIT_INLINE void _appendChar(char c) {
    ASMJIT_ASSERT(_capacity - _length >= 1);

    _data[_length] = c;
    _length++;
    _data[_length] = '\0';
  }

  //! Append `c` of `len`, inlined, without buffer overflow check.
  ASMJIT_INLINE void _appendChars(char c, size_t len) {
    ASMJIT_ASSERT(_capacity - _length >= len);

    char* p = &_data[_length];
    char* pEnd = p + len;

    while (p < pEnd)
      *p++ = c;

    *p = '\0';
    _length += len;
  }

  ASMJIT_INLINE void _appendUInt32(uint32_t i) {
    char buf_[32];

    char* pEnd = buf_ + ASMJIT_ARRAY_SIZE(buf_);
    char* pBuf = pEnd;

    do {
      uint32_t d = i / 10;
      uint32_t r = i % 10;

      *--pBuf = static_cast<uint8_t>(r + '0');
      i = d;
    } while (i);

    ASMJIT_ASSERT(_capacity - _length >= (size_t)(pEnd - pBuf));
    char* p = &_data[_length];

    do {
      *p++ = *pBuf;
    } while (++pBuf != pEnd);

    *p = '\0';
    _length = (size_t)(p - _data);
  }

  // --------------------------------------------------------------------------
  // [Eq]
  // --------------------------------------------------------------------------

  //! Check for equality with other `str` of `len`.
  ASMJIT_API bool eq(const char* str, size_t len = kInvalidIndex) const;
  //! Check for equality with `other`.
  ASMJIT_INLINE bool eq(const StringBuilder& other) const {
    return eq(other._data);
  }

  // --------------------------------------------------------------------------
  // [Operator Overload]
  // --------------------------------------------------------------------------

  ASMJIT_INLINE bool operator==(const StringBuilder& other) const { return  eq(other); }
  ASMJIT_INLINE bool operator!=(const StringBuilder& other) const { return !eq(other); }

  ASMJIT_INLINE bool operator==(const char* str) const { return  eq(str); }
  ASMJIT_INLINE bool operator!=(const char* str) const { return !eq(str); }

  // --------------------------------------------------------------------------
  // [Members]
  // --------------------------------------------------------------------------

  //! String data.
  char* _data;
  //! Length.
  size_t _length;
  //! Capacity.
  size_t _capacity;
  //! Whether the string can be freed.
  size_t _canFree;
};

// ============================================================================
// [asmjit::StringBuilderT]
// ============================================================================

//! \internal
template<size_t N>
struct StringBuilderT : public StringBuilder {
  ASMJIT_NO_COPY(StringBuilderT<N>)

  // --------------------------------------------------------------------------
  // [Construction / Destruction]
  // --------------------------------------------------------------------------

  ASMJIT_INLINE StringBuilderT() : StringBuilder(NoInit) {
    _data = _embeddedData;
    _data[0] = 0;

    _length = 0;
    _capacity = N;
    _canFree = false;
  }

  // --------------------------------------------------------------------------
  // [Members]
  // --------------------------------------------------------------------------

  //! Embedded data.
  char _embeddedData[static_cast<size_t>(
    N + 1 + sizeof(intptr_t)) & ~static_cast<size_t>(sizeof(intptr_t) - 1)];
};

//! \}

} // asmjit namespace

// [Api-End]
#include "../apiend.h"

// [Guard]
#endif // _ASMJIT_BASE_STRING_H