mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	* Add a storage layer for attachments * Fix some bug * fix test * Fix copyright head and lint * Fix bug * Add setting for minio and flags for migrate-storage * Add documents * fix lint * Add test for minio store type on attachments * fix test * fix test * Apply suggestions from code review Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> * Add warning when storage migrated successfully * Fix drone * fix test * rebase * Fix test * display the error on console * Move minio test to amd64 since minio docker don't support arm64 * refactor the codes * add trace * Fix test * remove log on xorm * Fi download bug * Add a storage layer for attachments * Add setting for minio and flags for migrate-storage * fix lint * Add test for minio store type on attachments * Apply suggestions from code review Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> * Fix drone * fix test * Fix test * display the error on console * Move minio test to amd64 since minio docker don't support arm64 * refactor the codes * add trace * Fix test * Add URL function to serve attachments directly from S3/Minio * Add ability to enable/disable redirection in attachment configuration * Fix typo * Add a storage layer for attachments * Add setting for minio and flags for migrate-storage * fix lint * Add test for minio store type on attachments * Apply suggestions from code review Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> * Fix drone * fix test * Fix test * display the error on console * Move minio test to amd64 since minio docker don't support arm64 * don't change unrelated files * Fix lint * Fix build * update go.mod and go.sum * Use github.com/minio/minio-go/v6 * Remove unused function * Upgrade minio to v7 and some other improvements * fix lint * Fix go mod Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: Tyler <tystuyfzand@gmail.com>
		
			
				
	
	
		
			299 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			299 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package reflect2
 | |
| 
 | |
| import (
 | |
| 	"github.com/modern-go/concurrent"
 | |
| 	"reflect"
 | |
| 	"unsafe"
 | |
| )
 | |
| 
 | |
| type Type interface {
 | |
| 	Kind() reflect.Kind
 | |
| 	// New return pointer to data of this type
 | |
| 	New() interface{}
 | |
| 	// UnsafeNew return the allocated space pointed by unsafe.Pointer
 | |
| 	UnsafeNew() unsafe.Pointer
 | |
| 	// PackEFace cast a unsafe pointer to object represented pointer
 | |
| 	PackEFace(ptr unsafe.Pointer) interface{}
 | |
| 	// Indirect dereference object represented pointer to this type
 | |
| 	Indirect(obj interface{}) interface{}
 | |
| 	// UnsafeIndirect dereference pointer to this type
 | |
| 	UnsafeIndirect(ptr unsafe.Pointer) interface{}
 | |
| 	// Type1 returns reflect.Type
 | |
| 	Type1() reflect.Type
 | |
| 	Implements(thatType Type) bool
 | |
| 	String() string
 | |
| 	RType() uintptr
 | |
| 	// interface{} of this type has pointer like behavior
 | |
| 	LikePtr() bool
 | |
| 	IsNullable() bool
 | |
| 	IsNil(obj interface{}) bool
 | |
| 	UnsafeIsNil(ptr unsafe.Pointer) bool
 | |
| 	Set(obj interface{}, val interface{})
 | |
| 	UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer)
 | |
| 	AssignableTo(anotherType Type) bool
 | |
| }
 | |
| 
 | |
| type ListType interface {
 | |
| 	Type
 | |
| 	Elem() Type
 | |
| 	SetIndex(obj interface{}, index int, elem interface{})
 | |
| 	UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer)
 | |
| 	GetIndex(obj interface{}, index int) interface{}
 | |
| 	UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer
 | |
| }
 | |
| 
 | |
| type ArrayType interface {
 | |
| 	ListType
 | |
| 	Len() int
 | |
| }
 | |
| 
 | |
| type SliceType interface {
 | |
| 	ListType
 | |
| 	MakeSlice(length int, cap int) interface{}
 | |
| 	UnsafeMakeSlice(length int, cap int) unsafe.Pointer
 | |
| 	Grow(obj interface{}, newLength int)
 | |
| 	UnsafeGrow(ptr unsafe.Pointer, newLength int)
 | |
| 	Append(obj interface{}, elem interface{})
 | |
| 	UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer)
 | |
| 	LengthOf(obj interface{}) int
 | |
| 	UnsafeLengthOf(ptr unsafe.Pointer) int
 | |
| 	SetNil(obj interface{})
 | |
| 	UnsafeSetNil(ptr unsafe.Pointer)
 | |
| 	Cap(obj interface{}) int
 | |
| 	UnsafeCap(ptr unsafe.Pointer) int
 | |
