Преглед изворни кода

refactor(parser): centralize seek logic and provide a hint for the compiler to eliminate a useless bound check

- Move the seeking inside of DetectFeedFormat instead of having it everywhere
  in ParseFeed
- Provide a hint for the compiler to eliminate a useless bound check in
  DetectJSONFormat, otherwise it'll check that buffer[i] is valid on every
  iteration of the loop. This shouldn't make a big difference, but oh well.
Julien Voisin пре 11 месеци
родитељ
комит
a43d150a27
2 измењених фајлова са 7 додато и 5 уклоњено
  1. 7 0
      internal/reader/parser/format.go
  2. 0 5
      internal/reader/parser/parser.go

+ 7 - 0
internal/reader/parser/format.go

@@ -22,6 +22,9 @@ const (
 
 // DetectFeedFormat tries to guess the feed format from input data.
 func DetectFeedFormat(r io.ReadSeeker) (string, string) {
+	r.Seek(0, io.SeekStart)
+	defer r.Seek(0, io.SeekStart)
+
 	if isJSON, err := detectJSONFormat(r); err == nil && isJSON {
 		return FormatJSON, ""
 	}
@@ -70,6 +73,10 @@ func detectJSONFormat(r io.ReadSeeker) (bool, error) {
 			return false, err
 		}
 
+		if len(buffer) < n {
+			panic("unreachable") // bounds check hint to compiler
+		}
+
 		// Check each byte in the buffer
 		for i := range n {
 			ch := buffer[i]

+ 0 - 5
internal/reader/parser/parser.go

@@ -18,20 +18,15 @@ var ErrFeedFormatNotDetected = errors.New("parser: unable to detect feed format"
 
 // ParseFeed analyzes the input data and returns a normalized feed object.
 func ParseFeed(baseURL string, r io.ReadSeeker) (*model.Feed, error) {
-	r.Seek(0, io.SeekStart)
 	format, version := DetectFeedFormat(r)
 	switch format {
 	case FormatAtom:
-		r.Seek(0, io.SeekStart)
 		return atom.Parse(baseURL, r, version)
 	case FormatRSS:
-		r.Seek(0, io.SeekStart)
 		return rss.Parse(baseURL, r)
 	case FormatJSON:
-		r.Seek(0, io.SeekStart)
 		return json.Parse(baseURL, r)
 	case FormatRDF:
-		r.Seek(0, io.SeekStart)
 		return rdf.Parse(baseURL, r)
 	default:
 		return nil, ErrFeedFormatNotDetected