yum-mirror/slang

Making it easier to work with shaders

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

Ellie Hermaszewskaformatf65d756bf

master
3.5 KiB131 linesraw
1// slang-slice-allocator.cpp
2#include "slang-slice-allocator.h"
3
4#include "../core/slang-blob.h"
5
6namespace Slang
7{
8
9/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SliceUtil !!!!!!!!!!!!!!!!!!!!!!!!!!! */
10
11/* static */ List<String> SliceUtil::toList(const Slice<TerminatedCharSlice>& in)
12{
13    List<String> list;
14    const auto count = in.count;
15
16    list.setCount(count);
17    for (Index i = 0; i < count; ++i)
18    {
19        list[i] = asStringSlice(in[i]);
20    }
21    return list;
22}
23
24/* static */ const char* SliceUtil::getTerminated(ISlangBlob* blob, TerminatedCharSlice& outSlice)
25{
26    const auto size = blob->getBufferSize();
27    if (size == 0)
28    {
29        outSlice = TerminatedCharSlice();
30        return outSlice.begin();
31    }
32
33    // If there is a 0 at the end byte, we are zero terminated
34    const char* chars = (const char*)blob->getBufferPointer();
35    if (chars[size - 1] == 0)
36    {
37        outSlice = TerminatedCharSlice(chars, Count(size - 1));
38        return chars;
39    }
40
41    // See if it has a castable interface
42    ComPtr<ICastable> castable;
43    if (SLANG_SUCCEEDED(blob->queryInterface(SLANG_IID_PPV_ARGS(castable.writeRef()))))
44    {
45        if (castable->castAs(SlangTerminatedChars::getTypeGuid()))
46        {
47            outSlice = TerminatedCharSlice(chars, Count(size));
48            return chars;
49        }
50    }
51
52    return nullptr;
53}
54
55/* static */ TerminatedCharSlice SliceUtil::toTerminatedCharSlice(
56    SliceAllocator& allocator,
57    ISlangBlob* blob)
58{
59    TerminatedCharSlice slice;
60    if (SliceUtil::getTerminated(blob, slice))
61    {
62        return slice;
63    }
64    const auto size = blob->getBufferSize();
65    // We are out of options, we just have to allocate with zero termination which allocateString
66    // does
67    auto dst =
68        allocator.getArena().allocateString((const char*)blob->getBufferPointer(), Count(size));
69    return TerminatedCharSlice(dst, Count(size));
70}
71
72/* static */ TerminatedCharSlice SliceUtil::toTerminatedCharSlice(
73    StringBuilder& storage,
74    ISlangBlob* blob)
75{
76    TerminatedCharSlice slice;
77    if (SliceUtil::getTerminated(blob, slice))
78    {
79        return slice;
80    }
81
82    const auto size = blob->getBufferSize();
83    auto chars = (const char*)blob->getBufferPointer();
84
85    storage.clear();
86    storage.append(UnownedStringSlice(chars, size));
87
88    return TerminatedCharSlice(storage.getBuffer(), Count(size));
89}
90
91/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! SliceAllocator !!!!!!!!!!!!!!!!!!!!!!!!!!! */
92
93TerminatedCharSlice SliceAllocator::allocate(const char* in)
94{
95    const size_t length = ::strlen(in);
96    auto dst = m_arena.allocateString(in, length);
97    return TerminatedCharSlice(dst, length);
98}
99
100TerminatedCharSlice SliceAllocator::allocate(const UnownedStringSlice& slice)
101{
102    const auto length = slice.getLength();
103    auto dst = m_arena.allocateString(slice.begin(), length);
104    return TerminatedCharSlice(dst, length);
105}
106
107TerminatedCharSlice SliceAllocator::allocate(const Slice<char>& slice)
108{
109    const auto count = slice.count;
110    auto dst = m_arena.allocateString(slice.begin(), count);
111    return TerminatedCharSlice(dst, count);
112}
113
114Slice<TerminatedCharSlice> SliceAllocator::allocate(const List<String>& in)
115{
116    const auto count = in.getCount();
117    if (count == 0)
118    {
119        return Slice<TerminatedCharSlice>(nullptr, 0);
120    }
121
122    auto dst = m_arena.allocateArray<TerminatedCharSlice>(count);
123    for (Index i = 0; i < count; ++i)
124    {
125        dst[i] = allocate(in[i]);
126    }
127
128    return Slice<TerminatedCharSlice>(dst, count);
129}
130
131} // namespace Slang