~samwhited/xmpp

ad06d1aac2abbec1db5a92fbed3d9a4c8665c7f4 — Sam Whited 1 year, 1 month ago 23dec77 marshal_tokenreader
internal/marshal: add TokenReader API

While thinking about whether or not it would be difficult to add
EncodeIQ and EncodeIQElement methods to Session I realized that I
wouldn't be able to implement them in terms of SendIQ and SendIQ element
because these use a token reader based API as opposed to the token
writer based API used by the functions in Marshal. However, internally
the marshal functions create a token reader and then copy from it into
the writer, so by exposing this functionality we can make it possible to
create reader or writer based functionality with the marshal package.

Signed-off-by: Sam Whited <sam@samwhited.com>
1 files changed, 14 insertions(+), 6 deletions(-)

M internal/marshal/encode.go
M internal/marshal/encode.go => internal/marshal/encode.go +14 -6
@@ 15,6 15,16 @@ import (

// BUG(ssw): Functions in this package are extremely inefficient.

// TokenReader returns a reader for the XML encoding of v.
func TokenReader(v interface{}) (xml.TokenReader, error) {
	var b bytes.Buffer
	err := xml.NewEncoder(&b).Encode(v)
	if err != nil {
		return nil, err
	}
	return xml.NewDecoder(&b), nil
}

// EncodeXML writes the XML encoding of v to the stream.
//
// See the documentation for xml.Marshal for details about the conversion of Go


@@ 23,12 33,11 @@ import (
// If the stream is an xmlstream.Flusher, EncodeXML calls Flush before
// returning.
func EncodeXML(w xmlstream.TokenWriter, v interface{}) error {
	var b bytes.Buffer
	err := xml.NewEncoder(&b).Encode(v)
	r, err := TokenReader(v)
	if err != nil {
		return err
	}
	_, err = xmlstream.Copy(w, xml.NewDecoder(&b))
	_, err = xmlstream.Copy(w, r)
	if err != nil {
		return err
	}


@@ 48,12 57,11 @@ func EncodeXML(w xmlstream.TokenWriter, v interface{}) error {
// If the stream is an xmlstream.Flusher, EncodeXMLElement calls Flush before
// returning.
func EncodeXMLElement(w xmlstream.TokenWriter, v interface{}, start xml.StartElement) error {
	var b bytes.Buffer
	err := xml.NewEncoder(&b).EncodeElement(v, start)
	r, err := TokenReader(v)
	if err != nil {
		return err
	}
	_, err = xmlstream.Copy(w, xml.NewDecoder(&b))
	_, err = xmlstream.Copy(w, xmlstream.Wrap(r, start))
	if err != nil {
		return err
	}