yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Yong HeAdd Slang Byte Code generation and interpreter. (#6896)c39c29bf4

master
10.0 KiB264 linesraw
1#ifndef SLANG_CORE_STRING_UTIL_H
2#define SLANG_CORE_STRING_UTIL_H
3
4#include "slang-com-helper.h"
5#include "slang-com-ptr.h"
6#include "slang-list.h"
7#include "slang-string.h"
8
9#include <stdarg.h>
10
11namespace Slang
12{
13
14struct StringUtil
15{
16    typedef bool (*EqualFn)(const UnownedStringSlice& a, const UnownedStringSlice& b);
17
18    /// True if the splits of a and b (via splitChar) are all equal as compared with the equalFn
19    /// function
20    static bool areAllEqualWithSplit(
21        const UnownedStringSlice& a,
22        const UnownedStringSlice& b,
23        char splitChar,
24        EqualFn equalFn);
25
26    /// True if all slices in match are all equal as compared with the equalFn function
27    static bool areAllEqual(
28        const List<UnownedStringSlice>& a,
29        const List<UnownedStringSlice>& b,
30        EqualFn equalFn);
31
32    /// Split in, by specified splitChar into slices out
33    /// Slices contents will directly address into in, so contents will only stay valid as long as
34    /// in does.
35    static void split(
36        const UnownedStringSlice& in,
37        char splitChar,
38        List<UnownedStringSlice>& slicesOut);
39    /// Split in by the specified splitSlice
40    /// Slices contents will directly address into in, so contents will only stay valid as long as
41    /// in does.
42    static void split(
43        const UnownedStringSlice& in,
44        const UnownedStringSlice& splitSlice,
45        List<UnownedStringSlice>& slicesOut);
46
47    /// Splits in into outSlices, up to maxSlices. May not consume all of in (for example if it runs
48    /// out of space).
49    static Index split(
50        const UnownedStringSlice& in,
51        char splitChar,
52        Index maxSlices,
53        UnownedStringSlice* outSlices);
54    /// Splits into outSlices up to maxSlices. Returns SLANG_OK if of 'in' consumed.
55    static SlangResult split(
56        const UnownedStringSlice& in,
57        char splitChar,
58        Index maxSlices,
59        UnownedStringSlice* outSlices,
60        Index& outSlicesCount);
61    /// Splits on white space
62    static void splitOnWhitespace(
63        const UnownedStringSlice& in,
64        List<UnownedStringSlice>& slicesOut);
65
66    /// Split in, by specified splitChar append into slices out
67    /// Slices contents will directly address into in, so contents will only stay valid as long as
68    /// in does.
69    static void appendSplit(
70        const UnownedStringSlice& in,
71        char splitChar,
72        List<UnownedStringSlice>& slicesOut);
73    /// Split in by the specified splitSlice
74    /// Slices contents will directly address into in, so contents will only stay valid as long as
75    /// in does.
76    static void appendSplit(
77        const UnownedStringSlice& in,
78        const UnownedStringSlice& splitSlice,
79        List<UnownedStringSlice>& slicesOut);
80
81    /// appends splits on white space
82    static void appendSplitOnWhitespace(
83        const UnownedStringSlice& in,
84        List<UnownedStringSlice>& slicesOut);
85
86    /// Append the joining of in items, separated by 'separator' onto out
87    static void join(const List<String>& in, char separator, StringBuilder& out);
88    static void join(
89        const List<String>& in,
90        const UnownedStringSlice& separator,
91        StringBuilder& out);
92
93    static void join(
94        const UnownedStringSlice* values,
95        Index valueCount,
96        char separator,
97        StringBuilder& out);
98    static void join(
99        const UnownedStringSlice* values,
100        Index valueCount,
101        const UnownedStringSlice& separator,
102        StringBuilder& out);
103
104    /// Equivalent to doing a split and then finding the index of 'find' on the array
105    /// Returns -1 if not found
106    static Index indexOfInSplit(
107        const UnownedStringSlice& in,
108        char splitChar,
109        const UnownedStringSlice& find);
110
111    /// Given the entry at the split index specified.
112    /// Will return slice with begin() == nullptr if not found or input has begin() == nullptr)
113    static UnownedStringSlice getAtInSplit(
114        const UnownedStringSlice& in,
115        char splitChar,
116        Index index);
117
118    /// Returns the size in bytes needed to hold the formatted string using the specified args, NOT
119    /// including a terminating 0 NOTE! The caller *should* assume this will consume the va_list
120    /// (use va_copy to make a copy to be consumed)
121    static size_t calcFormattedSize(const char* format, va_list args);
122
123    /// Calculate the formatted string using the specified args.
124    /// NOTE! The caller *should* assume this will consume the va_list
125    /// The buffer should be at least calcFormattedSize + 1 bytes. The +1 is needed because a
126    /// terminating 0 is written.
127    static void calcFormatted(const char* format, va_list args, size_t numChars, char* dst);
128
129    /// Appends formatted string with args into buf
130    static void append(const char* format, va_list args, StringBuilder& buf);
131
132    /// Appends the formatted string with specified trailing args
133    static void appendFormat(StringBuilder& buf, const char* format, ...);
134
135    /// Create a string from the format string applying args (like sprintf)
136    static String makeStringWithFormat(const char* format, ...);
137
138    /// Create a string from the format string and arguments in a buffer.
139    static String makeStringWithFormatFromArgArray(
140        const char* format,
141        ArrayView<const void*> ptrToArgs);
142
143    /// Given a string held in a blob, returns as a String
144    /// Returns an empty string if blob is nullptr
145    static String getString(ISlangBlob* blob);
146    static UnownedStringSlice getSlice(ISlangBlob* blob);
147
148    /// Given a string or slice, replaces all instances of fromChar with toChar
149    static String calcCharReplaced(const UnownedStringSlice& slice, char fromChar, char toChar);
150    static String calcCharReplaced(const String& string, char fromChar, char toChar);
151
152    /// Replaces all occurrances of subStr with replacement.
153    static String replaceAll(
154        UnownedStringSlice text,
155        UnownedStringSlice subStr,
156        UnownedStringSlice replacement);
157
158    /// Create a blob from a string
159    static ComPtr<ISlangBlob> createStringBlob(const String& string);
160
161    /// Given input text outputs with standardized line endings. Ie \n\r -> \n
162    static void appendStandardLines(const UnownedStringSlice& text, StringBuilder& out);
163
164    /// Extracts a line and stores the remaining text in ioText, and the line in outLine. Returns
165    /// true if has a line.
166    ///
167    /// As well as indicating end of text with the return value, at the end of all the text a
168    /// 'special' null UnownedStringSlice with a null 'begin' pointer is also returned as the
169    /// outLine. ioText will be modified to contain the remaining text, starting at the beginning of
170    /// the next line. As an empty final line is still a line, the special null UnownedStringSlice
171    /// is the last value ioText after the last valid line is returned.
172    ///
173    /// NOTE! That behavior is as if line terminators (like \n) act as separators. Thus input of
174    /// "\n" will return *two* lines - an empty line before and then after the \n.
175    static bool extractLine(UnownedStringSlice& ioText, UnownedStringSlice& outLine);
176
177    /// Given text, splits into lines stored in outLines. NOTE! That lines is only valid as long as
178    /// textIn remains valid
179    static void calcLines(const UnownedStringSlice& textIn, List<UnownedStringSlice>& lines);
180
181    /// Given a line that may contain cr/lf, returns the the a slice that doesn't have trailing
182    /// cr/lf
183    static UnownedStringSlice trimEndOfLine(const UnownedStringSlice& slice);
184
185    /// Equal if the lines are equal (in effect a way to ignore differences in line breaks)
186    static bool areLinesEqual(const UnownedStringSlice& a, const UnownedStringSlice& b);
187
188    /// Convert in to int. Returns SLANG_FAIL on error
189    static SlangResult parseInt(const UnownedStringSlice& in, Int& outValue);
190
191    /// Convert ioText into double. Returns SLANG_OK on success.
192    static SlangResult parseDouble(const UnownedStringSlice& text, double& out);
193
194    /// Convert into int64_t. Returns SLANG_OK on success.
195    static SlangResult parseInt64(const UnownedStringSlice& text, int64_t& out);
196
197    /// Parse an integer from text starting at pos until the end or the first non-digit char.
198    /// Modifies pos to the position where parsing ends.
199    /// Returns parsed integer.
200    static int parseIntAndAdvancePos(UnownedStringSlice text, Index& pos);
201};
202
203/* A helper class that allows parsing of lines from text with iteration. Uses
204 * StringUtil::extractLine for the actual underlying implementation. */
205class LineParser
206{
207public:
208    struct Iterator
209    {
210        const UnownedStringSlice& operator*() const { return m_line; }
211        const UnownedStringSlice* operator->() const { return &m_line; }
212        Iterator& operator++()
213        {
214            StringUtil::extractLine(m_remaining, m_line);
215            return *this;
216        }
217        Iterator operator++(int)
218        {
219            Iterator rs = *this;
220            operator++();
221            return rs;
222        }
223
224        /// Equal if both are at the same m_line address exactly. Handles termination case correctly
225        /// where line.begin() == nullptr.
226        bool operator==(const Iterator& rhs) const { return m_line.begin() == rhs.m_line.begin(); }
227        bool operator!=(const Iterator& rhs) const { return !(*this == rhs); }
228
229        /// Ctor
230        Iterator(const UnownedStringSlice& line, const UnownedStringSlice& remaining)
231            : m_line(line), m_remaining(remaining)
232        {
233        }
234
235    protected:
236        UnownedStringSlice m_line;
237        UnownedStringSlice m_remaining;
238    };
239
240    Iterator begin() const
241    {
242        UnownedStringSlice remaining(m_text), line;
243        StringUtil::extractLine(remaining, line);
244        return Iterator(line, remaining);
245    }
246    Iterator end() const
247    {
248        UnownedStringSlice term(nullptr, nullptr);
249        return Iterator(term, term);
250    }
251
252    /// Ctor
253    LineParser(const UnownedStringSlice& text)
254        : m_text(text)
255    {
256    }
257
258protected:
259    UnownedStringSlice m_text;
260};
261
262} // namespace Slang
263
264#endif // SLANG_STRING_UTIL_H