| }
 | |
| 
 | |
| type StructType interface {
 | |
| 	Type
 | |
| 	NumField() int
 | |
| 	Field(i int) StructField
 | |
| 	FieldByName(name string) StructField
 | |
| 	FieldByIndex(index []int) StructField
 | |
| 	FieldByNameFunc(match func(string) bool) StructField
 | |
| }
 | |
| 
 | |
| type StructField interface {
 | |
| 	Offset() uintptr
 | |
| 	Name() string
 | |
| 	PkgPath() string
 | |
| 	Type() Type
 | |
| 	Tag() reflect.StructTag
 | |
| 	Index() []int
 | |
| 	Anonymous() bool
 | |
| 	Set(obj interface{}, value interface{})
 | |
| 	UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer)
 | |
| 	Get(obj interface{}) interface{}
 | |
| 	UnsafeGet(obj unsafe.Pointer) unsafe.Pointer
 | |
| }
 | |
| 
 | |
| type MapType interface {
 | |
| 	Type
 | |
| 	Key() Type
 | |
| 	Elem() Type
 | |
| 	MakeMap(cap int) interface{}
 | |
| 	UnsafeMakeMap(cap int) unsafe.Pointer
 | |
| 	SetIndex(obj interface{}, key interface{}, elem interface{})
 | |
| 	UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer)
 | |
| 	TryGetIndex(obj interface{}, key interface{}) (interface{}, bool)
 | |
| 	GetIndex(obj interface{}, key interface{}) interface{}
 | |
| 	UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
 | |
| 	Iterate(obj interface{}) MapIterator
 | |
| 	UnsafeIterate(obj unsafe.Pointer) MapIterator
 | |
| }
 | |
| 
 | |
| type MapIterator interface {
 | |
| 	HasNext() bool
 | |
| 	Next() (key interface{}, elem interface{})
 | |
| 	UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer)
 | |
| }
 | |
| 
 | |
| type PtrType interface {
 | |
| 	Type
 | |
| 	Elem() Type
 | |
| }
 | |
| 
 | |
| type InterfaceType interface {
 | |
| 	NumMethod() int
 | |
| }
 | |
| 
 | |
| type Config struct {
 | |
| 	UseSafeImplementation bool
 | |
| }
 | |
| 
 | |
| type API interface {
 | |
| 	TypeOf(obj interface{}) Type
 | |
| 	Type2(type1 reflect.Type) Type
 | |
| }
 | |
| 
 | |
| var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze()
 | |
| var ConfigSafe = Config{UseSafeImplementation: true}.Froze()
 | |
| 
 | |
| type frozenConfig struct {
 | |
| 	useSafeImplementation bool
 | |
| 	cache                 *concurrent.Map
 | |
| }
 | |
| 
 | |
| func (cfg Config) Froze() *frozenConfig {
 | |
| 	return &frozenConfig{
 | |
| 		useSafeImplementation: cfg.UseSafeImplementation,
 | |
| 		cache: concurrent.NewMap(),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
 | |
| 	cacheKey := uintptr(unpackEFace(obj).rtype)
 | |
| 	typeObj, found := cfg.cache.Load(cacheKey)
 | |
| 	if found {
 | |
| 		return typeObj.(Type)
 | |
| 	}
 | |
| 	return cfg.Type2(reflect.TypeOf(obj))
 | |
| }
 | |
| 
 | |
| func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
 | |
| 	if type1 == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	cacheKey := uintptr(unpackEFace(type1).data)
 | |
| 	typeObj, found := cfg.cache.Load(cacheKey)
 | |
| 	if found {
 | |
| 		return typeObj.(Type)
 | |
| 	}
 | |
| 	type2 := cfg.wrapType(type1)
 | |
| 	cfg.cache.Store(cacheKey, type2)
 | |
| 	return type2
 | |
| }
 | |
| 
 | |
