mirror of
https://github.com/fhmq/hmq.git
synced 2026-09-01 23:34:52 +00:00
Plugins support (#46)
* modify * update * add acl * add feature * update dockerfile * add deploy * update * update * plugins * plugins * update * update * update * fixed * remove * fixed * add log * update * fixed * update * fix config * add http api * add http api * resp * add config for work chan * update * fixed * update * disable trace * fixed * change acl * fixed * fixed res * dd * dd * ddd * dd * update * fixed * update * add * fixed * update key * add log * update * format * update * update auth * update * update readme * added * update * fixed * fixed * fix * upade * update * update
This commit is contained in:
+57
@@ -0,0 +1,57 @@
|
||||
package ndr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Union interface must be implemented by structs that will be unmarshaled into from the NDR byte stream union representation.
|
||||
// The union's discriminating tag will be passed to the SwitchFunc method.
|
||||
// The discriminating tag field must have the struct tag: `ndr:"unionTag"`
|
||||
// If the union is encapsulated the discriminating tag field must have the struct tag: `ndr:"encapsulated"`
|
||||
// The possible value fields that can be selected from must have the struct tag: `ndr:"unionField"`
|
||||
type Union interface {
|
||||
SwitchFunc(t interface{}) string
|
||||
}
|
||||
|
||||
// Union related constants such as struct tag values
|
||||
const (
|
||||
unionSelectionFuncName = "SwitchFunc"
|
||||
TagEncapsulated = "encapsulated"
|
||||
TagUnionTag = "unionTag"
|
||||
TagUnionField = "unionField"
|
||||
)
|
||||
|
||||
func (dec *Decoder) isUnion(field reflect.Value, tag reflect.StructTag) (r reflect.Value) {
|
||||
ndrTag := parseTags(tag)
|
||||
if !ndrTag.HasValue(TagUnionTag) {
|
||||
return
|
||||
}
|
||||
r = field
|
||||
// For a non-encapsulated union, the discriminant is marshalled into the transmitted data stream twice: once as the
|
||||
// field or parameter, which is referenced by the switch_is construct, in the procedure argument list; and once as
|
||||
// the first part of the union representation.
|
||||
if !ndrTag.HasValue(TagEncapsulated) {
|
||||
dec.r.Discard(int(r.Type().Size()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// unionSelectedField returns the field name of which of the union values to fill
|
||||
func unionSelectedField(union, discriminant reflect.Value) (string, error) {
|
||||
if !union.Type().Implements(reflect.TypeOf(new(Union)).Elem()) {
|
||||
return "", errors.New("struct does not implement union interface")
|
||||
}
|
||||
args := []reflect.Value{discriminant}
|
||||
// Call the SelectFunc of the union struct to find the name of the field to fill with the value selected.
|
||||
sf := union.MethodByName(unionSelectionFuncName)
|
||||
if !sf.IsValid() {
|
||||
return "", fmt.Errorf("could not find a selection function called %s in the unions struct representation", unionSelectionFuncName)
|
||||
}
|
||||
f := sf.Call(args)
|
||||
if f[0].Kind() != reflect.String || f[0].String() == "" {
|
||||
return "", fmt.Errorf("the union select function did not return a string for the name of the field to fill")
|
||||
}
|
||||
return f[0].String(), nil
|
||||
}
|
||||
Reference in New Issue
Block a user