mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	- Remove vendor'ed package go.pedge.io/pb/go/google/protobuf. - Update vendor'ed package github.com/libopenstorage/openstorage.
		
			
				
	
	
		
			113 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// deepcopy makes deep copies of things. A standard copy will copy the
 | 
						|
// pointers: deep copy copies the values pointed to.  Unexported field
 | 
						|
// values are not copied.
 | 
						|
//
 | 
						|
// Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved.
 | 
						|
// License: MIT, for more details check the included LICENSE file.
 | 
						|
package deepcopy
 | 
						|
 | 
						|
import (
 | 
						|
	"reflect"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
// Iface is an alias to Copy; this exists for backwards compatibility reasons.
 | 
						|
func Iface(iface interface{}) interface{} {
 | 
						|
	return Copy(iface)
 | 
						|
}
 | 
						|
 | 
						|
// Copy creates a deep copy of whatever is passed to it and returns the copy
 | 
						|
// in an interface{}.  The returned value will need to be asserted to the
 | 
						|
// correct type.
 | 
						|
func Copy(src interface{}) interface{} {
 | 
						|
	if src == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	// Make the interface a reflect.Value
 | 
						|
	original := reflect.ValueOf(src)
 | 
						|
 | 
						|
	// Make a copy of the same type as the original.
 | 
						|
	cpy := reflect.New(original.Type()).Elem()
 | 
						|
 | 
						|
	// Recursively copy the original.
 | 
						|
	copyRecursive(original, cpy)
 | 
						|
 | 
						|
	// Return the copy as an interface.
 | 
						|
	return cpy.Interface()
 | 
						|
}
 | 
						|
 | 
						|
// copyRecursive does the actual copying of the interface. It currently has
 | 
						|
// limited support for what it can handle. Add as needed.
 | 
						|
func copyRecursive(original, cpy reflect.Value) {
 | 
						|
	// handle according to original's Kind
 | 
						|
	switch original.Kind() {
 | 
						|
	case reflect.Ptr:
 | 
						|
		// Get the actual value being pointed to.
 | 
						|
		originalValue := original.Elem()
 | 
						|
 | 
						|
		// if  it isn't valid, return.
 | 
						|
		if !originalValue.IsValid() {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		cpy.Set(reflect.New(originalValue.Type()))
 | 
						|
		copyRecursive(originalValue, cpy.Elem())
 | 
						|
 | 
						|
	case reflect.Interface:
 | 
						|
		// If this is a nil, don't do anything
 | 
						|
		if original.IsNil() {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		// Get the value for the interface, not the pointer.
 | 
						|
		originalValue := original.Elem()
 | 
						|
 | 
						|
		// Get the value by calling Elem().
 | 
						|
		copyValue := reflect.New(originalValue.Type()).Elem()
 | 
						|
		copyRecursive(originalValue, copyValue)
 | 
						|
		cpy.Set(copyValue)
 | 
						|
 | 
						|
	case reflect.Struct:
 | 
						|
		t, ok := original.Interface().(time.Time)
 | 
						|
		if ok {
 | 
						|
			cpy.Set(reflect.ValueOf(t))
 | 
						|
			return
 | 
						|
		}
 | 
						|
		// Go through each field of the struct and copy it.
 | 
						|
		for i := 0; i < original.NumField(); i++ {
 | 
						|
			// The Type's StructField for a given field is checked to see if StructField.PkgPath
 | 
						|
			// is set to determine if the field is exported or not because CanSet() returns false
 | 
						|
			// for settable fields.  I'm not sure why.  -mohae
 | 
						|
			if original.Type().Field(i).PkgPath != "" {
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			copyRecursive(original.Field(i), cpy.Field(i))
 | 
						|
		}
 | 
						|
 | 
						|
	case reflect.Slice:
 | 
						|
		if original.IsNil() {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		// Make a new slice and copy each element.
 | 
						|
		cpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap()))
 | 
						|
		for i := 0; i < original.Len(); i++ {
 | 
						|
			copyRecursive(original.Index(i), cpy.Index(i))
 | 
						|
		}
 | 
						|
 | 
						|
	case reflect.Map:
 | 
						|
		if original.IsNil() {
 | 
						|
			return
 | 
						|
		}
 | 
						|
		cpy.Set(reflect.MakeMap(original.Type()))
 | 
						|
		for _, key := range original.MapKeys() {
 | 
						|
			originalValue := original.MapIndex(key)
 | 
						|
			copyValue := reflect.New(originalValue.Type()).Elem()
 | 
						|
			copyRecursive(originalValue, copyValue)
 | 
						|
			copyKey := Copy(key.Interface())
 | 
						|
			cpy.SetMapIndex(reflect.ValueOf(copyKey), copyValue)
 | 
						|
		}
 | 
						|
 | 
						|
	default:
 | 
						|
		cpy.Set(original)
 | 
						|
	}
 | 
						|
}
 |