yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#pragma once 2#include "../core/slang-blob.h" 3#include "../core/slang-list.h" 4#include "../core/slang-string.h" 5#include "slang.h" 6 7namespace Slang 8{ 9struct DigestUtil 10{ 11/// Convert a binary digest to a string (lower-case hexadecimal). 12/// Returned string is double the length of the digest. 13static String digestToString (const void * digest ,SlangInt digestSize ); 14 15/// Convert a string to a binary digest. 16/// Expects a string of double the length of the digest size in hexadecimal format. 17/// Sets the digest to all zeros if the string is invalid. 18/// Returns true if string was converted successfully. 19static bool stringToDigest ( 20const char * str , 21SlangInt strLength , 22void * digest , 23SlangInt digestSize ); 24}; 25 26/// Represents a hash digest. Only sizes of multiple of 4 are supported. 27template < SlangInt N > 28class HashDigest 29{ 30public : 31static_assert (N %4 == 0 ,"size must be multiple of 4" ); 32uint32_t data [N /4 ]= {0 }; 33 34HashDigest ()= default ; 35 36HashDigest (const char * str ) {DigestUtil ::stringToDigest (str , ::strlen (str ),data ,N ); } 37 38HashDigest (const String & str ) 39 { 40DigestUtil ::stringToDigest (str .getBuffer (),str .getLength (),data ,N ); 41 } 42 43HashDigest (const UnownedStringSlice & str ) 44 { 45DigestUtil ::stringToDigest (str .begin (),str .getLength (),data ,N ); 46 } 47 48HashDigest (ISlangBlob * blob ) 49 { 50if (blob -> getBufferSize ()== N ) 51 { 52 ::memcpy (data ,blob -> getBufferPointer (),N ); 53 } 54 } 55 56String toString ()const {return DigestUtil ::digestToString (data ,N ); } 57 58ComPtr < ISlangBlob > toBlob ()const {return RawBlob ::create (data ,sizeof (data )); } 59 60bool operator == (const HashDigest & other )const 61 { 62return ::memcmp (data ,other .data ,sizeof (data ))== 0 ; 63 } 64 65bool operator != (const HashDigest & other )const {return !(* this == other ); } 66 67uint32_t getHashCode ()const {return data [0 ]; } 68}; 69 70/// MD5 hash generator implementing https://www.ietf.org/rfc/rfc1321.txt 71class MD5 72{ 73public : 74using Digest = HashDigest < 16 > ; 75 76MD5 (); 77 78void init (); 79void update (const void * data ,SlangSizeT size ); 80Digest finalize (); 81 82static Digest compute (const void * data ,SlangInt size ); 83 84private : 85const void * processBlock (const void * data ,SlangInt size ); 86 87uint32_t m_lo ,m_hi ; 88uint32_t m_a ,m_b ,m_c ,m_d ; 89uint32_t m_block [16 ]; 90uint8_t m_buffer [64 ]; 91}; 92 93/// SHA1 hash generator implementing https://www.ietf.org/rfc/rfc3174.txt 94class SHA1 95{ 96public : 97using Digest = HashDigest < 20 > ; 98 99SHA1 (); 100 101void init (); 102void update (const void * data ,SlangSizeT size ); 103Digest finalize (); 104 105static Digest compute (const void * data ,SlangInt size ); 106 107private : 108void addByte (uint8_t x ); 109void processBlock (const uint8_t * ptr ); 110 111uint32_t m_index ; 112uint64_t m_bits ; 113uint32_t m_state [5 ]; 114uint8_t m_buf [64 ]; 115}; 116 117// Helper class for building hashes. 118template < typename Hash > 119struct DigestBuilder 120{ 121public : 122void append (const void * data ,SlangInt size ) {m_hash .update (data ,size ); } 123 124template < 125typename T , 126typename std ::enable_if < std ::is_arithmetic < T > ::value || std ::is_enum < T > ::value ,int > ::type = 1270 > 128void append (const T value ) 129 { 130append (& value ,sizeof (T )); 131 } 132 133void append (const String & str ) {append (str .getBuffer (),str .getLength ()); } 134 135void append (const StringSlice & str ) {append (str .begin (),str .getLength ()); } 136 137void append (const UnownedStringSlice & str ) {append (str .begin (),str .getLength ()); } 138 139void append (ISlangBlob * blob ) {append (blob -> getBufferPointer (),blob -> getBufferSize ()); } 140 141template < SlangInt N > 142void append (const HashDigest < N >& digest ) 143 { 144append (digest .data ,sizeof (digest .data )); 145 } 146 147template < typename T ,std ::enable_if_t < std ::has_unique_object_representations_v < T > ,int > = 0 > 148void append (const List < T >& list ) 149 { 150append (list .getBuffer (),list .getCount ()* sizeof (T )); 151 } 152 153typename Hash ::Digest finalize () {return m_hash .finalize (); } 154 155private : 156Hash m_hash ; 157}; 158}// namespace Slang