helpers.go (2850B)
1 package mangler 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type ( 9 // serializing interfacing types. 10 stringer interface{ String() string } 11 binarymarshaler interface{ MarshalBinary() ([]byte, error) } 12 textmarshaler interface{ MarshalText() ([]byte, error) } 13 jsonmarshaler interface{ MarshalJSON() ([]byte, error) } 14 ) 15 16 func append_uint16(b []byte, u uint16) []byte { 17 return append(b, // LE 18 byte(u), 19 byte(u>>8), 20 ) 21 } 22 23 func append_uint32(b []byte, u uint32) []byte { 24 return append(b, // LE 25 byte(u), 26 byte(u>>8), 27 byte(u>>16), 28 byte(u>>24), 29 ) 30 } 31 32 func append_uint64(b []byte, u uint64) []byte { 33 return append(b, // LE 34 byte(u), 35 byte(u>>8), 36 byte(u>>16), 37 byte(u>>24), 38 byte(u>>32), 39 byte(u>>40), 40 byte(u>>48), 41 byte(u>>56), 42 ) 43 } 44 45 func deref_ptr_mangler(mangle Mangler, count int) rMangler { 46 return func(buf []byte, v reflect.Value) []byte { 47 for i := 0; i < count; i++ { 48 // Check for nil 49 if v.IsNil() { 50 buf = append(buf, '0') 51 return buf 52 } 53 54 // Further deref ptr 55 buf = append(buf, '1') 56 v = v.Elem() 57 } 58 59 // Mangle fully deref'd ptr 60 return mangle(buf, v.Interface()) 61 } 62 } 63 64 func deref_ptr_rmangler(mangle rMangler, count int) rMangler { 65 return func(buf []byte, v reflect.Value) []byte { 66 for i := 0; i < count; i++ { 67 // Check for nil 68 if v.IsNil() { 69 buf = append(buf, '0') 70 return buf 71 } 72 73 // Further deref ptr 74 buf = append(buf, '1') 75 v = v.Elem() 76 } 77 78 // Mangle fully deref'd ptr 79 return mangle(buf, v) 80 } 81 } 82 83 func array_to_slice_mangler(mangle Mangler) rMangler { 84 return func(buf []byte, v reflect.Value) []byte { 85 // Get slice of whole array 86 v = v.Slice(0, v.Len()) 87 88 // Mangle as known slice type 89 return mangle(buf, v.Interface()) 90 } 91 } 92 93 func iter_array_mangler(mangle Mangler) rMangler { 94 return func(buf []byte, v reflect.Value) []byte { 95 n := v.Len() 96 for i := 0; i < n; i++ { 97 buf = mangle(buf, v.Index(i).Interface()) 98 buf = append(buf, ',') 99 } 100 if n > 0 { 101 buf = buf[:len(buf)-1] 102 } 103 return buf 104 } 105 } 106 107 func iter_array_rmangler(mangle rMangler) rMangler { 108 return func(buf []byte, v reflect.Value) []byte { 109 n := v.Len() 110 for i := 0; i < n; i++ { 111 buf = mangle(buf, v.Index(i)) 112 buf = append(buf, ',') 113 } 114 if n > 0 { 115 buf = buf[:len(buf)-1] 116 } 117 return buf 118 } 119 } 120 121 func iter_map_rmangler(kMangle, vMangle rMangler) rMangler { 122 return func(buf []byte, v reflect.Value) []byte { 123 r := v.MapRange() 124 for r.Next() { 125 buf = kMangle(buf, r.Key()) 126 buf = append(buf, ':') 127 buf = vMangle(buf, r.Value()) 128 buf = append(buf, ',') 129 } 130 if v.Len() > 0 { 131 buf = buf[:len(buf)-1] 132 } 133 return buf 134 } 135 } 136 137 // iface_value returns the raw value ptr for input boxed within interface{} type. 138 func iface_value(a any) unsafe.Pointer { 139 type eface struct { 140 Type unsafe.Pointer 141 Value unsafe.Pointer 142 } 143 return (*eface)(unsafe.Pointer(&a)).Value 144 }