mirror of https://github.com/gwuhaolin/livego.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.1 KiB
127 lines
3.1 KiB
package amf |
|
|
|
import ( |
|
"fmt" |
|
"io" |
|
"math" |
|
) |
|
|
|
// Abstract external boilerplate |
|
func (d *Decoder) decodeAbstractMessage(r io.Reader) (result Object, err error) { |
|
result = make(Object) |
|
|
|
if err = d.decodeExternal(r, &result, |
|
[]string{"body", "clientId", "destination", "headers", "messageId", "timeStamp", "timeToLive"}, |
|
[]string{"clientIdBytes", "messageIdBytes"}); err != nil { |
|
return result, fmt.Errorf("unable to decode abstract external: %s", err) |
|
} |
|
|
|
return |
|
} |
|
|
|
// DSA |
|
func (d *Decoder) decodeAsyncMessageExt(r io.Reader) (result Object, err error) { |
|
return d.decodeAsyncMessage(r) |
|
} |
|
func (d *Decoder) decodeAsyncMessage(r io.Reader) (result Object, err error) { |
|
result, err = d.decodeAbstractMessage(r) |
|
if err != nil { |
|
return result, fmt.Errorf("unable to decode abstract for async: %s", err) |
|
} |
|
|
|
if err = d.decodeExternal(r, &result, []string{"correlationId", "correlationIdBytes"}); err != nil { |
|
return result, fmt.Errorf("unable to decode async external: %s", err) |
|
} |
|
|
|
return |
|
} |
|
|
|
// DSK |
|
func (d *Decoder) decodeAcknowledgeMessageExt(r io.Reader) (result Object, err error) { |
|
return d.decodeAcknowledgeMessage(r) |
|
} |
|
func (d *Decoder) decodeAcknowledgeMessage(r io.Reader) (result Object, err error) { |
|
result, err = d.decodeAsyncMessage(r) |
|
if err != nil { |
|
return result, fmt.Errorf("unable to decode async for ack: %s", err) |
|
} |
|
|
|
if err = d.decodeExternal(r, &result); err != nil { |
|
return result, fmt.Errorf("unable to decode ack external: %s", err) |
|
} |
|
|
|
return |
|
} |
|
|
|
// flex.messaging.io.ArrayCollection |
|
func (d *Decoder) decodeArrayCollection(r io.Reader) (interface{}, error) { |
|
result, err := d.DecodeAmf3(r) |
|
if err != nil { |
|
return result, fmt.Errorf("cannot decode child of array collection: %s", err) |
|
} |
|
|
|
return result, nil |
|
} |
|
|
|
func (d *Decoder) decodeExternal(r io.Reader, obj *Object, fieldSets ...[]string) (err error) { |
|
var flagSet []uint8 |
|
var reservedPosition uint8 |
|
var fieldNames []string |
|
|
|
flagSet, err = readFlags(r) |
|
if err != nil { |
|
return fmt.Errorf("unable to read flags: %s", err) |
|
} |
|
|
|
for i, flags := range flagSet { |
|
if i < len(fieldSets) { |
|
fieldNames = fieldSets[i] |
|
} else { |
|
fieldNames = []string{} |
|
} |
|
|
|
reservedPosition = uint8(len(fieldNames)) |
|
|
|
for p, field := range fieldNames { |
|
flagBit := uint8(math.Exp2(float64(p))) |
|
if (flags & flagBit) != 0 { |
|
tmp, err := d.DecodeAmf3(r) |
|
if err != nil { |
|
return fmt.Errorf("unable to decode external field %s %d %d (%#v): %s", field, i, p, flagSet, err) |
|
} |
|
(*obj)[field] = tmp |
|
} |
|
} |
|
|
|
if (flags >> reservedPosition) != 0 { |
|
for j := reservedPosition; j < 6; j++ { |
|
if ((flags >> j) & 0x01) != 0 { |
|
field := fmt.Sprintf("extra_%d_%d", i, j) |
|
tmp, err := d.DecodeAmf3(r) |
|
if err != nil { |
|
return fmt.Errorf("unable to decode post-external field %d %d (%#v): %s", i, j, flagSet, err) |
|
} |
|
(*obj)[field] = tmp |
|
} |
|
} |
|
} |
|
} |
|
|
|
return |
|
} |
|
|
|
func readFlags(r io.Reader) (result []uint8, err error) { |
|
for { |
|
flag, err := ReadByte(r) |
|
if err != nil { |
|
return result, fmt.Errorf("unable to read flags: %s", err) |
|
} |
|
|
|
result = append(result, flag) |
|
if (flag & 0x80) == 0 { |
|
break |
|
} |
|
} |
|
|
|
return |
|
}
|
|
|