diff --git a/rtmp/amf/amf.go b/rtmp/amf/amf.go index 0369ad82..c6806ad9 100644 --- a/rtmp/amf/amf.go +++ b/rtmp/amf/amf.go @@ -210,6 +210,8 @@ func EncodeBoolean(buf []byte, val bool) ([]byte, error) { buf[0] = typeBoolean if val { buf[1] = 1 + } else { + buf[1] = 0 } if len(buf) == 2 { return nil, ErrEndOfBuffer @@ -277,14 +279,13 @@ func PropEncode(p *Property, buf []byte) ([]byte, error) { buf = buf[len(p.Name):] } - var err error switch p.Type { case typeNumber: - buf, err = EncodeNumber(buf, p.Number) + return EncodeNumber(buf, p.Number) case typeBoolean: - buf, err = EncodeBoolean(buf, p.Number != 0) + return EncodeBoolean(buf, p.Number != 0) case typeString: - buf, err = EncodeString(buf, p.String) + return EncodeString(buf, p.String) case TypeNull: if len(buf) < 2 { return nil, ErrShortBuffer @@ -292,15 +293,15 @@ func PropEncode(p *Property, buf []byte) ([]byte, error) { buf[0] = TypeNull buf = buf[1:] case TypeObject: - buf, err = Encode(&p.Object, buf) + return Encode(&p.Object, buf) case typeEcmaArray: - buf, err = EncodeEcmaArray(&p.Object, buf) + return EncodeEcmaArray(&p.Object, buf) case typeStrictArray: - buf, err = EncodeArray(&p.Object, buf) + return EncodeArray(&p.Object, buf) default: - buf, err = nil, ErrInvalidType + return nil, ErrInvalidType } - return buf, err + return buf, nil } // PropDecode decodes a property, returning the number of bytes consumed from the supplied buffer. @@ -341,7 +342,11 @@ func PropDecode(prop *Property, buf []byte, decodeName bool) (int, error) { buf = buf[8:] case typeBoolean: - return 0, ErrUnimplemented + if len(buf) < 1 { + return 0, ErrShortBuffer + } + prop.Number = float64(uint8(buf[0])) + buf = buf[1:] case typeString: n := DecodeInt16(buf[:2]) diff --git a/rtmp/amf/amf_test.go b/rtmp/amf/amf_test.go index 9d19427b..cfca16c8 100644 --- a/rtmp/amf/amf_test.go +++ b/rtmp/amf/amf_test.go @@ -186,12 +186,35 @@ func TestObject(t *testing.T) { t.Errorf("Decode of object failed") } + // Change the object's property to a boolean. + obj1.Props[0].Type = typeBoolean + obj1.Props[0].Number = 1 + + // Re-encode it + enc = buf[:] + enc, err = Encode(&obj1, enc) + if err != nil { + t.Errorf("Encode of object failed") + } + + // Re-decode it. + dec = buf[1:] + _, err = Decode(&dobj1, dec, false) + if err != nil { + t.Errorf("Decode of object failed with error: %v", err) + } + if dobj1.Props[0].Number != 1 { + t.Errorf("Decoded wrong boolean value") + } + // Construct a more complicated object. var obj2 Object for i, _ := range testStrings { obj2.Props = append(obj2.Props, Property{Type: typeString, String: testStrings[i]}) obj2.Props = append(obj2.Props, Property{Type: typeNumber, Number: float64(testNumbers[i])}) } + obj2.Props = append(obj2.Props, Property{Type: typeBoolean, Number: 0}) + obj2.Props = append(obj2.Props, Property{Type: typeBoolean, Number: 1}) // Encode it. enc = buf[:] @@ -205,7 +228,7 @@ func TestObject(t *testing.T) { var dobj2 Object _, err = Decode(&dobj2, dec, false) if err != nil { - t.Errorf("Decode of object failed") + t.Errorf("Decode of object failed with error: %v", err) } // Find some properties that exist. @@ -223,6 +246,14 @@ func TestObject(t *testing.T) { if prop.Number != 1 { t.Errorf("GetProp(1) returned wrong Property") } + prop, err = obj2.GetProp("", 9) + if err != nil { + t.Errorf("GetProp(9) failed") + return + } + if prop.Type != typeBoolean && prop.Number != 1 { + t.Errorf("GetProp(9) returned wrong Property") + } // Try to find one that doesn't exist. prop, err = obj2.GetProp("", 10)