Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/utils/insertion_ordered_map.go
2070 views
1
package utils
2
3
import (
4
"fmt"
5
"strconv"
6
7
"github.com/projectdiscovery/nuclei/v3/pkg/utils/json"
8
"gopkg.in/yaml.v2"
9
)
10
11
type InsertionOrderedStringMap struct {
12
keys []string `yaml:"-"`
13
values map[string]interface{}
14
}
15
16
func NewEmptyInsertionOrderedStringMap(size int) *InsertionOrderedStringMap {
17
return &InsertionOrderedStringMap{
18
keys: make([]string, 0, size),
19
values: make(map[string]interface{}, size),
20
}
21
}
22
23
func NewInsertionOrderedStringMap(stringMap map[string]interface{}) *InsertionOrderedStringMap {
24
result := NewEmptyInsertionOrderedStringMap(len(stringMap))
25
26
for k, v := range stringMap {
27
result.Set(k, v)
28
}
29
return result
30
}
31
32
func (insertionOrderedStringMap *InsertionOrderedStringMap) Len() int {
33
return len(insertionOrderedStringMap.values)
34
}
35
36
func (insertionOrderedStringMap *InsertionOrderedStringMap) UnmarshalYAML(unmarshal func(interface{}) error) error {
37
var data yaml.MapSlice
38
if err := unmarshal(&data); err != nil {
39
return err
40
}
41
insertionOrderedStringMap.values = make(map[string]interface{})
42
for _, v := range data {
43
if v.Key == nil {
44
continue
45
}
46
insertionOrderedStringMap.Set(v.Key.(string), toString(v.Value))
47
}
48
return nil
49
}
50
51
func (insertionOrderedStringMap *InsertionOrderedStringMap) UnmarshalJSON(data []byte) error {
52
var dataMap map[string]interface{}
53
if err := json.Unmarshal(data, &dataMap); err != nil {
54
return err
55
}
56
insertionOrderedStringMap.values = make(map[string]interface{})
57
for k, v := range dataMap {
58
insertionOrderedStringMap.Set(k, toString(v))
59
}
60
return nil
61
}
62
63
// toString converts an interface to string in a quick way
64
func toString(data interface{}) interface{} {
65
switch s := data.(type) {
66
case nil:
67
return ""
68
case string:
69
return s
70
case bool:
71
return strconv.FormatBool(s)
72
case float64:
73
return strconv.FormatFloat(s, 'f', -1, 64)
74
case float32:
75
return strconv.FormatFloat(float64(s), 'f', -1, 32)
76
case int:
77
return strconv.Itoa(s)
78
case int64:
79
return strconv.FormatInt(s, 10)
80
case int32:
81
return strconv.Itoa(int(s))
82
case int16:
83
return strconv.FormatInt(int64(s), 10)
84
case int8:
85
return strconv.FormatInt(int64(s), 10)
86
case uint:
87
return strconv.FormatUint(uint64(s), 10)
88
case uint64:
89
return strconv.FormatUint(s, 10)
90
case uint32:
91
return strconv.FormatUint(uint64(s), 10)
92
case uint16:
93
return strconv.FormatUint(uint64(s), 10)
94
case uint8:
95
return strconv.FormatUint(uint64(s), 10)
96
case []byte:
97
return string(s)
98
case []interface{}:
99
return data
100
default:
101
return fmt.Sprintf("%v", data)
102
}
103
}
104
105
func (insertionOrderedStringMap *InsertionOrderedStringMap) ForEach(fn func(key string, data interface{})) {
106
for _, key := range insertionOrderedStringMap.keys {
107
fn(key, insertionOrderedStringMap.values[key])
108
}
109
}
110
111
func (insertionOrderedStringMap *InsertionOrderedStringMap) Set(key string, value interface{}) {
112
_, present := insertionOrderedStringMap.values[key]
113
insertionOrderedStringMap.values[key] = value
114
if !present {
115
insertionOrderedStringMap.keys = append(insertionOrderedStringMap.keys, key)
116
}
117
}
118
119