Path: blob/dev/pkg/utils/insertion_ordered_map.go
2070 views
package utils12import (3"fmt"4"strconv"56"github.com/projectdiscovery/nuclei/v3/pkg/utils/json"7"gopkg.in/yaml.v2"8)910type InsertionOrderedStringMap struct {11keys []string `yaml:"-"`12values map[string]interface{}13}1415func NewEmptyInsertionOrderedStringMap(size int) *InsertionOrderedStringMap {16return &InsertionOrderedStringMap{17keys: make([]string, 0, size),18values: make(map[string]interface{}, size),19}20}2122func NewInsertionOrderedStringMap(stringMap map[string]interface{}) *InsertionOrderedStringMap {23result := NewEmptyInsertionOrderedStringMap(len(stringMap))2425for k, v := range stringMap {26result.Set(k, v)27}28return result29}3031func (insertionOrderedStringMap *InsertionOrderedStringMap) Len() int {32return len(insertionOrderedStringMap.values)33}3435func (insertionOrderedStringMap *InsertionOrderedStringMap) UnmarshalYAML(unmarshal func(interface{}) error) error {36var data yaml.MapSlice37if err := unmarshal(&data); err != nil {38return err39}40insertionOrderedStringMap.values = make(map[string]interface{})41for _, v := range data {42if v.Key == nil {43continue44}45insertionOrderedStringMap.Set(v.Key.(string), toString(v.Value))46}47return nil48}4950func (insertionOrderedStringMap *InsertionOrderedStringMap) UnmarshalJSON(data []byte) error {51var dataMap map[string]interface{}52if err := json.Unmarshal(data, &dataMap); err != nil {53return err54}55insertionOrderedStringMap.values = make(map[string]interface{})56for k, v := range dataMap {57insertionOrderedStringMap.Set(k, toString(v))58}59return nil60}6162// toString converts an interface to string in a quick way63func toString(data interface{}) interface{} {64switch s := data.(type) {65case nil:66return ""67case string:68return s69case bool:70return strconv.FormatBool(s)71case float64:72return strconv.FormatFloat(s, 'f', -1, 64)73case float32:74return strconv.FormatFloat(float64(s), 'f', -1, 32)75case int:76return strconv.Itoa(s)77case int64:78return strconv.FormatInt(s, 10)79case int32:80return strconv.Itoa(int(s))81case int16:82return strconv.FormatInt(int64(s), 10)83case int8:84return strconv.FormatInt(int64(s), 10)85case uint:86return strconv.FormatUint(uint64(s), 10)87case uint64:88return strconv.FormatUint(s, 10)89case uint32:90return strconv.FormatUint(uint64(s), 10)91case uint16:92return strconv.FormatUint(uint64(s), 10)93case uint8:94return strconv.FormatUint(uint64(s), 10)95case []byte:96return string(s)97case []interface{}:98return data99default:100return fmt.Sprintf("%v", data)101}102}103104func (insertionOrderedStringMap *InsertionOrderedStringMap) ForEach(fn func(key string, data interface{})) {105for _, key := range insertionOrderedStringMap.keys {106fn(key, insertionOrderedStringMap.values[key])107}108}109110func (insertionOrderedStringMap *InsertionOrderedStringMap) Set(key string, value interface{}) {111_, present := insertionOrderedStringMap.values[key]112insertionOrderedStringMap.values[key] = value113if !present {114insertionOrderedStringMap.keys = append(insertionOrderedStringMap.keys, key)115}116}117118119