manglers.go (5944B)
1 package mangler 2 3 import ( 4 "math/bits" 5 _ "unsafe" 6 ) 7 8 // Notes: 9 // the use of unsafe conversion from the direct interface values to 10 // the chosen types in each of the below functions allows us to convert 11 // not only those types directly, but anything type-aliased to those 12 // types. e.g. `time.Duration` directly as int64. 13 14 func mangle_string(buf []byte, a any) []byte { 15 return append(buf, *(*string)(iface_value(a))...) 16 } 17 18 func mangle_string_ptr(buf []byte, a any) []byte { 19 if ptr := (*string)(iface_value(a)); ptr != nil { 20 buf = append(buf, '1') 21 return append(buf, *ptr...) 22 } 23 buf = append(buf, '0') 24 return buf 25 } 26 27 func mangle_string_slice(buf []byte, a any) []byte { 28 s := *(*[]string)(iface_value(a)) 29 for _, s := range s { 30 buf = append(buf, s...) 31 buf = append(buf, ',') 32 } 33 if len(s) > 0 { 34 buf = buf[:len(buf)-1] 35 } 36 return buf 37 } 38 39 func mangle_bool(buf []byte, a any) []byte { 40 if *(*bool)(iface_value(a)) { 41 return append(buf, '1') 42 } 43 return append(buf, '0') 44 } 45 46 func mangle_bool_ptr(buf []byte, a any) []byte { 47 if ptr := (*bool)(iface_value(a)); ptr != nil { 48 buf = append(buf, '1') 49 if *ptr { 50 return append(buf, '1') 51 } 52 return append(buf, '0') 53 } 54 buf = append(buf, '0') 55 return buf 56 } 57 58 func mangle_bool_slice(buf []byte, a any) []byte { 59 for _, b := range *(*[]bool)(iface_value(a)) { 60 if b { 61 buf = append(buf, '1') 62 } else { 63 buf = append(buf, '0') 64 } 65 } 66 return buf 67 } 68 69 func mangle_8bit(buf []byte, a any) []byte { 70 return append(buf, *(*uint8)(iface_value(a))) 71 } 72 73 func mangle_8bit_ptr(buf []byte, a any) []byte { 74 if ptr := (*uint8)(iface_value(a)); ptr != nil { 75 buf = append(buf, '1') 76 return append(buf, *ptr) 77 } 78 buf = append(buf, '0') 79 return buf 80 } 81 82 func mangle_8bit_slice(buf []byte, a any) []byte { 83 return append(buf, *(*[]uint8)(iface_value(a))...) 84 } 85 86 func mangle_16bit(buf []byte, a any) []byte { 87 return append_uint16(buf, *(*uint16)(iface_value(a))) 88 } 89 90 func mangle_16bit_ptr(buf []byte, a any) []byte { 91 if ptr := (*uint16)(iface_value(a)); ptr != nil { 92 buf = append(buf, '1') 93 return append_uint16(buf, *ptr) 94 } 95 buf = append(buf, '0') 96 return buf 97 } 98 99 func mangle_16bit_slice(buf []byte, a any) []byte { 100 for _, u := range *(*[]uint16)(iface_value(a)) { 101 buf = append_uint16(buf, u) 102 } 103 return buf 104 } 105 106 func mangle_32bit(buf []byte, a any) []byte { 107 return append_uint32(buf, *(*uint32)(iface_value(a))) 108 } 109 110 func mangle_32bit_ptr(buf []byte, a any) []byte { 111 if ptr := (*uint32)(iface_value(a)); ptr != nil { 112 buf = append(buf, '1') 113 return append_uint32(buf, *ptr) 114 } 115 buf = append(buf, '0') 116 return buf 117 } 118 119 func mangle_32bit_slice(buf []byte, a any) []byte { 120 for _, u := range *(*[]uint32)(iface_value(a)) { 121 buf = append_uint32(buf, u) 122 } 123 return buf 124 } 125 126 func mangle_64bit(buf []byte, a any) []byte { 127 return append_uint64(buf, *(*uint64)(iface_value(a))) 128 } 129 130 func mangle_64bit_ptr(buf []byte, a any) []byte { 131 if ptr := (*uint64)(iface_value(a)); ptr != nil { 132 buf = append(buf, '1') 133 return append_uint64(buf, *ptr) 134 } 135 buf = append(buf, '0') 136 return buf 137 } 138 139 func mangle_64bit_slice(buf []byte, a any) []byte { 140 for _, u := range *(*[]uint64)(iface_value(a)) { 141 buf = append_uint64(buf, u) 142 } 143 return buf 144 } 145 146 // mangle_platform_int contains the correct iface mangler on runtime for platform int size. 147 var mangle_platform_int = func() Mangler { 148 switch bits.UintSize { 149 case 32: 150 return mangle_32bit 151 case 64: 152 return mangle_64bit 153 default: 154 panic("unexpected platform int size") 155 } 156 }() 157 158 // mangle_platform_int_ptr contains the correct iface mangler on runtime for platform int size. 159 var mangle_platform_int_ptr = func() Mangler { 160 switch bits.UintSize { 161 case 32: 162 return mangle_32bit_ptr 163 case 64: 164 return mangle_64bit_ptr 165 default: 166 panic("unexpected platform int size") 167 } 168 }() 169 170 // mangle_platform_int_slice contains the correct iface mangler on runtime for platform int size. 171 var mangle_platform_int_slice = func() Mangler { 172 switch bits.UintSize { 173 case 32: 174 return mangle_32bit_slice 175 case 64: 176 return mangle_64bit_slice 177 default: 178 panic("unexpected platform int size") 179 } 180 }() 181 182 // uint128 provides an easily mangleable data type for 128bit data types to be cast into. 183 type uint128 [2]uint64 184 185 func mangle_128bit(buf []byte, a any) []byte { 186 u2 := *(*uint128)(iface_value(a)) 187 buf = append_uint64(buf, u2[0]) 188 buf = append_uint64(buf, u2[1]) 189 return buf 190 } 191 192 func mangle_128bit_ptr(buf []byte, a any) []byte { 193 if ptr := (*uint128)(iface_value(a)); ptr != nil { 194 buf = append(buf, '1') 195 buf = append_uint64(buf, (*ptr)[0]) 196 buf = append_uint64(buf, (*ptr)[1]) 197 } 198 buf = append(buf, '0') 199 return buf 200 } 201 202 func mangle_128bit_slice(buf []byte, a any) []byte { 203 for _, u2 := range *(*[]uint128)(iface_value(a)) { 204 buf = append_uint64(buf, u2[0]) 205 buf = append_uint64(buf, u2[1]) 206 } 207 return buf 208 } 209 210 func mangle_mangled(buf []byte, a any) []byte { 211 if v := a.(Mangled); v != nil { 212 buf = append(buf, '1') 213 return v.Mangle(buf) 214 } 215 buf = append(buf, '0') 216 return buf 217 } 218 219 func mangle_binary(buf []byte, a any) []byte { 220 if v := a.(binarymarshaler); v != nil { 221 b, err := v.MarshalBinary() 222 if err != nil { 223 panic("mangle_binary: " + err.Error()) 224 } 225 buf = append(buf, '1') 226 return append(buf, b...) 227 } 228 buf = append(buf, '0') 229 return buf 230 } 231 232 func mangle_stringer(buf []byte, a any) []byte { 233 if v := a.(stringer); v != nil { 234 buf = append(buf, '1') 235 return append(buf, v.String()...) 236 } 237 buf = append(buf, '0') 238 return buf 239 } 240 241 func mangle_text(buf []byte, a any) []byte { 242 if v := a.(textmarshaler); v != nil { 243 b, err := v.MarshalText() 244 if err != nil { 245 panic("mangle_text: " + err.Error()) 246 } 247 buf = append(buf, '1') 248 return append(buf, b...) 249 } 250 buf = append(buf, '0') 251 return buf 252 } 253 254 func mangle_json(buf []byte, a any) []byte { 255 if v := a.(jsonmarshaler); v != nil { 256 b, err := v.MarshalJSON() 257 if err != nil { 258 panic("mangle_json: " + err.Error()) 259 } 260 buf = append(buf, '1') 261 return append(buf, b...) 262 } 263 buf = append(buf, '0') 264 return buf 265 }