yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// slang-offset-container.cpp 2#include "slang-offset-container.h" 3 4namespace Slang 5{ 6 7/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! OffsetString !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ 8 9size_t OffsetString ::calcEncodedSize (size_t size ,uint8_t encode [kMaxSizeEncodeSize ]) 10{ 11SLANG_ASSERT (size <=0xffffffff ); 12if (size <=kSizeBase ) 13 { 14encode [0 ]= uint8_t (size ); 15return 1 ; 16 } 17// Encode 18int num = 0 ; 19while (size ) 20 { 21encode [num + 1 ]= uint8_t (size ); 22size >>=8 ; 23num ++ ; 24 } 25 26// It might be one byte past the front, if its < 0x100 but greater than kSizeBase 27SLANG_ASSERT (num >=1 ); 28 29encode [0 ]= uint8_t (kSizeBase + num ); 30return num + 1 ; 31} 32 33/* static */ const char * OffsetString ::decodeSize (const char * in ,size_t & outSize ) 34{ 35const uint8_t * cur = (const uint8_t * )in ; 36if (* cur <=kSizeBase ) 37 { 38outSize = * cur ; 39return in + 1 ; 40 } 41 42int numBytes = * cur - kSizeBase ; 43switch (numBytes ) 44 { 45case 1 : 46 { 47outSize = cur [1 ]; 48return in + 2 ; 49 } 50case 2 : 51 { 52outSize = cur [1 ] | (uint32_t (cur [2 ]) <<8 ); 53return in + 3 ; 54 } 55case 3 : 56 { 57outSize = cur [1 ] | (uint32_t (cur [2 ]) <<8 ) | (uint32_t (cur [3 ]) <<16 ); 58return in + 4 ; 59 } 60case 4 : 61 { 62outSize = cur [1 ] | (uint32_t (cur [2 ]) <<8 ) | (uint32_t (cur [3 ]) <<16 ) | 63 (uint32_t (cur [4 ]) <<24 ); 64return in + 5 ; 65 } 66default : 67 { 68outSize = 0 ; 69return nullptr ; 70 } 71 } 72} 73 74/* static */ size_t OffsetString ::calcAllocationSize (size_t stringSize ) 75{ 76uint8_t encode [kMaxSizeEncodeSize ]; 77size_t encodeSize = calcEncodedSize (stringSize ,encode ); 78// Add 1 for terminating 0 79return encodeSize + stringSize + 1 ; 80} 81 82/* static */ size_t OffsetString ::calcAllocationSize (const UnownedStringSlice & slice ) 83{ 84return calcAllocationSize (slice .getLength ()); 85} 86 87UnownedStringSlice OffsetString ::getSlice ()const 88{ 89size_t size ; 90const char * chars = decodeSize (m_sizeThenContents ,size ); 91 92return UnownedStringSlice (chars ,size ); 93} 94 95const char * OffsetString ::getCstr ()const 96{ 97return getSlice ().begin (); 98} 99 100/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! OffsetContainer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 101*/ 102 103OffsetContainer ::OffsetContainer () 104{ 105m_capacity = 0 ; 106m_data = nullptr ; 107 108// We need to allocate some of the first bytes 0 can be used for nullptr. 109allocateAndZero (kStartOffset ,1 ); 110} 111 112OffsetContainer ::~OffsetContainer () 113{ 114if (m_data ) 115 { 116 ::free (m_data ); 117 } 118} 119 120void * OffsetContainer ::allocate (size_t size ) 121{ 122return allocate (size ,1 ); 123} 124 125void OffsetContainer ::fixAlignment (size_t alignment ) 126{ 127allocate (0 ,alignment ); 128} 129 130void * OffsetContainer ::allocate (size_t size ,size_t alignment ) 131{ 132size_t offset = (m_dataSize + alignment - 1 )& ~(alignment - 1 ); 133 134if (offset + size > m_capacity ) 135 { 136const size_t minSize = offset + size ; 137 138size_t calcSize = m_capacity ; 139if (calcSize < 2048 ) 140 { 141calcSize = 2048 ; 142 } 143else 144 { 145// Expand geometrically, but lets not double in size... 146calcSize = calcSize + (calcSize /2 ); 147 } 148 149// We must be at least minSize 150size_t newSize = (calcSize < minSize ) ?minSize :calcSize ; 151 152// Reallocate space 153m_data = (uint8_t * )::realloc (m_data ,newSize ); 154m_capacity = newSize ; 155 } 156 157SLANG_ASSERT (offset + size <=m_capacity ); 158 159m_dataSize = offset + size ; 160return m_data + offset ; 161} 162 163void * OffsetContainer ::allocateAndZero (size_t size ,size_t alignment ) 164{ 165void * data = allocate (size ,alignment ); 166memset (data ,0 ,size ); 167return data ; 168} 169 170Offset32Ptr < OffsetString > OffsetContainer ::newString (const UnownedStringSlice & slice ) 171{ 172size_t stringSize = slice .getLength (); 173 174uint8_t head [OffsetString ::kMaxSizeEncodeSize ]; 175size_t headSize = OffsetString ::calcEncodedSize (stringSize ,head ); 176 177size_t allocSize = headSize + stringSize + 1 ; 178uint8_t * bytes = (uint8_t * )allocate (allocSize ); 179 180 ::memcpy (bytes ,head ,headSize ); 181 ::memcpy (bytes + headSize ,slice .begin (),stringSize ); 182 183// 0 terminate 184bytes [headSize + stringSize ]= 0 ; 185 186return Offset32Ptr < OffsetString > (getOffset (bytes )); 187} 188 189Offset32Ptr < OffsetString > OffsetContainer ::newString (const char * contents ) 190{ 191Offset32Ptr < OffsetString > relString ; 192if (contents ) 193 { 194relString = newString (UnownedStringSlice (contents )); 195 } 196return relString ; 197} 198 199}// namespace Slang