123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- package common
-
- import (
- "bufio"
- "os"
- "unicode"
- "unicode/utf8"
- )
-
- // ReadFileAsInts reads all lines from the given path and returns them in a slice of ints.
- // If an error occurs, the function will panic.
- func ReadFileAsInts(path string) []int {
- return readIntsWithScanner(path, bufio.ScanLines)
- }
-
- // ReadFileAsStrings reads all lines from the given path and returns them in a slice of strings.
- // If an error occurs, the function will panic.
- func ReadFileAsStrings(path string) []string {
- return readStringsWithScanner(path, bufio.ScanLines)
- }
-
- // ReadCsvAsInts reads all data from the given path and returns an int slice
- // containing comma-delimited parts. If an error occurs, the function will panic.
- func ReadCsvAsInts(path string) []int {
- return readIntsWithScanner(path, scanByCommas)
- }
-
- // readIntsWithScanner uses a bufio.Scanner to read ints from the file at
- // the given path, splitting using the given bufio.SplitFunc. If an error
- // occurs at any point, the function will panic.
- func readIntsWithScanner(path string, splitFunc bufio.SplitFunc) []int {
- file, err := os.Open(path)
- if err != nil {
- panic(err)
- }
- defer func() {
- _ = file.Close()
- }()
-
- var parts []int
- scanner := bufio.NewScanner(file)
- scanner.Split(splitFunc)
- for scanner.Scan() {
- parts = append(parts, MustAtoi(scanner.Text()))
- }
-
- if scanner.Err() != nil {
- panic(scanner.Err())
- }
-
- return parts
- }
-
- // readStringsWithScanner uses a bufio.Scanner to read strings from the file at
- // the given path, splitting using the given bufio.SplitFunc. If an error
- // occurs at any point, the function will panic.
- func readStringsWithScanner(path string, splitFunc bufio.SplitFunc) []string {
- file, err := os.Open(path)
- if err != nil {
- panic(err)
- }
- defer func() {
- _ = file.Close()
- }()
-
- var parts []string
- scanner := bufio.NewScanner(file)
- scanner.Split(splitFunc)
- for scanner.Scan() {
- parts = append(parts, scanner.Text())
- }
-
- if scanner.Err() != nil {
- panic(scanner.Err())
- }
-
- return parts
- }
-
- // scanByCommas is a split function for a Scanner that returns each
- // comma-separated section of text, with surrounding spaces deleted.
- // The definition of space is set by unicode.IsSpace.
- func scanByCommas(data []byte, atEOF bool) (advance int, token []byte, err error) {
- // Skip leading spaces.
- start := 0
- for width := 0; start < len(data); start += width {
- var r rune
- r, width = utf8.DecodeRune(data[start:])
- if !unicode.IsSpace(r) {
- break
- }
- }
-
- // Scan until comma, marking end of word.
- for width, i := 0, start; i < len(data); i += width {
- var r rune
- r, width = utf8.DecodeRune(data[i:])
- if r == ',' || unicode.IsSpace(r) {
- return i + width, data[start:i], nil
- }
- }
- // If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
- if atEOF && len(data) > start {
- return len(data), data[start:], nil
- }
- // Request more data.
- return start, nil, nil
- }
|