This repository has been archived by the owner on Jul 11, 2023. It is now read-only.
/
cmd_exportcsv.go
108 lines (92 loc) · 2.16 KB
/
cmd_exportcsv.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main
import (
"encoding/csv"
"fmt"
"os"
"sort"
"strings"
)
func cmdExportCSV() {
switch {
case flagDataFile == "":
fmt.Fprintf(os.Stderr, "fatal: missing required flag -d / --data-file\n")
os.Exit(1)
case flagCsvFile == "":
fmt.Fprintf(os.Stderr, "fatal: missing required flag -c / --csv-file\n")
os.Exit(1)
}
var file BlockFile
ReadJsonFile(&file, flagDataFile)
rows := make([][]string, 0, len(file.Blocks))
for domain := range file.Blocks {
row := make([]string, 1)
row[0] = domain
rows = append(rows, row)
}
sort.Sort(firstColumnDomainNameSort(rows))
gBuffer.Reset()
w := csv.NewWriter(&gBuffer)
w.UseCRLF = true
err := w.WriteAll(rows)
if err != nil {
fmt.Fprintf(os.Stderr, "fatal: %q: failed to convert data to CSV: %v\n", flagCsvFile, err)
os.Exit(1)
}
err = w.Error()
if err != nil {
fmt.Fprintf(os.Stderr, "fatal: %q: failed to convert data to CSV: %v\n", flagCsvFile, err)
os.Exit(1)
}
WriteFile(flagCsvFile, gBuffer.Bytes(), false)
}
type firstColumnDomainNameSort [][]string
func (list firstColumnDomainNameSort) Len() int {
return len(list)
}
func (list firstColumnDomainNameSort) Less(i, j int) bool {
a := list[i][0]
b := list[j][0]
aList := splitDomainName(a)
bList := splitDomainName(b)
aLen := uint(len(aList))
bLen := uint(len(bList))
minLen := aLen
if minLen > bLen {
minLen = bLen
}
for k := uint(0); k < minLen; k++ {
aWord := aList[k]
bWord := bList[k]
if aWord < bWord {
return true
}
if aWord > bWord {
return false
}
}
return aLen < bLen
}
func (list firstColumnDomainNameSort) Swap(i, j int) {
list[i], list[j] = list[j], list[i]
}
var _ sort.Interface = firstColumnDomainNameSort(nil)
var splitDomainNameCache map[string][]string
func splitDomainName(str string) []string {
str = strings.TrimRight(str, ".")
if cached, found := splitDomainNameCache[str]; found {
return cached
}
pieces := strings.Split(str, ".")
i := uint(0)
j := uint(len(pieces)) - 1
for i < j {
pieces[i], pieces[j] = pieces[j], pieces[i]
i++
j--
}
if splitDomainNameCache == nil {
splitDomainNameCache = make(map[string][]string, 1024)
}
splitDomainNameCache[str] = pieces
return pieces
}