github.com/timstclair/heapster@v0.20.0-alpha1/Godeps/_workspace/src/k8s.io/kubernetes/pkg/conversion/cloner.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors All rights reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package conversion
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  )
    23  
    24  // Cloner knows how to copy one type to another.
    25  type Cloner struct {
    26  	// Map from the type to a function which can do the deep copy.
    27  	deepCopyFuncs          map[reflect.Type]reflect.Value
    28  	generatedDeepCopyFuncs map[reflect.Type]reflect.Value
    29  }
    30  
    31  // NewCloner creates a new Cloner object.
    32  func NewCloner() *Cloner {
    33  	c := &Cloner{
    34  		deepCopyFuncs:          map[reflect.Type]reflect.Value{},
    35  		generatedDeepCopyFuncs: map[reflect.Type]reflect.Value{},
    36  	}
    37  	if err := c.RegisterDeepCopyFunc(byteSliceDeepCopy); err != nil {
    38  		// If one of the deep-copy functions is malformed, detect it immediately.
    39  		panic(err)
    40  	}
    41  	return c
    42  }
    43  
    44  // Prevent recursing into every byte...
    45  func byteSliceDeepCopy(in []byte, out *[]byte, c *Cloner) error {
    46  	if in != nil {
    47  		*out = make([]byte, len(in))
    48  		copy(*out, in)
    49  	} else {
    50  		*out = nil
    51  	}
    52  	return nil
    53  }
    54  
    55  // Verifies whether a deep-copy function has a correct signature.
    56  func verifyDeepCopyFunctionSignature(ft reflect.Type) error {
    57  	if ft.Kind() != reflect.Func {
    58  		return fmt.Errorf("expected func, got: %v", ft)
    59  	}
    60  	if ft.NumIn() != 3 {
    61  		return fmt.Errorf("expected three 'in' params, got %v", ft)
    62  	}
    63  	if ft.NumOut() != 1 {
    64  		return fmt.Errorf("expected one 'out' param, got %v", ft)
    65  	}
    66  	if ft.In(1).Kind() != reflect.Ptr {
    67  		return fmt.Errorf("expected pointer arg for 'in' param 1, got: %v", ft)
    68  	}
    69  	if ft.In(1).Elem() != ft.In(0) {
    70  		return fmt.Errorf("expected 'in' param 0 the same as param 1, got: %v", ft)
    71  	}
    72  	var forClonerType Cloner
    73  	if expected := reflect.TypeOf(&forClonerType); ft.In(2) != expected {
    74  		return fmt.Errorf("expected '%v' arg for 'in' param 2, got: '%v'", expected, ft.In(2))
    75  	}
    76  	var forErrorType error
    77  	// This convolution is necessary, otherwise TypeOf picks up on the fact
    78  	// that forErrorType is nil
    79  	errorType := reflect.TypeOf(&forErrorType).Elem()
    80  	if ft.Out(0) != errorType {
    81  		return fmt.Errorf("expected error return, got: %v", ft)
    82  	}
    83  	return nil
    84  }
    85  
    86  // RegisterGeneratedDeepCopyFunc registers a copying func with the Cloner.
    87  // deepCopyFunc must take three parameters: a type input, a pointer to a
    88  // type output, and a pointer to Cloner. It should return an error.
    89  //
    90  // Example:
    91  // c.RegisterGeneratedDeepCopyFunc(
    92  //         func(in Pod, out *Pod, c *Cloner) error {
    93  //                 // deep copy logic...
    94  //                 return nil
    95  //          })
    96  func (c *Cloner) RegisterDeepCopyFunc(deepCopyFunc interface{}) error {
    97  	fv := reflect.ValueOf(deepCopyFunc)
    98  	ft := fv.Type()
    99  	if err := verifyDeepCopyFunctionSignature(ft); err != nil {
   100  		return err
   101  	}
   102  	c.deepCopyFuncs[ft.In(0)] = fv
   103  	return nil
   104  }
   105  
   106  // Similar to RegisterDeepCopyFunc, but registers deep copy function that were
   107  // automatically generated.
   108  func (c *Cloner) RegisterGeneratedDeepCopyFunc(deepCopyFunc interface{}) error {
   109  	fv := reflect.ValueOf(deepCopyFunc)
   110  	ft := fv.Type()
   111  	if err := verifyDeepCopyFunctionSignature(ft); err != nil {
   112  		return err
   113  	}
   114  	c.generatedDeepCopyFuncs[ft.In(0)] = fv
   115  	return nil
   116  }
   117  
   118  // DeepCopy will perform a deep copy of a given object.
   119  func (c *Cloner) DeepCopy(in interface{}) (interface{}, error) {
   120  	// Can be invalid if we run DeepCopy(X) where X is a nil interface type.
   121  	// For example, we get an invalid value when someone tries to deep-copy
   122  	// a nil labels.Selector.
   123  	// This does not occur if X is nil and is a pointer to a concrete type.
   124  	if in == nil {
   125  		return nil, nil
   126  	}
   127  	inValue := reflect.ValueOf(in)
   128  	outValue, err := c.deepCopy(inValue)
   129  	if err != nil {
   130  		return nil, err
   131  	}
   132  	return outValue.Interface(), nil
   133  }
   134  
   135  func (c *Cloner) deepCopy(src reflect.Value) (reflect.Value, error) {
   136  	inType := src.Type()
   137  
   138  	if fv, ok := c.deepCopyFuncs[inType]; ok {
   139  		return c.customDeepCopy(src, fv)
   140  	}
   141  	if fv, ok := c.generatedDeepCopyFuncs[inType]; ok {
   142  		return c.customDeepCopy(src, fv)
   143  	}
   144  	return c.defaultDeepCopy(src)
   145  }
   146  
   147  func (c *Cloner) customDeepCopy(src, fv reflect.Value) (reflect.Value, error) {
   148  	outValue := reflect.New(src.Type())
   149  	args := []reflect.Value{src, outValue, reflect.ValueOf(c)}
   150  	result := fv.Call(args)[0].Interface()
   151  	// This convolution is necessary because nil interfaces won't convert
   152  	// to error.
   153  	if result == nil {
   154  		return outValue.Elem(), nil
   155  	}
   156  	return outValue.Elem(), result.(error)
   157  }
   158  
   159  func (c *Cloner) defaultDeepCopy(src reflect.Value) (reflect.Value, error) {
   160  	switch src.Kind() {
   161  	case reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Uintptr:
   162  		return src, fmt.Errorf("cannot deep copy kind: %s", src.Kind())
   163  	case reflect.Array:
   164  		dst := reflect.New(src.Type())
   165  		for i := 0; i < src.Len(); i++ {
   166  			copyVal, err := c.deepCopy(src.Index(i))
   167  			if err != nil {
   168  				return src, err
   169  			}
   170  			dst.Elem().Index(i).Set(copyVal)
   171  		}
   172  		return dst.Elem(), nil
   173  	case reflect.Interface:
   174  		if src.IsNil() {
   175  			return src, nil
   176  		}
   177  		return c.deepCopy(src.Elem())
   178  	case reflect.Map:
   179  		if src.IsNil() {
   180  			return src, nil
   181  		}
   182  		dst := reflect.MakeMap(src.Type())
   183  		for _, k := range src.MapKeys() {
   184  			copyVal, err := c.deepCopy(src.MapIndex(k))
   185  			if err != nil {
   186  				return src, err
   187  			}
   188  			dst.SetMapIndex(k, copyVal)
   189  		}
   190  		return dst, nil
   191  	case reflect.Ptr:
   192  		if src.IsNil() {
   193  			return src, nil
   194  		}
   195  		dst := reflect.New(src.Type().Elem())
   196  		copyVal, err := c.deepCopy(src.Elem())
   197  		if err != nil {
   198  			return src, err
   199  		}
   200  		dst.Elem().Set(copyVal)
   201  		return dst, nil
   202  	case reflect.Slice:
   203  		if src.IsNil() {
   204  			return src, nil
   205  		}
   206  		dst := reflect.MakeSlice(src.Type(), 0, src.Len())
   207  		for i := 0; i < src.Len(); i++ {
   208  			copyVal, err := c.deepCopy(src.Index(i))
   209  			if err != nil {
   210  				return src, err
   211  			}
   212  			dst = reflect.Append(dst, copyVal)
   213  		}
   214  		return dst, nil
   215  	case reflect.Struct:
   216  		dst := reflect.New(src.Type())
   217  		for i := 0; i < src.NumField(); i++ {
   218  			if !dst.Elem().Field(i).CanSet() {
   219  				// Can't set private fields. At this point, the
   220  				// best we can do is a shallow copy. For
   221  				// example, time.Time is a value type with
   222  				// private members that can be shallow copied.
   223  				return src, nil
   224  			}
   225  			copyVal, err := c.deepCopy(src.Field(i))
   226  			if err != nil {
   227  				return src, err
   228  			}
   229  			dst.Elem().Field(i).Set(copyVal)
   230  		}
   231  		return dst.Elem(), nil
   232  
   233  	default:
   234  		// Value types like numbers, booleans, and strings.
   235  		return src, nil
   236  	}
   237  }