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 }