yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
1e20eed6e
master
1// slang-hex-dump-util.cpp 2#include "slang-hex-dump-util.h" 3 4#include "slang-char-util.h" 5#include "slang-com-helper.h" 6#include "slang-common.h" 7#include "slang-hash.h" 8#include "slang-string-util.h" 9#include "slang-writer.h" 10 11namespace Slang 12{ 13 14static const UnownedStringSlice s_start = UnownedStringSlice ::fromLiteral ("--START--" ); 15static const UnownedStringSlice s_end = UnownedStringSlice ::fromLiteral ("--END--" ); 16static const char s_hex []= "0123456789abcdef" ; 17 18/* static */ SlangResult HexDumpUtil ::dumpWithMarkers ( 19const List < uint8_t >& data , 20int maxBytesPerLine , 21ISlangWriter * writer ) 22{ 23return dumpWithMarkers (data .getBuffer (),data .getCount (),maxBytesPerLine ,writer ); 24} 25 26/* static */ SlangResult HexDumpUtil ::dumpWithMarkers ( 27const uint8_t * data , 28size_t dataCount , 29int maxBytesPerLine , 30ISlangWriter * writer ) 31{ 32WriterHelper helper (writer ); 33SLANG_RETURN_ON_FAIL (helper .write (s_start .begin (),s_start .getLength ())); 34SLANG_RETURN_ON_FAIL (helper ." %zu" ,dataCount )); 35 36const StableHashCode32 hash = getStableHashCode32 ((const char * )data ,dataCount ); 37SLANG_RETURN_ON_FAIL (helper ." %d\n" ,hash .hash )); 38 39SLANG_RETURN_ON_FAIL (dump (data ,dataCount ,maxBytesPerLine ,writer )); 40 41SLANG_RETURN_ON_FAIL (helper .write (s_end .begin (),s_end .getLength ())); 42SLANG_RETURN_ON_FAIL (helper .put ("\n" )); 43return SLANG_OK ; 44} 45 46/* static */ void HexDumpUtil ::dump (uint32_t value ,ISlangWriter * writer ) 47{ 48char c [9 ]; 49for (int i = 0 ;i < 8 ;++ i ) 50 { 51c [i ]= s_hex [value >>28 ]; 52value <<=4 ; 53 } 54writer -> write (c ,8 ); 55} 56 57 58/* static */ SlangResult HexDumpUtil ::dump ( 59const List < uint8_t >& data , 60int maxBytesPerLine , 61ISlangWriter * writer ) 62{ 63return dump (data .getBuffer (),data .getCount (),maxBytesPerLine ,writer ); 64} 65 66SlangResult HexDumpUtil ::dumpSourceBytes ( 67const uint8_t * data , 68size_t dataCount , 69int maxBytesPerLine , 70ISlangWriter * writer ) 71{ 72const uint8_t * cur = data ; 73const uint8_t * end = data + dataCount ; 74 75while (cur < end ) 76 { 77size_t count = size_t (end - cur ); 78count = (count > size_t (maxBytesPerLine )) ?size_t (maxBytesPerLine ) :count ; 79 80// each byte is output as "0xAA, " 81// Ends with '\n" 82const size_t lineBytes = count * 6 + 1 ; 83 84char * startDst = writer -> beginAppendBuffer (lineBytes ); 85char * dst = startDst ; 86 87for (size_t i = 0 ;i < count ;++ i ) 88 { 89uint8_t byte = cur [i ]; 90dst [0 ]= '0' ; 91dst [1 ]= 'x' ; 92dst [2 ]= s_hex [byte >>4 ]; 93dst [3 ]= s_hex [byte & 0xf ]; 94dst [4 ]= ',' ; 95dst [5 ]= ' ' ; 96 97dst += 6 ; 98 } 99 100* dst ++ = '\n' ; 101 102SLANG_RETURN_ON_FAIL (writer -> endAppendBuffer (startDst ,size_t (dst - startDst ))); 103 104cur += count ; 105 } 106 107return SLANG_OK ; 108} 109 110/* static */ SlangResult HexDumpUtil ::dump ( 111const uint8_t * data , 112size_t dataCount , 113int maxBytesPerLine , 114ISlangWriter * writer ) 115{ 116int maxCharsPerLine = 2 * maxBytesPerLine + 1 + maxBytesPerLine + 1 ; 117 118const uint8_t * cur = data ; 119const uint8_t * end = data + dataCount ; 120 121while (cur < end ) 122 { 123size_t count = size_t (end - cur ); 124count = (count > size_t (maxBytesPerLine )) ?size_t (maxBytesPerLine ) :count ; 125 126char * startDst = writer -> beginAppendBuffer (maxCharsPerLine ); 127char * dst = startDst ; 128 129for (size_t i = 0 ;i < count ;++ i ) 130 { 131uint8_t byte = cur [i ]; 132* dst ++ = s_hex [byte >>4 ]; 133* dst ++ = s_hex [byte & 0xf ]; 134 } 135 136// If not a complete line write spaces 137for (size_t i = count ;i < size_t (maxBytesPerLine );++ i ) 138 { 139* dst ++ = ' ' ; 140* dst ++ = ' ' ; 141 } 142 143* dst ++ = ' ' ; 144 145for (size_t i = 0 ;i < count ;++ i ) 146 { 147char c = char (cur [i ]); 148 149if ((c >='0' && c <='9' )|| (c >='a' && c <='z' )|| (c >='A' && c <='Z' )|| 150 (c >=32 && (c & 0x80 )== 0 )) 151 { 152 } 153else 154 { 155c = '.' ; 156 } 157* dst ++ = c ; 158 } 159 160* dst ++ = '\n' ; 161SLANG_ASSERT (dst <=startDst + maxCharsPerLine ); 162 163SLANG_RETURN_ON_FAIL (writer -> endAppendBuffer (startDst ,size_t (dst - startDst ))); 164 165cur += count ; 166 } 167 168return SLANG_OK ; 169} 170 171/* static */ SlangResult HexDumpUtil ::parse ( 172const UnownedStringSlice & lines , 173List < uint8_t >& outBytes ) 174{ 175outBytes .clear (); 176 177LineParser lineParser (lines ); 178for (const auto & line :lineParser ) 179 { 180const char * cur = line .begin (); 181const char * end = line .end (); 182 183while (cur + 2 <=end ) 184 { 185const char c = cur [0 ]; 186if (c == ' ' || c == '\n' || c == '\r' || c == '\t' ) 187 { 188// Skip to next line 189break ; 190 } 191 192const int hi = CharUtil ::getHexDigitValue (c ); 193const int lo = CharUtil ::getHexDigitValue (cur [1 ]); 194cur += 2 ; 195 196if (hi < 0 || lo < 0 ) 197 { 198return SLANG_FAIL ; 199 } 200outBytes .add (uint8_t ((hi <<4 ) |lo )); 201 } 202 } 203 204return SLANG_OK ; 205} 206 207static SlangResult _findLine ( 208const UnownedStringSlice & find , 209UnownedStringSlice & ioRemaining , 210UnownedStringSlice & outLine ) 211{ 212// Find the start line 213UnownedStringSlice line ; 214while (StringUtil ::extractLine (ioRemaining ,line )) 215 { 216if (line .startsWith (find )) 217 { 218outLine = line ; 219return SLANG_OK ; 220 } 221 } 222return SLANG_FAIL ; 223} 224 225/* static */ SlangResult HexDumpUtil ::findStartAndEndLines ( 226const UnownedStringSlice & lines , 227UnownedStringSlice & outStart , 228UnownedStringSlice & outEnd ) 229{ 230UnownedStringSlice remaining (lines ); 231SLANG_RETURN_ON_FAIL (_findLine (s_start ,remaining ,outStart )); 232SLANG_RETURN_ON_FAIL (_findLine (s_end ,remaining ,outEnd )); 233return SLANG_OK ; 234} 235 236/* static */ SlangResult HexDumpUtil ::parseWithMarkers ( 237const UnownedStringSlice & lines , 238List < uint8_t >& outBytes ) 239{ 240UnownedStringSlice startLine ,endLine ; 241SLANG_RETURN_ON_FAIL (findStartAndEndLines (lines ,startLine ,endLine )); 242 243StableHashCode32 hash ; 244size_t size ; 245 { 246// Get the size and the hash 247List < UnownedStringSlice > slices ; 248StringUtil ::split (startLine ,' ' ,slices ); 249if (slices .getCount ()!= 3 ) 250 { 251return SLANG_FAIL ; 252 } 253// Extract the size 254size = stringToInt (String (slices [1 ])); 255hash = StableHashCode32 {stringToUInt (String (slices [2 ]))}; 256 } 257 258SLANG_RETURN_ON_FAIL (parse (UnownedStringSlice (startLine .end (),endLine .begin ()),outBytes )); 259 260// Calc the hash 261const StableHashCode32 readHash = 262getStableHashCode32 ((const char * )outBytes .begin (),outBytes .getCount ()); 263 264if (readHash != hash || size_t (outBytes .getCount ())!= size ) 265 { 266return SLANG_FAIL ; 267 } 268return SLANG_OK ; 269} 270 271}// namespace Slang