yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
6104a5554
master
1#define _CRT_SECURE_NO_WARNINGS 2 3#include "slang-writer.h" 4 5#include "slang-platform.h" 6#include "slang-string-util.h" 7 8// Includes to allow us to control console 9// output when writing assembly dumps. 10#include <fcntl.h> 11#ifdef _WIN32 12#include <io.h> 13#else 14#include <unistd.h> 15#endif 16 17#include <stdarg.h> 18 19namespace Slang 20{ 21 22/* !!!!!!!!!!!!!!!!!!!!!!!!! WriterHelper !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 23 24SlangResult WriterHelper ::const char * format , ...) 25{ 26va_list args ; 27va_start (args ,format ); 28 29SlangResult res = SLANG_OK ; 30 31// numChars is the amount of characters needed *not* including terminating 0 32size_t numChars ; 33 { 34// Create a copy of args, as will be consumed by calcFormattedSize 35va_list argsCopy ; 36va_copy (argsCopy ,args ); 37numChars = StringUtil ::calcFormattedSize (format ,argsCopy ); 38va_end (argsCopy ); 39 } 40 41if (numChars > 0 ) 42 { 43// We need to add 1 here, because calcFormatted, *requires* space for terminating 0 44char * appendBuffer = m_writer -> beginAppendBuffer (numChars + 1 ); 45StringUtil ::calcFormatted (format ,args ,numChars ,appendBuffer ); 46res = m_writer -> endAppendBuffer (appendBuffer ,numChars ); 47 } 48 49va_end (args ); 50return res ; 51} 52 53SlangResult WriterHelper ::put (const char * text ) 54{ 55return m_writer -> write (text , ::strlen (text )); 56} 57 58SlangResult WriterHelper ::put (const UnownedStringSlice & text ) 59{ 60return m_writer -> write (text .begin (),text .getLength ()); 61} 62 63/* !!!!!!!!!!!!!!!!!!!!!!!!! BaseWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 64 65ISlangUnknown * BaseWriter ::getInterface (const Guid & guid ) 66{ 67return (guid == ISlangUnknown ::getTypeGuid ()|| guid == ISlangWriter ::getTypeGuid ()) 68 ?static_cast < ISlangWriter *> (this ) 69 :nullptr ; 70} 71 72/* !!!!!!!!!!!!!!!!!!!!!!!!! AppendBufferWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 73 74SLANG_NO_THROW char * SLANG_MCALL AppendBufferWriter ::beginAppendBuffer (size_t maxNumChars ) 75{ 76mutex .lock (); 77m_appendBuffer .setCount (maxNumChars ); 78return m_appendBuffer .getBuffer (); 79} 80 81SLANG_NO_THROW SlangResult SLANG_MCALL 82AppendBufferWriter ::endAppendBuffer (char * buffer ,size_t numChars ) 83{ 84SLANG_ASSERT (m_appendBuffer .getBuffer ()== buffer && buffer + numChars <=m_appendBuffer .end ()); 85// Do the actual write 86SlangResult res = write (buffer ,numChars ); 87// Clear so that buffer can't be written from again without assert 88m_appendBuffer .clear (); 89mutex .unlock (); 90return res ; 91} 92 93/* !!!!!!!!!!!!!!!!!!!!!!!!! CallbackWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 94 95SLANG_NO_THROW char * SLANG_MCALL CallbackWriter ::beginAppendBuffer (size_t maxNumChars ) 96{ 97// Add one so there is always space for end termination, we need for the callback. 98m_appendBuffer .setCount (maxNumChars + 1 ); 99return m_appendBuffer .getBuffer (); 100} 101 102SlangResult CallbackWriter ::write (const char * chars ,size_t numChars ) 103{ 104if (numChars > 0 ) 105 { 106char * appendBuffer = m_appendBuffer .getBuffer (); 107// See if it's from an append buffer 108if (chars >=appendBuffer && 109 (chars + numChars )< (appendBuffer + m_appendBuffer .getCount ())) 110 { 111// Set terminating 0 112appendBuffer [(chars + numChars )- appendBuffer ]= 0 ; 113 114m_callback (chars , (void * )m_data ); 115 } 116else 117 { 118// Use the append buffer to add the terminating 0 119m_appendBuffer .setCount (numChars + 1 ); 120 ::memcpy (m_appendBuffer .getBuffer (),chars ,numChars ); 121m_appendBuffer [numChars ]= 0 ; 122 123m_callback (m_appendBuffer .getBuffer (), (void * )m_data ); 124 } 125 } 126 127return SLANG_OK ; 128} 129 130/* !!!!!!!!!!!!!!!!!!!!!!!!! FileWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 131 132FileWriter ::~FileWriter () 133{ 134if (m_file ) 135 { 136 ::fflush (m_file ); 137 138if ((m_flags & WriterFlag ::IsUnowned )== 0 ) 139 { 140 ::fclose (m_file ); 141 } 142 } 143} 144 145SlangResult FileWriter ::write (const char * text ,size_t numChars ) 146{ 147const size_t numWritten = ::fwrite (text ,sizeof (char ),numChars ,m_file ); 148if (m_flags & WriterFlag ::AutoFlush ) 149 { 150 ::fflush (m_file ); 151 } 152return numChars == numWritten ?SLANG_OK :SLANG_FAIL ; 153} 154 155void FileWriter ::flush () 156{ 157 ::fflush (m_file ); 158} 159 160/* static */ bool FileWriter ::isFileConsole (FILE * file ) 161{ 162const int stdoutFileDesc = _fileno (file ); 163return _isatty (stdoutFileDesc )!= 0 ; 164} 165 166SlangResult FileWriter ::setMode (SlangWriterMode mode ) 167{ 168switch (mode ) 169 { 170case SLANG_WRITER_MODE_BINARY : 171 { 172#ifdef _WIN32 173int stdoutFileDesc = _fileno (m_file ); 174_setmode (stdoutFileDesc ,_O_BINARY ); 175return SLANG_OK ; 176#else 177break ; 178#endif 179 } 180default : 181break ; 182 } 183return SLANG_FAIL ; 184} 185 186/* static */ SlangResult FileWriter ::create ( 187const char * filePath , 188const char * writeOptions , 189WriterFlags flags , 190ComPtr < ISlangWriter >& outWriter ) 191{ 192flags &= ~WriterFlag ::IsUnowned ; 193 194FILE * file = fopen (filePath ,writeOptions ); 195if (!file ) 196 { 197return SLANG_E_CANNOT_OPEN ; 198 } 199 200outWriter = new FileWriter (file ,flags ); 201return SLANG_OK ; 202} 203 204 205/* !!!!!!!!!!!!!!!!!!!!!!!!! StringWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ 206 207SLANG_NO_THROW char * SLANG_MCALL StringWriter ::beginAppendBuffer (size_t maxNumChars ) 208{ 209return m_builder -> prepareForAppend (maxNumChars ); 210} 211 212SLANG_NO_THROW SlangResult SLANG_MCALL StringWriter ::endAppendBuffer (char * buffer ,size_t numChars ) 213{ 214m_builder -> appendInPlace (buffer ,numChars ); 215return SLANG_OK ; 216} 217 218SlangResult StringWriter ::write (const char * chars ,size_t numChars ) 219{ 220if (numChars > 0 ) 221 { 222m_builder -> append (chars ,numChars ); 223 } 224return SLANG_OK ; 225} 226 227}// namespace Slang