package isphere import ( "bufio" "fmt" "io/fs" "os" "path/filepath" "sort" "strings" ) func LoadEncryptedPacketLogSourceFromFile(path string) (EncryptedPacketLogSource, error) { trimmedPath := strings.TrimSpace(path) if trimmedPath == "" { return EncryptedPacketLogSource{}, fmt.Errorf("packet log file path is empty") } lines, err := readEncryptedPacketLogLinesFromFile(trimmedPath) if err != nil { return EncryptedPacketLogSource{}, err } return EncryptedPacketLogSource{Lines: lines}, nil } func LoadEncryptedPacketLogSourceFromDirectory(path string) (EncryptedPacketLogSource, error) { trimmedPath := strings.TrimSpace(path) if trimmedPath == "" { return EncryptedPacketLogSource{}, fmt.Errorf("packet log directory path is empty") } info, err := os.Stat(trimmedPath) if err != nil { return EncryptedPacketLogSource{}, fmt.Errorf("stat packet log directory %q: %w", trimmedPath, err) } if !info.IsDir() { return EncryptedPacketLogSource{}, fmt.Errorf("packet log directory %q is not a directory", trimmedPath) } paths := []string{} if err := filepath.WalkDir(trimmedPath, func(path string, entry fs.DirEntry, walkErr error) error { if walkErr != nil { return walkErr } if entry.IsDir() { return nil } ext := strings.ToLower(filepath.Ext(entry.Name())) if ext == ".log" || ext == ".txt" { paths = append(paths, path) } return nil }); err != nil { return EncryptedPacketLogSource{}, fmt.Errorf("walk packet log directory %q: %w", trimmedPath, err) } sort.Strings(paths) lines := []string{} for _, path := range paths { fileLines, err := readEncryptedPacketLogLinesFromFile(path) if err != nil { return EncryptedPacketLogSource{}, err } lines = append(lines, fileLines...) } return EncryptedPacketLogSource{Lines: lines}, nil } func readEncryptedPacketLogLinesFromFile(path string) ([]string, error) { file, err := os.Open(path) if err != nil { return nil, fmt.Errorf("open packet log file %q: %w", path, err) } defer file.Close() scanner := bufio.NewScanner(file) scanner.Buffer(make([]byte, 64*1024), 16*1024*1024) lines := []string{} for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" { continue } lines = append(lines, line) } if err := scanner.Err(); err != nil { return nil, fmt.Errorf("read packet log file %q: %w", path, err) } return lines, nil }