yum-mirror/slang

Making it easier to work with shaders

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

Theresa FoleyCleanups related to RIFF support (#7041)4c76b2759

master
3.9 KiB166 linesraw
1#include "slang-text-io.h"
2
3#include "slang-com-helper.h"
4
5namespace Slang
6{
7
8// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StreamWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9
10SlangResult StreamWriter::init(const String& path, CharEncoding* encoding)
11{
12    RefPtr<FileStream> fileStream = new FileStream;
13    SLANG_RETURN_ON_FAIL(fileStream->init(path, FileMode::Create));
14    return init(fileStream, encoding);
15}
16
17SlangResult StreamWriter::init(RefPtr<Stream> stream, CharEncoding* encoding)
18{
19    m_stream = stream;
20    m_encoding = encoding;
21    if (encoding == CharEncoding::UTF16)
22    {
23        SLANG_RETURN_ON_FAIL(m_stream->write(&kUTF16Header, 2));
24    }
25    else if (encoding == CharEncoding::UTF16Reversed)
26    {
27        SLANG_RETURN_ON_FAIL(m_stream->write(&kUTF16ReversedHeader, 2));
28    }
29
30    return SLANG_OK;
31}
32
33SlangResult StreamWriter::writeSlice(const UnownedStringSlice& slice)
34{
35    // TODO(JS):
36    // We can do better here. On Linux, this is a no-op and can just write directly (assuming slice
37    // only contains \n)
38
39    m_encodingBuffer.clear();
40
41    StringBuilder sb;
42#ifdef _WIN32
43    const char newLine[] = "\r\n";
44#else
45    const char newLine[] = "\n";
46#endif
47    const Index length = slice.getLength();
48
49    for (Index i = 0; i < length; i++)
50    {
51        if (slice[i] == '\r')
52            sb << newLine;
53        else if (slice[i] == '\n')
54        {
55            if (i > 0 && slice[i - 1] != '\r')
56                sb << newLine;
57        }
58        else
59            sb << slice[i];
60    }
61
62    // NOTE! This assumes that sb contains *complete* utf8 code points, which it might not, as
63    // encoder is only able to handle complete code points.
64    m_encodingBuffer.clear();
65    m_encoding->encode(sb.getUnownedSlice(), m_encodingBuffer);
66    return m_stream->write(m_encodingBuffer.getBuffer(), m_encodingBuffer.getCount());
67}
68
69// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! StreamReader !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
70
71StreamReader::StreamReader() {}
72
73SlangResult StreamReader::init(const String& path)
74{
75    RefPtr<FileStream> fileStream = new FileStream;
76    SLANG_RETURN_ON_FAIL(fileStream->init(path, FileMode::Open));
77    return init(fileStream);
78}
79
80SlangResult StreamReader::init(RefPtr<Stream> stream, CharEncoding* encoding)
81{
82    m_stream = stream;
83    m_encoding = encoding;
84    SLANG_RETURN_ON_FAIL(readBuffer());
85
86    if (encoding == nullptr)
87    {
88        size_t offset;
89        m_encodingType = CharEncoding::determineEncoding(
90            (const Byte*)m_buffer.getBuffer(),
91            m_buffer.getCount(),
92            offset);
93        m_encoding = CharEncoding::getEncoding(m_encodingType);
94        m_index = Index(offset);
95    }
96    else
97    {
98        m_encodingType = encoding->getEncodingType();
99        m_encoding = encoding;
100    }
101
102    return SLANG_OK;
103}
104
105SlangResult StreamReader::readBuffer()
106{
107    m_buffer.setCount(0);
108    m_index = 0;
109
110    if (m_stream->isEnd())
111    {
112        return SLANG_OK;
113    }
114
115    m_buffer.setCount(4096);
116
117    // TODO(JS): Not clear this is necessary
118    memset(m_buffer.getBuffer(), 0, m_buffer.getCount() * sizeof(m_buffer[0]));
119
120    size_t readBytes;
121    SLANG_RETURN_ON_FAIL(m_stream->read(m_buffer.getBuffer(), m_buffer.getCount(), readBytes));
122
123    m_buffer.setCount(Index(readBytes));
124    m_index = 0;
125    return SLANG_OK;
126}
127
128Byte StreamReader::readBufferByte()
129{
130    if (m_index < m_buffer.getCount())
131    {
132        return m_buffer[m_index++];
133    }
134
135    readBuffer();
136
137    if (m_index < m_buffer.getCount())
138    {
139        return m_buffer[m_index++];
140    }
141    return 0;
142}
143
144SlangResult StreamReader::readToEnd(String& outString)
145{
146    StringBuilder sb(16384);
147    while (!isEnd())
148    {
149        auto ch = read();
150        if (isEnd())
151            break;
152        if (ch == '\r')
153        {
154            sb.append('\n');
155            if (peek() == '\n')
156                read();
157        }
158        else
159            sb.append(ch);
160    }
161
162    outString = sb.produceString();
163    return SLANG_OK;
164}
165
166} // namespace Slang