-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.go
More file actions
146 lines (125 loc) · 3.54 KB
/
Copy pathparser.go
File metadata and controls
146 lines (125 loc) · 3.54 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package fedach
import (
"bytes"
"errors"
"fmt"
"reflect"
"runtime"
"strconv"
"strings"
)
// Unmarshal parses the Fed-format-encoded data and stores the result in the value
// pointed to by v.
// If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
func Unmarshal(data []byte, v interface{}) error {
reader := bytes.NewBuffer(data)
switch reflect.TypeOf(v).String() {
case "*[][]string":
records := [][]string{}
SampleRecord := RoutingDirectoryRecord{}
for {
line, err := reader.ReadString('\n')
if len(line) == 0 {
reflect.ValueOf(v).Elem().Set(reflect.ValueOf(records))
return nil
}
record := []string{}
t := reflect.TypeOf(&SampleRecord).Elem()
for i := 0; i < t.NumField(); i++ {
pos := t.Field(i).Tag.Get("pos")
indexes := strings.Split(pos, "-")
start, _ := strconv.ParseInt(indexes[0], 10, 64)
var end int64
if len(indexes) == 2 {
end, _ = strconv.ParseInt(indexes[1], 10, 64)
} else {
end = start
}
record = append(record, line[start-1:end])
}
records = append(records, record)
if err != nil {
reflect.ValueOf(v).Elem().Set(reflect.ValueOf(records))
return nil
}
}
case "*[]fedach.RoutingDirectoryRecord":
records := []RoutingDirectoryRecord{}
for {
line, err := reader.ReadString('\n')
if len(line) == 0 {
reflect.ValueOf(v).Elem().Set(reflect.ValueOf(records))
return nil
}
record := RoutingDirectoryRecord{}
t := reflect.TypeOf(&record).Elem()
for i := 0; i < t.NumField(); i++ {
pos := t.Field(i).Tag.Get("pos")
indexes := strings.Split(pos, "-")
start, _ := strconv.ParseInt(indexes[0], 10, 64)
var end int64
if len(indexes) == 2 {
end, _ = strconv.ParseInt(indexes[1], 10, 64)
} else {
end = start
}
value := reflect.ValueOf(line[start-1 : end])
reflect.ValueOf(&record).Elem().Field(i).Set(value)
}
records = append(records, record)
if err != nil {
reflect.ValueOf(v).Elem().Set(reflect.ValueOf(records))
return nil
}
}
default:
return fmt.Errorf("Can't Unmarshal to %s, use *[][]string or *[]fedach.RoutingDirectoryRecord ", reflect.TypeOf(v).String())
}
}
// Marshal returns the Fed file encoding of v.
func Marshal(v interface{}) (bs []byte, err error) {
defer func() {
if r := recover(); r != nil {
if _, ok := r.(runtime.Error); ok {
panic(r)
} else if s, ok := r.(string); ok {
err = errors.New(s)
} else {
err = r.(error)
}
}
}()
var records Records
bs = records.bytes(v, records)
return bs, err
}
// Records is an array of records from a Fed file.
type Records []byte
func (r *Records) bytes(input interface{}, records Records) []byte {
v := reflect.ValueOf(input)
var routingDirectoryFileBuf bytes.Buffer
switch v.Type().String() {
case "[]fedach.RoutingDirectoryRecord":
for _, record := range v.Interface().([]RoutingDirectoryRecord) {
// fmt.Printf("%s\n", record.Bytes())
routingDirectoryFileBuf.Write(record.Bytes())
}
case "[][]string":
records := make([]RoutingDirectoryRecord, 0, len(input.([][]string)))
for _, recordLine := range input.([][]string) {
record := RoutingDirectoryRecord{}
for i, field := range recordLine {
value := reflect.ValueOf(field)
reflect.ValueOf(&record).Elem().Field(i).Set(value)
}
records = append(records, record)
}
for _, record := range records {
// fmt.Printf("%s\n", record.Bytes())
routingDirectoryFileBuf.Write(record.Bytes())
}
default:
panic("Cannot marshal provided struct.")
}
return routingDirectoryFileBuf.Bytes()
}