Add io.Writer-based feed generation methods

The current ToXML method returns a string, meaning the content is
buffered into memory before being written to some output. With this
change, XML can be written directly to the output, which may make
a difference with large feeds.

This is a backwards compatible change, as methods are only added.
This commit is contained in:
Jason Hall
2014-07-20 15:19:14 -04:00
parent ced1bd794b
commit fd92eaecf8
2 changed files with 48 additions and 4 deletions
+25 -1
View File
@@ -2,6 +2,7 @@ package feeds
import (
"encoding/xml"
"io"
"time"
)
@@ -41,7 +42,7 @@ func (f *Feed) Add(item *Item) {
f.Items = append(f.Items, item)
}
// returns the first non-zero time formatted as a string or ""
// returns the first non-zero time formatted as a string or ""
func anyTimeFormat(format string, times ...time.Time) string {
for _, t := range times {
if !t.IsZero() {
@@ -69,14 +70,37 @@ func ToXML(feed XmlFeed) (string, error) {
return s, nil
}
// Write a feed object (either a Feed, AtomFeed, or RssFeed) as XML into
// the writer. Returns an error if XML marshaling fails.
func WriteXML(feed XmlFeed, w io.Writer) error {
x := feed.FeedXml()
// write default xml header, without the newline
if _, err := w.Write([]byte(xml.Header[:len(xml.Header)-1])); err != nil {
return err
}
e := xml.NewEncoder(w)
e.Indent("", " ")
return e.Encode(x)
}
// creates an Atom representation of this feed
func (f *Feed) ToAtom() (string, error) {
a := &Atom{f}
return ToXML(a)
}
// Writes an Atom representation of this feed to the writer.
func (f *Feed) WriteAtom(w io.Writer) error {
return WriteXML(&Atom{f}, w)
}
// creates an Rss representation of this feed
func (f *Feed) ToRss() (string, error) {
r := &Rss{f}
return ToXML(r)
}
// Writes an RSS representation of this feed to the writer.
func (f *Feed) WriteRss(w io.Writer) error {
return WriteXML(&Rss{f}, w)
}
+23 -3
View File
@@ -1,6 +1,7 @@
package feeds
import (
"bytes"
"testing"
"time"
)
@@ -112,14 +113,33 @@ func TestFeed(t *testing.T) {
},
}
atom, _ := feed.ToAtom()
rss, _ := feed.ToRss()
atom, err := feed.ToAtom()
if err != nil {
t.Error("unexpected error encoding Atom: %v", err)
}
if atom != atomOutput {
t.Errorf("Atom not what was expected. Got:\n%s\n\nExpected:\n%s\n", atom, atomOutput)
}
var buf bytes.Buffer
if err := feed.WriteAtom(&buf); err != nil {
t.Errorf("unexpected error writing Atom: %v", err)
}
if got := buf.String(); got != atomOutput {
t.Errorf("Atom not what was expected. Got:\n%s\n\nExpected:\n%s\n", got, rssOutput)
}
rss, err := feed.ToRss()
if err != nil {
t.Errorf("unexpected error encoding RSS: %v", err)
}
if rss != rssOutput {
t.Errorf("Rss not what was expected. Got:\n%s\n\nExpected:\n%s\n", rss, rssOutput)
}
buf.Reset()
if err := feed.WriteRss(&buf); err != nil {
t.Errorf("unexpected error writing RSS: %v", err)
}
if got := buf.String(); got != rssOutput {
t.Errorf("Rss not what was expected. Got:\n%s\n\nExpected:\n%s\n", got, rssOutput)
}
}