/* Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments Copyright (C) ITsysCOM GmbH This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ package utils import ( "reflect" "strconv" "strings" ) // Converts map[string]string into map[string]interface{} func ConvertMapValStrIf(inMap map[string]string) map[string]interface{} { outMap := make(map[string]interface{}) for field, val := range inMap { outMap[field] = val } return outMap } // Mirrors key/val func MirrorMap(mapIn map[string]string) map[string]string { mapOut := make(map[string]string, len(mapIn)) for key, val := range mapIn { mapOut[val] = key } return mapOut } // Returns mising keys in a map func MissingMapKeys(inMap map[string]string, requiredKeys []string) []string { missingKeys := []string{} for _, reqKey := range requiredKeys { if val, hasKey := inMap[reqKey]; !hasKey || val == "" { missingKeys = append(missingKeys, reqKey) } } return missingKeys } // Return map keys func MapKeys(m map[string]string) []string { n := make([]string, len(m)) i := 0 for k := range m { n[i] = k i++ } return n } type StringMap map[string]bool func NewStringMap(s ...string) StringMap { result := make(StringMap) for _, v := range s { v = strings.TrimSpace(v) if v != "" { if strings.HasPrefix(v, "!") { result[v[1:]] = false } else { result[v] = true } } } return result } func ParseStringMap(s string) StringMap { if s == ZERO { return make(StringMap) } return StringMapFromSlice(strings.Split(s, INFIELD_SEP)) } func (sm StringMap) Equal(om StringMap) bool { if sm == nil && om != nil { return false } if len(sm) != len(om) { return false } for key := range sm { if !om[key] { return false } } return true } func (sm StringMap) Includes(om StringMap) bool { if len(sm) < len(om) { return false } for key := range om { if !sm[key] { return false } } return true } func (sm StringMap) Slice() []string { result := make([]string, len(sm)) i := 0 for k := range sm { result[i] = k i++ } return result } func (sm StringMap) IsEmpty() bool { return sm == nil || len(sm) == 0 || sm[ANY] == true } func StringMapFromSlice(s []string) StringMap { result := make(StringMap, len(s)) for _, v := range s { v = strings.TrimSpace(v) if v != "" { if strings.HasPrefix(v, "!") { result[v[1:]] = false } else { result[v] = true } } } return result } func (sm StringMap) Copy(o StringMap) { for k, v := range o { sm[k] = v } } func (sm StringMap) Clone() StringMap { result := make(StringMap, len(sm)) result.Copy(sm) return result } func (sm StringMap) String() string { return strings.Join(sm.Slice(), INFIELD_SEP) } func (sm StringMap) GetOne() string { for key := range sm { return key } return "" } func (sm StringMap) Join(mps ...StringMap) { for _, mp := range mps { for k, v := range mp { sm[k] = v } } } func (sm StringMap) HasKey(key string) (has bool) { _, has = sm[key] return } func (sm StringMap) GetSlice() (result []string) { result = make([]string, len(sm)) i := 0 for k := range sm { result[i] = k i += 1 } return } /* func NoDots(m map[string]struct{}) map[string]struct{} { return MapKeysReplace(m, ".", ".") } func YesDots(m map[string]struct{}) map[string]struct{} { return MapKeysReplace(m, ".", ".") } func MapKeysReplace(m map[string]struct{}, old, new string) map[string]struct{} { for key, val := range m { delete(m, key) key = strings.Replace(key, old, new, -1) m[key] = val } return m } */ // Used to merge multiple maps (eg: output of struct having ExtraFields) func MergeMapsStringIface(mps ...map[string]interface{}) (outMp map[string]interface{}) { outMp = make(map[string]interface{}) for i, mp := range mps { if i == 0 { outMp = mp continue } for k, v := range mp { outMp[k] = v } } return } // FieldMultiplyFactor defines multiply factors for different field values // original defined for CDRE component type FieldMultiplyFactor map[string]float64 func (fmp FieldMultiplyFactor) Clone() (cln FieldMultiplyFactor) { cln = make(FieldMultiplyFactor, len(fmp)) for k, v := range fmp { cln[k] = v } return } func MapStringToInt64(in map[string]string) (out map[string]int64, err error) { mapout := make(map[string]int64, len(in)) for key, val := range in { x, err := strconv.Atoi(val) if err != nil { return nil, err } mapout[key] = int64(x) } return mapout, nil } func FlagsWithParamsFromSlice(s []string) (FlagsWithParams, error) { result := make(FlagsWithParams, len(s)) for _, v := range s { subsystemWithIDs := strings.Split(v, InInFieldSep) result[subsystemWithIDs[0]] = []string{} if len(subsystemWithIDs) == 2 { result[subsystemWithIDs[0]] = strings.Split(subsystemWithIDs[1], INFIELD_SEP) } else if len(subsystemWithIDs) > 2 { return nil, ErrUnsupportedFormat } } return result, nil } type FlagsWithParams map[string]interface{} func (fWp FlagsWithParams) HasKey(key string) (has bool) { _, has = fWp[key] return } func (fWp FlagsWithParams) ParamsSlice(subs string) (ps []string) { if psIfc, has := fWp[subs]; has { ps, _ = psIfc.([]string) } return ps } //func to convert from FlagsWithParams back to []string func (fWp FlagsWithParams) SliceFlags() (sls []string) { for key, _ := range fWp { if prmSlice := fWp.ParamsSlice(key); !reflect.DeepEqual(prmSlice, []string{}) { sls = append(sls, ConcatenatedKey(key, strings.Join(prmSlice, INFIELD_SEP))) } else { sls = append(sls, key) } } return } // GetBool returns the flag as boolean func (fWp FlagsWithParams) GetBool(key string) (b bool) { var v interface{} if _, b = fWp[key]; !b { return // not present means false } if v.(string) != "" && v.(string) != "true" { return // not empty nor true means false again } return true }