Files
cgrates/utils/map.go

303 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
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 <http://www.gnu.org/licenses/>
*/
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
}