| func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type {
 | |
| 	safeType := safeType{Type: type1, cfg: cfg}
 | |
| 	switch type1.Kind() {
 | |
| 	case reflect.Struct:
 | |
| 		if cfg.useSafeImplementation {
 | |
| 			return &safeStructType{safeType}
 | |
| 		}
 | |
| 		return newUnsafeStructType(cfg, type1)
 | |
| 	case reflect.Array:
 | |
| 		if cfg.useSafeImplementation {
 | |
| 			return &safeSliceType{safeType}
 | |
| 		}
 | |
| 		return newUnsafeArrayType(cfg, type1)
 | |
| 	case reflect.Slice:
 | |
| 		if cfg.useSafeImplementation {
 | |
| 			return &safeSliceType{safeType}
 | |
| 		}
 | |
| 		return newUnsafeSliceType(cfg, type1)
 | |
| 	case reflect.Map:
 | |
| 		if cfg.useSafeImplementation {
 | |
| 			return &safeMapType{safeType}
 | |
| 		}
 | |
| 		return newUnsafeMapType(cfg, type1)
 | |
| 	case reflect.Ptr, reflect.Chan, reflect.Func:
 | |
| 		if cfg.useSafeImplementation {
 | |
| 			return &safeMapType{safeType}
 | |
| 		}
 | |
| 		return newUnsafePtrType(cfg, type1)
 | |
| 	case reflect.Interface:
 | |
| 		if cfg.useSafeImplementation {
 | |
| 			return &safeMapType{safeType}
 | |
| 		}
 | |
| 		if type1.NumMethod() == 0 {
 | |
| 			return newUnsafeEFaceType(cfg, type1)
 | |
| 		}
 | |
| 		return newUnsafeIFaceType(cfg, type1)
 | |
| 	default:
 | |
| 		if cfg.useSafeImplementation {
 | |
| 			return &safeType
 | |
| 		}
 | |
| 		return newUnsafeType(cfg, type1)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TypeOf(obj interface{}) Type {
 | |
| 	return ConfigUnsafe.TypeOf(obj)
 | |
| }
 | |
| 
 | |
| func TypeOfPtr(obj interface{}) PtrType {
 | |
| 	return TypeOf(obj).(PtrType)
 | |
| }
 | |
| 
 | |
| func Type2(type1 reflect.Type) Type {
 | |
| 	if type1 == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 	return ConfigUnsafe.Type2(type1)
 | |
| }
 | |
| 
 | |
| func PtrTo(typ Type) Type {
 | |
| 	return Type2(reflect.PtrTo(typ.Type1()))
 | |
| }
 | |
| 
 | |
| func PtrOf(obj interface{}) unsafe.Pointer {
 | |
| 	return unpackEFace(obj).data
 | |
| }
 | |
| 
 | |
| func RTypeOf(obj interface{}) uintptr {
 | |
| 	return uintptr(unpackEFace(obj).rtype)
 | |
| }
 | |
| 
 | |
| func IsNil(obj interface{}) bool {
 | |
| 	if obj == nil {
 | |
| 		return true
 | |
| 	}
 | |
| 	return unpackEFace(obj).data == nil
 | |
| }
 | |
| 
 | |
| func IsNullable(kind reflect.Kind) bool {
 | |
| 	switch kind {
 | |
| 	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface:
 | |
| 		return true
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| func likePtrKind(kind reflect.Kind) bool {
 | |
| 	switch kind {
 | |
| 	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func:
 | |
| 		return true
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| func likePtrType(typ reflect.Type) bool {
 | |
| 	if likePtrKind(typ.Kind()) {
 | |
| 		return true
 | |
| 	}
 | |
| 	if typ.Kind() == reflect.Struct {
 | |
| 		if typ.NumField() != 1 {
 | |
| 			return false
 | |
| 		}
 | |
| 		return likePtrType(typ.Field(0).Type)
 | |
| 	}
 | |
| 	if typ.Kind() == reflect.Array {
 | |
| 		if typ.Len() != 1 {
 | |
| 			return false
 | |
| 		}
 | |
| 		return likePtrType(typ.Elem())
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| // NoEscape hides a pointer from escape analysis.  noescape is
 | |
| // the identity function but escape analysis doesn't think the
 | |
| // output depends on the input.  noescape is inlined and currently
 | |
| // compiles down to zero instructions.
 | |
| // USE CAREFULLY!
 | |
| //go:nosplit
 | |
| func NoEscape(p unsafe.Pointer) unsafe.Pointer {
 | |
| 	x := uintptr(p)
 | |
| 	return unsafe.Pointer(x ^ 0)
 | |
| }
 | |
| 
 | |
| func UnsafeCastString(str string) []byte {
 | |
| 	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
 | |
| 	sliceHeader := &reflect.SliceHeader{
 | |
| 		Data: stringHeader.Data,
 | |
| 		Cap: stringHeader.Len,
 | |
| 		Len: stringHeader.Len,
 | |
| 	}
 | |
| 	return *(*[]byte)(unsafe.Pointer(sliceHeader))
 | |
| }
 |