github.com/cs3org/reva/v2@v2.27.7/pkg/appctx/ctxmap.go (about) 1 // Copyright 2018-2021 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package appctx 20 21 import ( 22 "context" 23 "reflect" 24 "unsafe" 25 ) 26 27 // PutKeyValuesToCtx puts all the key-value pairs from the provided map to a background context. 28 func PutKeyValuesToCtx(m map[interface{}]interface{}) context.Context { 29 ctx := context.Background() 30 for key, value := range m { 31 ctx = context.WithValue(ctx, key, value) 32 } 33 return ctx 34 } 35 36 // GetKeyValuesFromCtx retrieves all the key-value pairs from the provided context. 37 func GetKeyValuesFromCtx(ctx context.Context) map[interface{}]interface{} { 38 m := make(map[interface{}]interface{}) 39 getKeyValue(ctx, m) 40 return m 41 } 42 43 func getKeyValue(ctx interface{}, m map[interface{}]interface{}) { 44 // This is a dirty hack to run with go 1.21.x 45 reflectCtxValues := reflect.ValueOf(ctx) 46 if reflectCtxValues.Kind() != reflect.Struct { 47 ctxVals := reflectCtxValues.Elem() 48 ctxType := reflect.TypeOf(ctx).Elem() 49 50 if ctxType.Kind() == reflect.Struct { 51 for i := 0; i < ctxVals.NumField(); i++ { 52 currField, currIf := extractField(ctxVals, ctxType, i) 53 switch currField { 54 case "Context": 55 getKeyValue(currIf, m) 56 case "key": 57 nextField, nextIf := extractField(ctxVals, ctxType, i+1) 58 if nextField == "val" { 59 m[currIf] = nextIf 60 i++ 61 } 62 } 63 } 64 } 65 } 66 } 67 68 func extractField(vals reflect.Value, fieldType reflect.Type, pos int) (string, interface{}) { 69 currVal := vals.Field(pos) 70 currVal = reflect.NewAt(currVal.Type(), unsafe.Pointer(currVal.UnsafeAddr())).Elem() 71 currField := fieldType.Field(pos) 72 return currField.Name, currVal.Interface() 73 }