github.com/Rookout/GoSDK@v0.1.48/pkg/processor/namespaces/value_namespace.go (about)

     1  package namespaces
     2  
     3  import (
     4  	"container/list"
     5  	"reflect"
     6  	"unsafe"
     7  
     8  	"github.com/Rookout/GoSDK/pkg/config"
     9  
    10  	"github.com/Rookout/GoSDK/pkg/rookoutErrors"
    11  )
    12  
    13  type ValueNamespace struct {
    14  	value          reflect.Value
    15  	ObjectDumpConf config.ObjectDumpConfig
    16  }
    17  
    18  func NewValueNamespace(value reflect.Value) *ValueNamespace {
    19  	g := &ValueNamespace{
    20  		value:          value,
    21  		ObjectDumpConf: config.GetDefaultDumpConfig(),
    22  	}
    23  
    24  	return g
    25  }
    26  
    27  func (v *ValueNamespace) GetSize(_ string, _ string) Namespace {
    28  	value := v.value
    29  	if value.Kind() == reflect.Ptr {
    30  		value = value.Elem()
    31  	}
    32  
    33  	switch value.Kind() {
    34  	case reflect.Array:
    35  		return NewGoObjectNamespace(value.Len())
    36  
    37  	case reflect.Map:
    38  		return NewGoObjectNamespace(len(value.MapKeys()))
    39  
    40  	default:
    41  
    42  		switch reflect.Zero(value.Type()).String() {
    43  		case "<*list.List Value>":
    44  			l := value.Interface().(*list.List)
    45  
    46  			return NewGoObjectNamespace(l.Len())
    47  		}
    48  	}
    49  	return nil
    50  }
    51  
    52  func (v *ValueNamespace) CallMethod(name string, args string) (n Namespace, err rookoutErrors.RookoutError) {
    53  	defer func() {
    54  		if recover() != nil {
    55  			n = NewGoObjectNamespace("nil")
    56  		}
    57  	}()
    58  
    59  	switch name {
    60  	case "type":
    61  		return NewGoObjectNamespace(v.value.Type().String()), nil
    62  	case "size":
    63  		size := v.GetSize(name, args)
    64  		if size == nil {
    65  			return nil, rookoutErrors.NewObjectHasNoSizeException(v.value.Type().String())
    66  		}
    67  		return size, nil
    68  
    69  	default:
    70  		return nil, rookoutErrors.NewRookMethodNotFound(name)
    71  	}
    72  }
    73  
    74  func (v *ValueNamespace) ReadAttribute(name string) (n Namespace, err rookoutErrors.RookoutError) {
    75  	value := v.value
    76  	for value.Kind() == reflect.Ptr || value.Kind() == reflect.Interface {
    77  		value = value.Elem()
    78  	}
    79  	_, ok := value.Type().FieldByName(name)
    80  	if !ok {
    81  		return nil, rookoutErrors.NewRookAttributeNotFoundException(name)
    82  	}
    83  
    84  	return NewValueNamespace(value.FieldByName(name)), nil
    85  }
    86  
    87  func (v *ValueNamespace) WriteAttribute(_ string, _ Namespace) rookoutErrors.RookoutError {
    88  	return rookoutErrors.NewNotImplemented()
    89  }
    90  
    91  func (v *ValueNamespace) ReadKey(key interface{}) (Namespace, rookoutErrors.RookoutError) {
    92  	value := v.value
    93  	for value.Kind() == reflect.Ptr {
    94  		value = value.Elem()
    95  	}
    96  
    97  	switch value.Kind() {
    98  	case reflect.Array:
    99  		return NewValueNamespace(value.Index(key.(int))), nil
   100  
   101  	case reflect.Map:
   102  		k := value.MapKeys()
   103  
   104  		for i := 0; i < len(k); i++ {
   105  			if key.(string) == k[i].String() {
   106  				return NewValueNamespace(value.MapIndex(k[i])), nil
   107  			}
   108  		}
   109  
   110  	case reflect.Struct:
   111  		return NewValueNamespace(value.FieldByName(key.(string))), nil
   112  
   113  	case reflect.Slice:
   114  		return NewValueNamespace(value.Index(key.(int))), nil
   115  	}
   116  
   117  	return nil, rookoutErrors.NewAgentKeyNotFoundException("", key, nil)
   118  }
   119  
   120  func (v *ValueNamespace) GetObject() (i interface{}) {
   121  	defer func() {
   122  		if recover() != nil {
   123  			if v.value.CanAddr() {
   124  				valueCopy := reflect.NewAt(v.value.Type(), unsafe.Pointer(v.value.UnsafeAddr()))
   125  				valueCopy = valueCopy.Elem()
   126  				i = valueCopy.Interface()
   127  			}
   128  		}
   129  	}()
   130  
   131  	return v.value.Interface()
   132  }
   133  
   134  func (v *ValueNamespace) Serialize(serializer Serializer) {
   135  	dumpValue(serializer, v.value, v.ObjectDumpConf)
   136  }
   137  
   138  func (v *ValueNamespace) GetObjectDumpConfig() config.ObjectDumpConfig {
   139  	return v.ObjectDumpConf
   140  }
   141  
   142  func (v *ValueNamespace) SetObjectDumpConfig(config config.ObjectDumpConfig) {
   143  	v.ObjectDumpConf = config
   144  }