collection.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. package fp
  2. import (
  3. "bytes"
  4. "fmt"
  5. "sort"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "golang.org/x/tools/container/intsets"
  10. )
  11. // IntList is a list of integers
  12. type IntList []int
  13. // IntSet is a set of integers
  14. type IntSet struct {
  15. intsets.Sparse
  16. sync.RWMutex
  17. }
  18. // NewIntList returns a string list parsed from a string.
  19. func NewIntList(s string) (IntList, error) {
  20. var a IntList
  21. err := a.Parse(s)
  22. return a, err
  23. }
  24. // Parse an int list from a string and return an error on failure
  25. func (a *IntList) Parse(s string) error {
  26. *a = nil
  27. var split []string
  28. if len(s) > 0 {
  29. split = strings.Split(s, ",")
  30. }
  31. for _, v := range split {
  32. if len(v) == 0 {
  33. return fmt.Errorf("invalid int list format: '%s'", s)
  34. }
  35. elem64bit, err := strconv.ParseUint(v, 16, 16)
  36. elem := int(elem64bit)
  37. if err != nil {
  38. return err
  39. }
  40. *a = append(*a, elem)
  41. }
  42. return nil
  43. }
  44. // String returns a comma-separated string of list elements
  45. func (a *IntList) String() string {
  46. var buf bytes.Buffer
  47. for idx, elem := range *a {
  48. if idx != 0 {
  49. buf.WriteString(",")
  50. }
  51. buf.WriteString(fmt.Sprintf("%x", elem))
  52. }
  53. return buf.String()
  54. }
  55. // Contains returns true if b is an ordered subsequence of a
  56. func (a IntList) Contains(b IntList) bool {
  57. bIdx := 0
  58. bLen := len(b)
  59. if bLen == 0 {
  60. return true
  61. }
  62. for _, elem := range a {
  63. if elem == b[bIdx] {
  64. bIdx++
  65. if bIdx == bLen {
  66. return true
  67. }
  68. }
  69. }
  70. return false
  71. }
  72. // Equals returns true if a and b are equal
  73. func (a IntList) Equals(b IntList) bool {
  74. if len(a) != len(b) {
  75. return false
  76. }
  77. for idx := range a {
  78. if a[idx] != b[idx] {
  79. return false
  80. }
  81. }
  82. return true
  83. }
  84. // Set returns a set representation of a list
  85. func (a IntList) Set() *IntSet {
  86. var set IntSet
  87. for _, elem := range a {
  88. set.Insert(elem)
  89. }
  90. return &set
  91. }
  92. /*
  93. * intset.Sparse is NOT thread-safe, so we must add locking for mitmengine's processor.Check() function
  94. * to be run concurrently.
  95. */
  96. // String stringifies an IntSet
  97. func (a *IntSet) String() string {
  98. str := ""
  99. if a != nil {
  100. a.RLock()
  101. // Make sure to call Sparse version of String()
  102. str = a.Sparse.String()
  103. a.RUnlock()
  104. }
  105. return str
  106. }
  107. // Len returns the length of an IntSet.
  108. func (a *IntSet) Len() int {
  109. len := 0
  110. if a != nil {
  111. a.RLock()
  112. // Make sure to call Sparse implementation of Len()
  113. len = a.Sparse.Len()
  114. a.RUnlock()
  115. }
  116. return len
  117. }
  118. // Inserts the given element into the IntSet.
  119. func (a *IntSet) Insert(elem int) {
  120. if a != nil {
  121. a.RLock()
  122. a.Sparse.Insert(elem)
  123. a.RUnlock()
  124. }
  125. }
  126. // IsEmpty a bool indicating whether two intsets are equal or not
  127. func (a *IntSet) Equal(b *IntSet) bool {
  128. var equal bool
  129. if a != nil && b != nil {
  130. a.RLock()
  131. b.RLock()
  132. equal = a.Sparse.Equals(&b.Sparse)
  133. b.RUnlock()
  134. a.RUnlock()
  135. }
  136. return equal
  137. }
  138. // Has returns a bool indicating whether an intset actually contains the given elem or not.
  139. func (a *IntSet) Has(elem int) bool {
  140. has := false
  141. if a != nil {
  142. a.RLock()
  143. // Make sure to call Sparse implementation of Has()
  144. has = a.Sparse.Has(elem)
  145. a.RUnlock()
  146. }
  147. return has
  148. }
  149. // IsEmpty a bool indicating whether an intset is empty or not.
  150. func (a *IntSet) IsEmpty() bool {
  151. empty := false
  152. if a != nil {
  153. a.RLock()
  154. // Make sure to call Sparse implementation of IsEmpty()
  155. empty = a.Sparse.IsEmpty()
  156. a.RUnlock()
  157. }
  158. return empty
  159. }
  160. // Clear empties an array.
  161. func (a *IntSet) Clear() {
  162. if a != nil {
  163. a.Lock()
  164. a.Sparse.Clear()
  165. a.Unlock()
  166. }
  167. }
  168. // List returns a list representation of a set in sorted order
  169. func (a *IntSet) List() IntList {
  170. var list IntList
  171. if a != nil {
  172. a.Lock()
  173. list = a.AppendTo([]int{})
  174. a.Unlock()
  175. sort.Slice(list, func(i, j int) bool { return list[i] < list[j] })
  176. }
  177. return list
  178. }
  179. // Copy sets the value of IntSet a to the value of IntSet b.
  180. func (a *IntSet) Copy(b *IntSet) {
  181. if a != nil && b != nil {
  182. a.Lock()
  183. b.Lock()
  184. a.Sparse.Copy(&b.Sparse)
  185. b.Unlock()
  186. a.Unlock()
  187. }
  188. }
  189. // Inter returns the set intersection (a & b)
  190. func (a *IntSet) Inter(b *IntSet) *IntSet {
  191. var inter IntSet
  192. if a != nil && b != nil {
  193. a.Lock()
  194. b.Lock()
  195. inter.Intersection(&a.Sparse, &b.Sparse)
  196. b.Unlock()
  197. a.Unlock()
  198. }
  199. return &inter
  200. }
  201. // Diff returns the set difference (a \ b)
  202. func (a *IntSet) Diff(b *IntSet) *IntSet {
  203. var diff IntSet
  204. if a != nil && b != nil {
  205. a.Lock()
  206. b.Lock()
  207. diff.Difference(&a.Sparse, &b.Sparse)
  208. b.Unlock()
  209. a.Unlock()
  210. }
  211. return &diff
  212. }
  213. // Union returns the set union (a | b)
  214. func (a *IntSet) Union(b *IntSet) *IntSet {
  215. var union IntSet
  216. // Need to use .Sparse to call intsets Union function, because our function has the same name.
  217. if a != nil && b != nil {
  218. a.Lock()
  219. b.Lock()
  220. union.Sparse.Union(&a.Sparse, &b.Sparse)
  221. b.Unlock()
  222. a.Unlock()
  223. }
  224. return &union
  225. }
  226. // StringList is a list of strings
  227. type StringList []string
  228. // StringSet is a set of strings
  229. type StringSet map[string]bool
  230. // NewStringList returns a string list parsed from a string.
  231. func NewStringList(s string) (StringList, error) {
  232. var a StringList
  233. err := a.Parse(s)
  234. return a, err
  235. }
  236. // Parse a stringlist from a string and return an error on failure
  237. func (a *StringList) Parse(s string) error {
  238. *a = nil
  239. if len(s) > 0 {
  240. *a = strings.Split(s, ",")
  241. }
  242. return nil
  243. }
  244. // String returns a comma-separated string of list elements
  245. func (a StringList) String() string {
  246. var buf bytes.Buffer
  247. for idx, elem := range a {
  248. if idx != 0 {
  249. buf.WriteString(",")
  250. }
  251. buf.WriteString(elem)
  252. }
  253. return buf.String()
  254. }
  255. // Contains returns true if b is an ordered subsequence of a
  256. func (a StringList) Contains(b StringList) bool {
  257. bIdx := 0
  258. bLen := len(b)
  259. if bLen == 0 {
  260. return true
  261. }
  262. for _, elem := range a {
  263. if elem == b[bIdx] {
  264. bIdx++
  265. if bIdx == bLen {
  266. return true
  267. }
  268. }
  269. }
  270. return false
  271. }
  272. // Equals returns true if a and b are equal
  273. func (a StringList) Equals(b StringList) bool {
  274. if len(a) != len(b) {
  275. return false
  276. }
  277. for idx := range a {
  278. if a[idx] != b[idx] {
  279. return false
  280. }
  281. }
  282. return true
  283. }
  284. // Set returns a set representation of a list
  285. func (a StringList) Set() StringSet {
  286. set := make(StringSet, len(a))
  287. for _, elem := range a {
  288. set[elem] = true
  289. }
  290. return set
  291. }
  292. // List returns a list representation of a set in sorted order
  293. func (a StringSet) List() StringList {
  294. list := make(StringList, len(a))
  295. idx := 0
  296. for elem := range a {
  297. list[idx] = elem
  298. idx++
  299. }
  300. sort.Slice(list, func(i, j int) bool { return list[i] < list[j] })
  301. return list
  302. }
  303. // Inter returns the set intersection (a & b)
  304. func (a StringSet) Inter(b StringSet) StringSet {
  305. inter := make(StringSet, len(a))
  306. for elem := range a {
  307. if b[elem] {
  308. inter[elem] = true
  309. }
  310. }
  311. return inter
  312. }
  313. // Diff returns the set difference (a - b)
  314. func (a StringSet) Diff(b StringSet) StringSet {
  315. diff := make(StringSet, len(a))
  316. for elem := range a {
  317. if !b[elem] {
  318. diff[elem] = true
  319. }
  320. }
  321. return diff
  322. }
  323. // Union returns the set union (a | b)
  324. func (a StringSet) Union(b StringSet) StringSet {
  325. union := make(StringSet, len(a)+len(b))
  326. for elem := range a {
  327. union[elem] = true
  328. }
  329. for elem := range b {
  330. union[elem] = true
  331. }
  332. return union
  333. }