mirror of
				https://github.com/aclindsa/ofxgo.git
				synced 2025-11-03 18:03:25 -05:00 
			
		
		
		
	Reorganization
This commit is contained in:
		@@ -5,15 +5,6 @@ import (
 | 
				
			|||||||
	"github.com/golang/go/src/encoding/xml"
 | 
						"github.com/golang/go/src/encoding/xml"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BankAcct struct {
 | 
					 | 
				
			||||||
	XMLName  xml.Name // BANKACCTTO or BANKACCTFROM
 | 
					 | 
				
			||||||
	BankId   String   `xml:"BANKID"`
 | 
					 | 
				
			||||||
	BranchId String   `xml:"BRANCHID,omitempty"` // Unused in USA
 | 
					 | 
				
			||||||
	AcctId   String   `xml:"ACCTID"`
 | 
					 | 
				
			||||||
	AcctType String   `xml:"ACCTTYPE"`          // One of CHECKING, SAVINGS, MONEYMRKT, CREDITLINE, CD
 | 
					 | 
				
			||||||
	AcctKey  String   `xml:"ACCTKEY,omitempty"` // Unused in USA
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type StatementRequest struct {
 | 
					type StatementRequest struct {
 | 
				
			||||||
	XMLName          xml.Name `xml:"STMTTRNRQ"`
 | 
						XMLName          xml.Name `xml:"STMTTRNRQ"`
 | 
				
			||||||
	TrnUID           UID      `xml:"TRNUID"`
 | 
						TrnUID           UID      `xml:"TRNUID"`
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								common.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								common.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					package ofxgo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/golang/go/src/encoding/xml"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Represents a top-level OFX message set (i.e. BANKMSGSRSV1)
 | 
				
			||||||
 | 
					type Message interface {
 | 
				
			||||||
 | 
						Name() string         // The name of the OFX element this set represents
 | 
				
			||||||
 | 
						Valid() (bool, error) // Called before a Message is marshaled and after
 | 
				
			||||||
 | 
						// it's unmarshaled to ensure the request or response is valid
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BankAcct struct {
 | 
				
			||||||
 | 
						XMLName  xml.Name // BANKACCTTO or BANKACCTFROM
 | 
				
			||||||
 | 
						BankId   String   `xml:"BANKID"`
 | 
				
			||||||
 | 
						BranchId String   `xml:"BRANCHID,omitempty"` // Unused in USA
 | 
				
			||||||
 | 
						AcctId   String   `xml:"ACCTID"`
 | 
				
			||||||
 | 
						AcctType String   `xml:"ACCTTYPE"`          // One of CHECKING, SAVINGS, MONEYMRKT, CREDITLINE, CD
 | 
				
			||||||
 | 
						AcctKey  String   `xml:"ACCTKEY,omitempty"` // Unused in USA
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CCAcct struct {
 | 
				
			||||||
 | 
						XMLName xml.Name // CCACCTTO or CCACCTFROM
 | 
				
			||||||
 | 
						AcctId  String   `xml:"ACCTID"`
 | 
				
			||||||
 | 
						AcctKey String   `xml:"ACCTKEY,omitempty"` // Unused in USA
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										121
									
								
								request.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								request.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
				
			|||||||
 | 
					package ofxgo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"github.com/golang/go/src/encoding/xml"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Request struct {
 | 
				
			||||||
 | 
						URL     string
 | 
				
			||||||
 | 
						Version string        // OFX version string, overwritten in Client.Request()
 | 
				
			||||||
 | 
						Signon  SignonRequest //<SIGNONMSGSETV1>
 | 
				
			||||||
 | 
						Signup  []Message     //<SIGNUPMSGSETV1>
 | 
				
			||||||
 | 
						Banking []Message     //<BANKMSGSETV1>
 | 
				
			||||||
 | 
						//<CREDITCARDMSGSETV1>
 | 
				
			||||||
 | 
						//<LOANMSGSETV1>
 | 
				
			||||||
 | 
						//<INVSTMTMSGSETV1>
 | 
				
			||||||
 | 
						//<INTERXFERMSGSETV1>
 | 
				
			||||||
 | 
						//<WIREXFERMSGSETV1>
 | 
				
			||||||
 | 
						//<BILLPAYMSGSETV1>
 | 
				
			||||||
 | 
						//<EMAILMSGSETV1>
 | 
				
			||||||
 | 
						//<SECLISTMSGSETV1>
 | 
				
			||||||
 | 
						//<PRESDIRMSGSETV1>
 | 
				
			||||||
 | 
						//<PRESDLVMSGSETV1>
 | 
				
			||||||
 | 
						Profile []Message //<PROFMSGSETV1>
 | 
				
			||||||
 | 
						//<IMAGEMSGSETV1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						indent bool // Whether to indent the marshaled XML
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func marshalMessageSet(e *xml.Encoder, requests []Message, setname string) error {
 | 
				
			||||||
 | 
						if len(requests) > 0 {
 | 
				
			||||||
 | 
							messageSetElement := xml.StartElement{Name: xml.Name{Local: setname}}
 | 
				
			||||||
 | 
							if err := e.EncodeToken(messageSetElement); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, request := range requests {
 | 
				
			||||||
 | 
								if ok, err := request.Valid(); !ok {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if err := e.Encode(request); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err := e.EncodeToken(messageSetElement.End()); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (oq *Request) Marshal() (*bytes.Buffer, error) {
 | 
				
			||||||
 | 
						var b bytes.Buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Write the header appropriate to our version
 | 
				
			||||||
 | 
						switch oq.Version {
 | 
				
			||||||
 | 
						case "102", "103", "151", "160":
 | 
				
			||||||
 | 
							b.WriteString(`OFXHEADER:100
 | 
				
			||||||
 | 
					DATA:OFXSGML
 | 
				
			||||||
 | 
					VERSION:` + oq.Version + `
 | 
				
			||||||
 | 
					SECURITY:NONE
 | 
				
			||||||
 | 
					ENCODING:USASCII
 | 
				
			||||||
 | 
					CHARSET:1252
 | 
				
			||||||
 | 
					COMPRESSION:NONE
 | 
				
			||||||
 | 
					OLDFILEUID:NONE
 | 
				
			||||||
 | 
					NEWFILEUID:NONE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`)
 | 
				
			||||||
 | 
						case "200", "201", "202", "203", "210", "211", "220":
 | 
				
			||||||
 | 
							b.WriteString(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>` + "\n")
 | 
				
			||||||
 | 
							b.WriteString(`<?OFX OFXHEADER="200" VERSION="` + oq.Version + `" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>` + "\n")
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, errors.New(oq.Version + " is not a valid OFX version string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						encoder := xml.NewEncoder(&b)
 | 
				
			||||||
 | 
						if oq.indent {
 | 
				
			||||||
 | 
							encoder.Indent("", "    ")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ofxElement := xml.StartElement{Name: xml.Name{Local: "OFX"}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := encoder.EncodeToken(ofxElement); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ok, err := oq.Signon.Valid(); !ok {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						signonMsgSet := xml.StartElement{Name: xml.Name{Local: "SIGNONMSGSRQV1"}}
 | 
				
			||||||
 | 
						if err := encoder.EncodeToken(signonMsgSet); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := encoder.Encode(&oq.Signon); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := encoder.EncodeToken(signonMsgSet.End()); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := marshalMessageSet(encoder, oq.Signup, "SIGNUPMSGSRQV1"); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := marshalMessageSet(encoder, oq.Banking, "BANKMSGSRQV1"); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := marshalMessageSet(encoder, oq.Profile, "PROFMSGSRQV1"); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := encoder.EncodeToken(ofxElement.End()); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := encoder.Flush(); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &b, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -9,125 +9,6 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Message interface {
 | 
					 | 
				
			||||||
	Name() string
 | 
					 | 
				
			||||||
	Valid() (bool, error)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Request struct {
 | 
					 | 
				
			||||||
	URL     string
 | 
					 | 
				
			||||||
	Version string        // OFX version string, overwritten in Client.Request()
 | 
					 | 
				
			||||||
	Signon  SignonRequest //<SIGNONMSGSETV1>
 | 
					 | 
				
			||||||
	Signup  []Message     //<SIGNUPMSGSETV1>
 | 
					 | 
				
			||||||
	Banking []Message     //<BANKMSGSETV1>
 | 
					 | 
				
			||||||
	//<CREDITCARDMSGSETV1>
 | 
					 | 
				
			||||||
	//<LOANMSGSETV1>
 | 
					 | 
				
			||||||
	//<INVSTMTMSGSETV1>
 | 
					 | 
				
			||||||
	//<INTERXFERMSGSETV1>
 | 
					 | 
				
			||||||
	//<WIREXFERMSGSETV1>
 | 
					 | 
				
			||||||
	//<BILLPAYMSGSETV1>
 | 
					 | 
				
			||||||
	//<EMAILMSGSETV1>
 | 
					 | 
				
			||||||
	//<SECLISTMSGSETV1>
 | 
					 | 
				
			||||||
	//<PRESDIRMSGSETV1>
 | 
					 | 
				
			||||||
	//<PRESDLVMSGSETV1>
 | 
					 | 
				
			||||||
	Profile []Message //<PROFMSGSETV1>
 | 
					 | 
				
			||||||
	//<IMAGEMSGSETV1>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	indent bool // Whether to indent the marshaled XML
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func marshalMessageSet(e *xml.Encoder, requests []Message, setname string) error {
 | 
					 | 
				
			||||||
	if len(requests) > 0 {
 | 
					 | 
				
			||||||
		messageSetElement := xml.StartElement{Name: xml.Name{Local: setname}}
 | 
					 | 
				
			||||||
		if err := e.EncodeToken(messageSetElement); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for _, request := range requests {
 | 
					 | 
				
			||||||
			if ok, err := request.Valid(); !ok {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if err := e.Encode(request); err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if err := e.EncodeToken(messageSetElement.End()); err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (oq *Request) Marshal() (*bytes.Buffer, error) {
 | 
					 | 
				
			||||||
	var b bytes.Buffer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Write the header appropriate to our version
 | 
					 | 
				
			||||||
	switch oq.Version {
 | 
					 | 
				
			||||||
	case "102", "103", "151", "160":
 | 
					 | 
				
			||||||
		b.WriteString(`OFXHEADER:100
 | 
					 | 
				
			||||||
DATA:OFXSGML
 | 
					 | 
				
			||||||
VERSION:` + oq.Version + `
 | 
					 | 
				
			||||||
SECURITY:NONE
 | 
					 | 
				
			||||||
ENCODING:USASCII
 | 
					 | 
				
			||||||
CHARSET:1252
 | 
					 | 
				
			||||||
COMPRESSION:NONE
 | 
					 | 
				
			||||||
OLDFILEUID:NONE
 | 
					 | 
				
			||||||
NEWFILEUID:NONE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`)
 | 
					 | 
				
			||||||
	case "200", "201", "202", "203", "210", "211", "220":
 | 
					 | 
				
			||||||
		b.WriteString(`<?xml version="1.0" encoding="UTF-8" standalone="no"?>` + "\n")
 | 
					 | 
				
			||||||
		b.WriteString(`<?OFX OFXHEADER="200" VERSION="` + oq.Version + `" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>` + "\n")
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return nil, errors.New(oq.Version + " is not a valid OFX version string")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	encoder := xml.NewEncoder(&b)
 | 
					 | 
				
			||||||
	if oq.indent {
 | 
					 | 
				
			||||||
		encoder.Indent("", "    ")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ofxElement := xml.StartElement{Name: xml.Name{Local: "OFX"}}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := encoder.EncodeToken(ofxElement); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ok, err := oq.Signon.Valid(); !ok {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	signonMsgSet := xml.StartElement{Name: xml.Name{Local: "SIGNONMSGSRQV1"}}
 | 
					 | 
				
			||||||
	if err := encoder.EncodeToken(signonMsgSet); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := encoder.Encode(&oq.Signon); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := encoder.EncodeToken(signonMsgSet.End()); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := marshalMessageSet(encoder, oq.Signup, "SIGNUPMSGSRQV1"); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := marshalMessageSet(encoder, oq.Banking, "BANKMSGSRQV1"); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := marshalMessageSet(encoder, oq.Profile, "PROFMSGSRQV1"); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := encoder.EncodeToken(ofxElement.End()); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err := encoder.Flush(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return &b, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Response struct {
 | 
					type Response struct {
 | 
				
			||||||
	Version string         // String for OFX header, defaults to 203
 | 
						Version string         // String for OFX header, defaults to 203
 | 
				
			||||||
	Signon  SignonResponse //<SIGNONMSGSETV1>
 | 
						Signon  SignonResponse //<SIGNONMSGSETV1>
 | 
				
			||||||
@@ -208,22 +89,6 @@ func (or *Response) readSGMLHeaders(r *bufio.Reader) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func nextNonWhitespaceToken(decoder *xml.Decoder) (xml.Token, error) {
 | 
					 | 
				
			||||||
	for {
 | 
					 | 
				
			||||||
		tok, err := decoder.Token()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		} else if chars, ok := tok.(xml.CharData); ok {
 | 
					 | 
				
			||||||
			strippedBytes := bytes.TrimSpace(chars)
 | 
					 | 
				
			||||||
			if len(strippedBytes) != 0 {
 | 
					 | 
				
			||||||
				return tok, nil
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			return tok, nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (or *Response) readXMLHeaders(decoder *xml.Decoder) error {
 | 
					func (or *Response) readXMLHeaders(decoder *xml.Decoder) error {
 | 
				
			||||||
	var tok xml.Token
 | 
						var tok xml.Token
 | 
				
			||||||
	tok, err := nextNonWhitespaceToken(decoder)
 | 
						tok, err := nextNonWhitespaceToken(decoder)
 | 
				
			||||||
@@ -61,12 +61,6 @@ func (bai *BankAcctInfo) String() string {
 | 
				
			|||||||
	return fmt.Sprintf("%+v", *bai)
 | 
						return fmt.Sprintf("%+v", *bai)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CCAcct struct {
 | 
					 | 
				
			||||||
	XMLName xml.Name // CCACCTTO or CCACCTFROM
 | 
					 | 
				
			||||||
	AcctId  String   `xml:"ACCTID"`
 | 
					 | 
				
			||||||
	AcctKey String   `xml:"ACCTKEY,omitempty"` // Unused in USA
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type CCAcctInfo struct {
 | 
					type CCAcctInfo struct {
 | 
				
			||||||
	XMLName            xml.Name `xml:"CCACCTINFO"`
 | 
						XMLName            xml.Name `xml:"CCACCTINFO"`
 | 
				
			||||||
	CCAcctFrom         CCAcct   `xml:"CCACCTFROM"`
 | 
						CCAcctFrom         CCAcct   `xml:"CCACCTFROM"`
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										25
									
								
								util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								util.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					package ofxgo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"github.com/golang/go/src/encoding/xml"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Returns the next available Token from the xml.Decoder that is not CharData
 | 
				
			||||||
 | 
					// made up entirely of whitespace. This is useful to skip whitespace when
 | 
				
			||||||
 | 
					// manually unmarshaling XML.
 | 
				
			||||||
 | 
					func nextNonWhitespaceToken(decoder *xml.Decoder) (xml.Token, error) {
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							tok, err := decoder.Token()
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							} else if chars, ok := tok.(xml.CharData); ok {
 | 
				
			||||||
 | 
								strippedBytes := bytes.TrimSpace(chars)
 | 
				
			||||||
 | 
								if len(strippedBytes) != 0 {
 | 
				
			||||||
 | 
									return tok, nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return tok, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user