raiguard/odin-wayland
git clone https://git.raiguard.me/raiguard/odin-wayland
fd8ef50
trunk
1#+build linux 2package wayland 3 4import "base:runtime" 5import "core:io" 6 7_unmarshal_raw :: proc ( stream : io . Stream , $ Value_Type : typeid ) -> ( value : Value_Type , error : io . Error ) 8where Value_Type == u32 || Value_Type == i32 || Value_Type == Object_ID || Value_Type == Message_Header 9{ 10VALUE_LEN :: size_of ( Value_Type ) 11bytes : [ VALUE_LEN ] byte 12n_read := io . read ( stream , bytes [:]) or_return 13if n_read < VALUE_LEN { 14return {}, . Unexpected_EOF 15} 16return transmute ( Value_Type ) bytes , nil 17} 18 19_unmarshal_fixed :: proc ( stream : io . Stream ) -> ( value : Fixed , error : io . Error ) { 20raw_value := _unmarshal_raw ( stream , u32 ) or_return 21return Fixed { i = raw_value }, nil 22} 23 24_unmarshal_string :: proc ( stream : io . Stream , allocator : runtime . Allocator ) -> ( str : string , error : io . Error ) { 25str_len := _unmarshal_raw ( stream , u32 ) or_return 26if str_len == 0 { 27return 28} 29// -1 because the string ends will a null terminator. 30buf := make ([] byte , str_len - 1 , allocator ) 31n_read := io . read ( stream , buf ) or_return 32if n_read < len ( buf ) { 33error = . Unexpected_EOF 34return 35} 36 37// Pad to 4 bytes 38@( static ) 39padding_buf : [ 4 ] byte 40remainder := ( 4 - ( str_len % 4 )) % 4 41// +1 for unread null terminator. 42io . read ( stream , padding_buf [: remainder + 1 ]) 43 44return string ( buf ), nil 45} 46 47_unmarshal_to :: proc ( destination : ^ $ T , stream : io . Stream , allocator : runtime . Allocator ) -> io . Error { 48when T == u32 || T == i32 || T == Object_ID || T == Message_Header { 49destination ^ = _unmarshal_raw ( stream , T ) or_return 50} else when T == Fixed { 51destination ^ = _unmarshal_fixed ( stream ) or_return 52} else when T == string { 53destination ^ = _unmarshal_string ( stream , allocator ) or_return 54} 55return nil 56}