mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 18:42:25 -06:00 
			
		
		
		
	
		
			
	
	
		
			94 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			94 lines
		
	
	
	
		
			2.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package mangler
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"unsafe"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"codeberg.org/gruf/go-xunsafe"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Mangler is a function that will take an input value of known type,
							 | 
						||
| 
								 | 
							
								// and append it in mangled serialized form to the given byte buffer.
							 | 
						||
| 
								 | 
							
								type Mangler func(buf []byte, ptr unsafe.Pointer) []byte
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Get will fetch the Mangler function for given runtime type information.
							 | 
						||
| 
								 | 
							
								// The required argument is of type xunsafe.TypeIter{} as unsafe pointer
							 | 
						||
| 
								 | 
							
								// access requires further contextual information like type nesting.
							 | 
						||
| 
								 | 
							
								func Get(t xunsafe.TypeIter) Mangler {
							 | 
						||
| 
								 | 
							
									t.Parent = nil // enforce type prefix
							 | 
						||
| 
								 | 
							
									fn := loadOrStore(t)
							 | 
						||
| 
								 | 
							
									if fn == nil {
							 | 
						||
| 
								 | 
							
										panic(fmt.Sprintf("cannot mangle type: %s", t.Type))
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return fn
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// GetNoLoad is functionally similar to Get(),
							 | 
						||
| 
								 | 
							
								// without caching the resulting Mangler.
							 | 
						||
| 
								 | 
							
								func GetNoLoad(t xunsafe.TypeIter) Mangler {
							 | 
						||
| 
								 | 
							
									t.Parent = nil // enforce type prefix
							 | 
						||
| 
								 | 
							
									fn := loadOrGet(t)
							 | 
						||
| 
								 | 
							
									if fn == nil {
							 | 
						||
| 
								 | 
							
										panic(fmt.Sprintf("cannot mangle type: %s", t.Type))
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return fn
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Append will append the mangled form of input value 'a' to buffer 'b'.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// See mangler.String() for more information on mangled output.
							 | 
						||
| 
								 | 
							
								func Append(b []byte, a any) []byte {
							 | 
						||
| 
								 | 
							
									t := xunsafe.TypeIterFrom(a)
							 | 
						||
| 
								 | 
							
									p := xunsafe.UnpackEface(a)
							 | 
						||
| 
								 | 
							
									return Get(t)(b, p)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// AppendMulti appends all mangled forms of input value(s) 'a' to buffer 'b'
							 | 
						||
| 
								 | 
							
								// separated by colon characters. When all type manglers are currently cached
							 | 
						||
| 
								 | 
							
								// for all types in 'a', this will be faster than multiple calls to Append().
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// See mangler.String() for more information on mangled output.
							 | 
						||
| 
								 | 
							
								func AppendMulti(b []byte, a ...any) []byte {
							 | 
						||
| 
								 | 
							
									if p := manglers.load(); p != nil {
							 | 
						||
| 
								 | 
							
										b4 := len(b)
							 | 
						||
| 
								 | 
							
										for _, a := range a {
							 | 
						||
| 
								 | 
							
											t := xunsafe.TypeIterFrom(a)
							 | 
						||
| 
								 | 
							
											m := (*p)[t.TypeInfo]
							 | 
						||
| 
								 | 
							
											if m == nil {
							 | 
						||
| 
								 | 
							
												b = b[:b4]
							 | 
						||
| 
								 | 
							
												goto slow
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											b = m(b, xunsafe.UnpackEface(a))
							 | 
						||
| 
								 | 
							
											b = append(b, '.')
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return b
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								slow:
							 | 
						||
| 
								 | 
							
									for _, a := range a {
							 | 
						||
| 
								 | 
							
										b = Append(b, a)
							 | 
						||
| 
								 | 
							
										b = append(b, '.')
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return b
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// String will return the mangled format of input value 'a'. This
							 | 
						||
| 
								 | 
							
								// mangled output will be unique for all default supported input types
							 | 
						||
| 
								 | 
							
								// during a single runtime instance. Uniqueness cannot be guaranteed
							 | 
						||
| 
								 | 
							
								// between separate runtime instances (whether running concurrently, or
							 | 
						||
| 
								 | 
							
								// the same application running at different times).
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// The exact formatting of the output data should not be relied upon,
							 | 
						||
| 
								 | 
							
								// only that it is unique given the above constraints. Generally though,
							 | 
						||
| 
								 | 
							
								// the mangled output is the binary formatted text of given input data.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Uniqueness is guaranteed for similar input data of differing types
							 | 
						||
| 
								 | 
							
								// (e.g. string("hello world") vs. []byte("hello world")) by prefixing
							 | 
						||
| 
								 | 
							
								// mangled output with the input data's runtime type pointer.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Default supported types include all concrete (i.e. non-interface{})
							 | 
						||
| 
								 | 
							
								// data types, and interfaces implementing Mangleable{}.
							 | 
						||
| 
								 | 
							
								func String(a any) string {
							 | 
						||
| 
								 | 
							
									b := Append(make([]byte, 0, 32), a)
							 | 
						||
| 
								 | 
							
									return *(*string)(unsafe.Pointer(&b))
							 | 
						||
| 
								 | 
							
								}
							 |