148 lines
3.0 KiB
Go
148 lines
3.0 KiB
Go
package common
|
|
|
|
import (
|
|
"bufio"
|
|
"strconv"
|
|
)
|
|
|
|
|
|
type Packet interface {
|
|
Compare(Packet) int
|
|
ToList() ListPacket
|
|
IsSeparator() bool
|
|
}
|
|
|
|
|
|
type IntPacket int
|
|
|
|
func (packet IntPacket) Compare(other Packet) int {
|
|
if otherInt, ok := other.(IntPacket); ok {
|
|
if packet < otherInt {
|
|
return -1
|
|
} else if packet > otherInt {
|
|
return 1
|
|
} else {
|
|
return 0
|
|
}
|
|
} else {
|
|
otherList, _ := other.(ListPacket)
|
|
return packet.ToList().Compare(otherList)
|
|
}
|
|
}
|
|
|
|
func (packet IntPacket) ToList() ListPacket {
|
|
return ListPacket{[]Packet{packet}, false}
|
|
}
|
|
|
|
func (packet IntPacket) IsSeparator() bool {
|
|
return false
|
|
}
|
|
|
|
|
|
type ListPacket struct {
|
|
content []Packet
|
|
separator bool
|
|
}
|
|
|
|
func (packet ListPacket) Compare(other Packet) int {
|
|
otherList := other.ToList()
|
|
comparisonRes := 0
|
|
for i := 0; comparisonRes == 0; i++ {
|
|
if i == len(packet.content) && i == len(otherList.content) {
|
|
break
|
|
} else if i == len(packet.content) {
|
|
comparisonRes = -1
|
|
} else if i == len(otherList.content) {
|
|
comparisonRes = 1
|
|
} else {
|
|
comparisonRes = packet.content[i].Compare(otherList.content[i])
|
|
}
|
|
}
|
|
return comparisonRes
|
|
}
|
|
|
|
func (packet ListPacket) ToList() ListPacket {
|
|
return packet
|
|
}
|
|
|
|
func (packet ListPacket) IsSeparator() bool {
|
|
return packet.separator
|
|
}
|
|
|
|
|
|
type Pair struct {
|
|
first Packet
|
|
second Packet
|
|
}
|
|
|
|
func (pair Pair) CheckOrder() bool {
|
|
return pair.first.Compare(pair.second) < 0
|
|
}
|
|
|
|
|
|
func ParseListPacket(listString string) ListPacket {
|
|
var j int
|
|
packet := ListPacket{[]Packet{}, false}
|
|
|
|
for i := 1; i < len(listString) - 1; i++ {
|
|
if listString[i] >= '0' && listString[i] <= '9' {
|
|
for j = i + 1; listString[j] != ',' && listString[j] != ']'; j++ {}
|
|
convertedInt, _ := strconv.Atoi(listString[i:j])
|
|
packet.content = append(packet.content, IntPacket(convertedInt))
|
|
} else if listString[i] == '[' {
|
|
depth := 1
|
|
for j = i + 1; depth != 0; j++ {
|
|
if listString[j] == '[' {
|
|
depth++
|
|
} else if listString[j] == ']' {
|
|
depth--
|
|
}
|
|
}
|
|
packet.content = append(packet.content, ParseListPacket(listString[i:j]))
|
|
}
|
|
i = j
|
|
}
|
|
|
|
return packet
|
|
}
|
|
|
|
|
|
func ParsePairs(scanner bufio.Scanner) []Pair {
|
|
pairs := []Pair{}
|
|
current := make([]Packet, 0, 2)
|
|
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
|
|
if line == "" {
|
|
pairs = append(pairs, Pair{current[0], current[1]})
|
|
current = make([]Packet, 0, 2)
|
|
} else {
|
|
current = append(current, ParseListPacket(line))
|
|
}
|
|
}
|
|
|
|
return append(pairs, Pair{current[0], current[1]})
|
|
}
|
|
|
|
|
|
func ParsePackets(scanner bufio.Scanner, separators []string) []Packet {
|
|
packets := []Packet{}
|
|
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
|
|
if line != "" {
|
|
packets = append(packets, ParseListPacket(line))
|
|
}
|
|
}
|
|
|
|
for _, separator := range separators {
|
|
separatorPacket := ParseListPacket(separator)
|
|
separatorPacket.separator = true
|
|
packets = append(packets, separatorPacket)
|
|
}
|
|
|
|
return packets
|
|
}
|