mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00: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>
		
			
				
	
	
		
			212 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
package jsoniter
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"github.com/modern-go/reflect2"
 | 
						|
	"io"
 | 
						|
	"reflect"
 | 
						|
	"unsafe"
 | 
						|
)
 | 
						|
 | 
						|
func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
 | 
						|
	type bindingTo struct {
 | 
						|
		binding *Binding
 | 
						|
		toName  string
 | 
						|
		ignored bool
 | 
						|
	}
 | 
						|
	orderedBindings := []*bindingTo{}
 | 
						|
	structDescriptor := describeStruct(ctx, typ)
 | 
						|
	for _, binding := range structDescriptor.Fields {
 | 
						|
		for _, toName := range binding.ToNames {
 | 
						|
			new := &bindingTo{
 | 
						|
				binding: binding,
 | 
						|
				toName:  toName,
 | 
						|
			}
 | 
						|
			for _, old := range orderedBindings {
 | 
						|
				if old.toName != toName {
 | 
						|
					continue
 | 
						|
				}
 | 
						|
				old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding)
 | 
						|
			}
 | 
						|
			orderedBindings = append(orderedBindings, new)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	if len(orderedBindings) == 0 {
 | 
						|
		return &emptyStructEncoder{}
 | 
						|
	}
 | 
						|
	finalOrderedFields := []structFieldTo{}
 | 
						|
	for _, bindingTo := range orderedBindings {
 | 
						|
		if !bindingTo.ignored {
 | 
						|
			finalOrderedFields = append(finalOrderedFields, structFieldTo{
 | 
						|
				encoder: bindingTo.binding.Encoder.(*structFieldEncoder),
 | 
						|
				toName:  bindingTo.toName,
 | 
						|
			})
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return &structEncoder{typ, finalOrderedFields}
 | 
						|
}
 | 
						|
 | 
						|
func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty {
 | 
						|
	encoder := createEncoderOfNative(ctx, typ)
 | 
						|
	if encoder != nil {
 | 
						|
		return encoder
 | 
						|
	}
 | 
						|
	kind := typ.Kind()
 | 
						|
	switch kind {
 | 
						|
	case reflect.Interface:
 | 
						|
		return &dynamicEncoder{typ}
 | 
						|
	case reflect.Struct:
 | 
						|
		return &structEncoder{typ: typ}
 | 
						|
	case reflect.Array:
 | 
						|
		return &arrayEncoder{}
 | 
						|
	case reflect.Slice:
 | 
						|
		return &sliceEncoder{}
 | 
						|
	case reflect.Map:
 | 
						|
		return encoderOfMap(ctx, typ)
 | 
						|
	case reflect.Ptr:
 | 
						|
		return &OptionalEncoder{}
 | 
						|
	default:
 | 
						|
		return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
 | 
						|
	newTagged := new.Field.Tag().Get(cfg.getTagKey()) != ""
 | 
						|
	oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != ""
 | 
						|
	if newTagged {
 | 
						|
		if oldTagged {
 | 
						|
			if len(old.levels) > len(new.levels) {
 | 
						|
				return true, false
 | 
						|
			} else if len(new.levels) > len(old.levels) {
 | 
						|
				return false, true
 | 
						|
			} else {
 | 
						|
				return true, true
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			return true, false
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		if oldTagged {
 | 
						|
			return true, false
 | 
						|
		}
 | 
						|
		if len(old.levels) > len(new.levels) {
 | 
						|
			return true, false
 | 
						|
		} else if len(new.levels) > len(old.levels) {
 | 
						|
			return false, true
 | 
						|
		} else {
 | 
						|
			return true, true
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type structFieldEncoder struct {
 | 
						|
	field        reflect2.StructField
 | 
						|
	fieldEncoder ValEncoder
 | 
						|
	omitempty    bool
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 | 
						|
	fieldPtr := encoder.field.UnsafeGet(ptr)
 | 
						|
	encoder.fieldEncoder.Encode(fieldPtr, stream)
 | 
						|
	if stream.Error != nil && stream.Error != io.EOF {
 | 
						|
		stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 | 
						|
	fieldPtr := encoder.field.UnsafeGet(ptr)
 | 
						|
	return encoder.fieldEncoder.IsEmpty(fieldPtr)
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
 | 
						|
	isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil)
 | 
						|
	if !converted {
 | 
						|
		return false
 | 
						|
	}
 | 
						|
	fieldPtr := encoder.field.UnsafeGet(ptr)
 | 
						|
	return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
 | 
						|
}
 | 
						|
 | 
						|
type IsEmbeddedPtrNil interface {
 | 
						|
	IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
 | 
						|
}
 | 
						|
 | 
						|
type structEncoder struct {
 | 
						|
	typ    reflect2.Type
 | 
						|
	fields []structFieldTo
 | 
						|
}
 | 
						|
 | 
						|
type structFieldTo struct {
 | 
						|
	encoder *structFieldEncoder
 | 
						|
	toName  string
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 | 
						|
	stream.WriteObjectStart()
 | 
						|
	isNotFirst := false
 | 
						|
	for _, field := range encoder.fields {
 | 
						|
		if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		if field.encoder.IsEmbeddedPtrNil(ptr) {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		if isNotFirst {
 | 
						|
			stream.WriteMore()
 | 
						|
		}
 | 
						|
		stream.WriteObjectField(field.toName)
 | 
						|
		field.encoder.Encode(ptr, stream)
 | 
						|
		isNotFirst = true
 | 
						|
	}
 | 
						|
	stream.WriteObjectEnd()
 | 
						|
	if stream.Error != nil && stream.Error != io.EOF {
 | 
						|
		stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *structEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
type emptyStructEncoder struct {
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 | 
						|
	stream.WriteEmptyObject()
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
type stringModeNumberEncoder struct {
 | 
						|
	elemEncoder ValEncoder
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 | 
						|
	stream.writeByte('"')
 | 
						|
	encoder.elemEncoder.Encode(ptr, stream)
 | 
						|
	stream.writeByte('"')
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 | 
						|
	return encoder.elemEncoder.IsEmpty(ptr)
 | 
						|
}
 | 
						|
 | 
						|
type stringModeStringEncoder struct {
 | 
						|
	elemEncoder ValEncoder
 | 
						|
	cfg         *frozenConfig
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 | 
						|
	tempStream := encoder.cfg.BorrowStream(nil)
 | 
						|
	tempStream.Attachment = stream.Attachment
 | 
						|
	defer encoder.cfg.ReturnStream(tempStream)
 | 
						|
	encoder.elemEncoder.Encode(ptr, tempStream)
 | 
						|
	stream.WriteString(string(tempStream.Buffer()))
 | 
						|
}
 | 
						|
 | 
						|
func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 | 
						|
	return encoder.elemEncoder.IsEmpty(ptr)
 | 
						|
}
 |