yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
c39c29bf4
master
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{ 16typedef 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 20static bool areAllEqualWithSplit ( 21const UnownedStringSlice & a , 22const UnownedStringSlice & b , 23char splitChar , 24EqualFn equalFn ); 25 26/// True if all slices in match are all equal as compared with the equalFn function 27static bool areAllEqual ( 28const List < UnownedStringSlice >& a , 29const List < UnownedStringSlice >& b , 30EqualFn 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. 35static void split ( 36const UnownedStringSlice & in , 37char splitChar , 38List < 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. 42static void split ( 43const UnownedStringSlice & in , 44const UnownedStringSlice & splitSlice , 45List < 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). 49static Index split ( 50const UnownedStringSlice & in , 51char splitChar , 52Index maxSlices , 53UnownedStringSlice * outSlices ); 54/// Splits into outSlices up to maxSlices. Returns SLANG_OK if of 'in' consumed. 55static SlangResult split ( 56const UnownedStringSlice & in , 57char splitChar , 58Index maxSlices , 59UnownedStringSlice * outSlices , 60Index & outSlicesCount ); 61/// Splits on white space 62static void splitOnWhitespace ( 63const UnownedStringSlice & in , 64List < 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. 69static void appendSplit ( 70const UnownedStringSlice & in , 71char splitChar , 72List < 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. 76static void appendSplit ( 77const UnownedStringSlice & in , 78const UnownedStringSlice & splitSlice , 79List < UnownedStringSlice >& slicesOut ); 80 81/// appends splits on white space 82static void appendSplitOnWhitespace ( 83const UnownedStringSlice & in , 84List < UnownedStringSlice >& slicesOut ); 85 86/// Append the joining of in items, separated by 'separator' onto out 87static void join (const List < String >& in ,char separator ,StringBuilder & out ); 88static void join ( 89const List < String >& in , 90const UnownedStringSlice & separator , 91StringBuilder & out ); 92 93static void join ( 94const UnownedStringSlice * values , 95Index valueCount , 96char separator , 97StringBuilder & out ); 98static void join ( 99const UnownedStringSlice * values , 100Index valueCount , 101const UnownedStringSlice & separator , 102StringBuilder & out ); 103 104/// Equivalent to doing a split and then finding the index of 'find' on the array 105/// Returns -1 if not found 106static Index indexOfInSplit ( 107const UnownedStringSlice & in , 108char splitChar , 109const 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) 113static UnownedStringSlice getAtInSplit ( 114const UnownedStringSlice & in , 115char splitChar , 116Index 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) 121static 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. 127static void calcFormatted (const char * format ,va_list args ,size_t numChars ,char * dst ); 128 129/// Appends formatted string with args into buf 130static void append (const char * format ,va_list args ,StringBuilder & buf ); 131 132/// Appends the formatted string with specified trailing args 133static void appendFormat (StringBuilder & buf ,const char * format , ...); 134 135/// Create a string from the format string applying args (like sprintf) 136static String makeStringWithFormat (const char * format , ...); 137 138/// Create a string from the format string and arguments in a buffer. 139static String makeStringWithFormatFromArgArray ( 140const char * format , 141ArrayView < 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 145static String getString (ISlangBlob * blob ); 146static UnownedStringSlice getSlice (ISlangBlob * blob ); 147 148/// Given a string or slice, replaces all instances of fromChar with toChar 149static String calcCharReplaced (const UnownedStringSlice & slice ,char fromChar ,char toChar ); 150static String calcCharReplaced (const String & string ,char fromChar ,char toChar ); 151 152/// Replaces all occurrances of subStr with replacement. 153static String replaceAll ( 154UnownedStringSlice text , 155UnownedStringSlice subStr , 156UnownedStringSlice replacement ); 157 158/// Create a blob from a string 159static ComPtr < ISlangBlob > createStringBlob (const String & string ); 160 161/// Given input text outputs with standardized line endings. Ie \n\r -> \n 162static 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. 175static 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 179static 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 183static UnownedStringSlice trimEndOfLine (const UnownedStringSlice & slice ); 184 185/// Equal if the lines are equal (in effect a way to ignore differences in line breaks) 186static bool areLinesEqual (const UnownedStringSlice & a ,const UnownedStringSlice & b ); 187 188/// Convert in to int. Returns SLANG_FAIL on error 189static SlangResult parseInt (const UnownedStringSlice & in ,Int & outValue ); 190 191/// Convert ioText into double. Returns SLANG_OK on success. 192static SlangResult parseDouble (const UnownedStringSlice & text ,double & out ); 193 194/// Convert into int64_t. Returns SLANG_OK on success. 195static 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. 200static 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 : 208struct Iterator 209 { 210const UnownedStringSlice & operator * ()const {return m_line ; } 211const UnownedStringSlice * operator -> () const { return & m_line ; } 212Iterator & operator ++ () 213{ 214StringUtil ::extractLine( m_remaining , m_line ); 215return * this ; 216} 217Iterator operator ++ ( int ) 218{ 219Iterator rs = * this ; 220operator ++ (); 221return rs ; 222} 223 224/// Equal if both are at the same m_line address exactly. Handles termination case correctly 225/// where line.begin() == nullptr. 226bool operator == ( const Iterator & rhs ) const { return m_line .begin() == rhs . m_line .begin(); } 227bool operator != ( const Iterator & rhs ) const { return !( * this == rhs ); } 228 229/// Ctor 230Iterator ( const UnownedStringSlice & line , const UnownedStringSlice & remaining ) 231: m_line( line ), m_remaining( remaining ) 232{ 233} 234 235protected : 236UnownedStringSlice m_line ; 237UnownedStringSlice m_remaining ; 238}; 239 240Iterator begin() const 241{ 242UnownedStringSlice remaining( m_text ), line ; 243StringUtil ::extractLine( remaining , line ); 244return Iterator( line , remaining ); 245} 246Iterator end() const 247{ 248UnownedStringSlice term( nullptr , nullptr ); 249return Iterator( term , term ); 250} 251 252/// Ctor 253LineParser ( const UnownedStringSlice & text ) 254: m_text( text ) 255{ 256} 257 258protected : 259UnownedStringSlice m_text ; 260}; 261 262} // namespace Slang 263 264#endif // SLANG_STRING_UTIL_H