forked from jshiffer/go-xmpp
don't use reflect. element in map[string]interface{} don't have type enough to reflecting value/type/construct.
This commit is contained in:
parent
fca5966193
commit
094f05fb75
58
xmpp.go
58
xmpp.go
@ -23,7 +23,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
|
||||||
"strings"
|
"strings"
|
||||||
"xml"
|
"xml"
|
||||||
)
|
)
|
||||||
@ -379,30 +378,6 @@ func nextStart(p *xml.Parser) (xml.StartElement, os.Error) {
|
|||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prototypical nil pointers for specific XML element names.
|
|
||||||
var proto = map[string]interface{}{
|
|
||||||
nsStream + " features": (*streamFeatures)(nil),
|
|
||||||
nsStream + " error": (*streamError)(nil),
|
|
||||||
|
|
||||||
nsTLS + " starttls": (*tlsStartTLS)(nil),
|
|
||||||
nsTLS + " proceed": (*tlsProceed)(nil),
|
|
||||||
nsTLS + " failure": (*tlsFailure)(nil),
|
|
||||||
|
|
||||||
nsSASL + " mechanisms": (*saslMechanisms)(nil),
|
|
||||||
nsSASL + " challenge": (*saslChallenge)(nil),
|
|
||||||
nsSASL + " response": (*saslResponse)(nil),
|
|
||||||
nsSASL + " abort": (*saslAbort)(nil),
|
|
||||||
nsSASL + " success": (*saslSuccess)(nil),
|
|
||||||
nsSASL + " failure": (*saslFailure)(nil),
|
|
||||||
|
|
||||||
nsBind + " bind": (*bindBind)(nil),
|
|
||||||
|
|
||||||
nsClient + " message": (*clientMessage)(nil),
|
|
||||||
nsClient + " presence": (*clientPresence)(nil),
|
|
||||||
nsClient + " iq": (*clientIQ)(nil),
|
|
||||||
nsClient + " error": (*clientError)(nil),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan XML token stream for next element and save into val.
|
// Scan XML token stream for next element and save into val.
|
||||||
// If val == nil, allocate new element based on proto map.
|
// If val == nil, allocate new element based on proto map.
|
||||||
// Either way, return val.
|
// Either way, return val.
|
||||||
@ -412,23 +387,36 @@ func next(p *xml.Parser) (xml.Name, interface{}, os.Error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return xml.Name{}, nil, err
|
return xml.Name{}, nil, err
|
||||||
}
|
}
|
||||||
v, ok := proto[se.Name.Space+" "+se.Name.Local]
|
|
||||||
if !ok {
|
// Put it in an interface and allocate one.
|
||||||
|
var nv interface{}
|
||||||
|
switch (se.Name.Space+" "+se.Name.Local) {
|
||||||
|
case nsStream + " features": nv = &streamFeatures{}
|
||||||
|
case nsStream + " error": nv = &streamError{}
|
||||||
|
case nsTLS + " starttls": nv = &tlsStartTLS{}
|
||||||
|
case nsTLS + " proceed": nv = &tlsProceed{}
|
||||||
|
case nsTLS + " failure": nv = &tlsFailure{}
|
||||||
|
case nsSASL + " mechanisms": nv = &saslMechanisms{}
|
||||||
|
case nsSASL + " challenge": nv = ""
|
||||||
|
case nsSASL + " response": nv = ""
|
||||||
|
case nsSASL + " abort": nv = &saslAbort{}
|
||||||
|
case nsSASL + " success": nv = &saslSuccess{}
|
||||||
|
case nsSASL + " failure": nv = &saslFailure{}
|
||||||
|
case nsBind + " bind": nv = &bindBind{}
|
||||||
|
case nsClient + " message": nv = &clientMessage{}
|
||||||
|
case nsClient + " presence": nv = &clientPresence{}
|
||||||
|
case nsClient + " iq": nv = &clientIQ{}
|
||||||
|
case nsClient + " error": nv = &clientError{}
|
||||||
|
default:
|
||||||
return xml.Name{}, nil, os.ErrorString("unexpected XMPP message " +
|
return xml.Name{}, nil, os.ErrorString("unexpected XMPP message " +
|
||||||
se.Name.Space + " <" + se.Name.Local + "/>")
|
se.Name.Space + " <" + se.Name.Local + "/>")
|
||||||
}
|
}
|
||||||
|
|
||||||
// The map lookup got us a pointer.
|
|
||||||
// Put it in an interface and allocate one.
|
|
||||||
pv := reflect.ValueOf(v)
|
|
||||||
zv := reflect.Zero(pv.Type().Elem())
|
|
||||||
pv.Set(zv.Addr())
|
|
||||||
|
|
||||||
// Unmarshal into that storage.
|
// Unmarshal into that storage.
|
||||||
if err = p.Unmarshal(pv.Interface(), &se); err != nil {
|
if err = p.Unmarshal(nv, &se); err != nil {
|
||||||
return xml.Name{}, nil, err
|
return xml.Name{}, nil, err
|
||||||
}
|
}
|
||||||
return se.Name, pv.Interface(), err
|
return se.Name, nv, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var xmlSpecial = map[byte]string{
|
var xmlSpecial = map[byte]string{
|
||||||
|
Loading…
Reference in New Issue
Block a user