package can import ( "bufio" "fmt" "os" "regexp" "strconv" "time" ) // (2022-07-08 16:54:15.587099) can0 100 [8] 00 00 00 00 00 00 64 00 // (1670578900.771868) can0 00004021#00000000FCFFFFFF const EXPR_HR = "\\((.*)\\)\\s+can\\d+\\s+(\\S+)\\s+\\[\\d\\]\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)\\s+([A-F0-9]+)" const EXPR_M = "\\((\\d+)\\.(\\d+)\\)\\s+can\\d+\\s+(\\S+)#([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})" const time_hr_layout = "2006-01-02 15:04:05.000000" const base_length = 11 var patternHr = regexp.MustCompile(EXPR_HR) var patternM = regexp.MustCompile(EXPR_M) func Readfile(filename *string) <-chan *CanFrame { c := make(chan *CanFrame) go func() { defer close(c) file, err := os.Open(*filename) if err != nil { fmt.Println(err) os.Exit(1) } defer file.Close() scanner := bufio.NewScanner(file) process(scanner, c) }() return c } func process(scanner *bufio.Scanner, ch chan<- *CanFrame) { for scanner.Scan() { text := scanner.Text() if frame := fromString(text); frame != nil { ch <- frame } } if err := scanner.Err(); err != nil { fmt.Println(err) } } func ReadStdin(file *os.File) <-chan *CanFrame { c := make(chan *CanFrame) go func() { scanner := bufio.NewScanner(file) process(scanner, c) close(c) }() return c } func fromString(text string) *CanFrame { var match []string var now time.Time var offset int if match = patternHr.FindStringSubmatch(text); match != nil { now, _ = time.ParseInLocation(time_hr_layout, match[1], time.Local) offset = 0 } else if match = patternM.FindStringSubmatch(text); match != nil { var seconds, _ = strconv.ParseInt(match[1], 10, 0) var nanos, _ = strconv.ParseInt(match[2], 10, 0) now = time.Unix(seconds, nanos*1000) //.In(time.Local) // Correct time to local zone var _, zoneoffset = now.Zone() now = now.Add(-time.Duration(zoneoffset) * time.Second) offset = 1 } else { return nil } if len(match) == base_length+offset { canId, err := strconv.ParseUint(match[2+offset], 16, 0) if err != nil { return nil } payload := make([]uint8, 8) for idx, octet := range match[3+offset:] { val, err := strconv.ParseUint(octet, 16, 0) if err != nil { fmt.Println(err) continue } payload[idx] = uint8(val) } return &CanFrame{ Date: &now, CanId: uint32(canId), Payload: &payload, } } return nil }