From a5fc4be5bdda919b5df28c139dcd84e6a98ba867 Mon Sep 17 00:00:00 2001
From: Since <ax20yhum@cip.cs.fau.de>
Date: Fri, 5 May 2017 20:59:44 +0200
Subject: [PATCH] Add NewComposites function

---
 radolan.go | 38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/radolan.go b/radolan.go
index cfdce27..44244cb 100644
--- a/radolan.go
+++ b/radolan.go
@@ -19,10 +19,13 @@
 package radolan
 
 import (
+	"archive/tar"
 	"bufio"
+	"compress/gzip"
 	"fmt"
 	"io"
 	"math"
+	"sort"
 	"time"
 )
 
@@ -81,7 +84,7 @@ type Composite struct {
 	offy float64 // vertical projection offset
 }
 
-// NewComposite reads from rd and parses the composite.
+// NewComposite reads binary data from rd and parses the composite.
 func NewComposite(rd io.Reader) (comp *Composite, err error) {
 	reader := bufio.NewReader(rd)
 	comp = &Composite{}
@@ -101,6 +104,39 @@ func NewComposite(rd io.Reader) (comp *Composite, err error) {
 	return
 }
 
+// NewComposites reads tar gz data from rd and returns the parsed composites sorted by
+// ForecastTime in ascending order.
+func NewComposites(rd io.Reader) ([]*Composite, error) {
+	gzipReader, err := gzip.NewReader(rd)
+	if err != nil {
+		return nil, err
+	}
+	defer gzipReader.Close()
+
+	tarReader := tar.NewReader(gzipReader)
+
+	var cs []*Composite
+	for {
+		_, err := tarReader.Next()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			return nil, err
+		}
+
+		c, err := NewComposite(tarReader)
+		if err != nil {
+			return nil, err
+		}
+		cs = append(cs, c)
+	}
+
+	// sort composites in chronological order
+	sort.Slice(cs, func(i, j int) bool { return cs[i].ForecastTime.Before(cs[j].ForecastTime) })
+	return cs, nil
+}
+
 // NewDummy creates a blank dummy composite with the given product label and dimensions. It can
 // be used for generic coordinate translation.
 func NewDummy(product string, dx, dy int) (comp *Composite) {
-- 
GitLab