Skip to content

Commit

Permalink
Implement amf3 packing, fix amf3 extraction bug with empty arrays bec…
Browse files Browse the repository at this point in the history
…oming null, rename flate functions
  • Loading branch information
blead committed Aug 17, 2024
1 parent ed4b97d commit 69781f0
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 8 deletions.
58 changes: 54 additions & 4 deletions pkg/encoding/amf3.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@ package encoding
import (
"bytes"
"encoding/json"
"fmt"
"strings"

amf "github.com/remyoudompheng/goamf"
)

// Amf3ToJSON converts Adobe AMF3 to JSON.
func Amf3ToJSON(raw []byte, indent int) ([]byte, error) {
data, err := deflate(raw)
data, err := inflate(raw)
if err != nil {
return nil, err
return nil, fmt.Errorf("flate decompress error, %w", err)
}

d := amf.NewDecoder()
amf3, err := d.DecodeAmf3(bytes.NewReader(data))
if err != nil {
return nil, err
return nil, fmt.Errorf("amf3 decode error, %w", err)
}

js, err := jsonMarshalNoEscape(amf3)
js, err := jsonMarshalNoEscape(initAmfTypes(amf3))
if err != nil {
return nil, err
}
Expand All @@ -31,3 +32,52 @@ func Amf3ToJSON(raw []byte, indent int) ([]byte, error) {

return output.Bytes(), err
}

// JSONToAmf3 converts JSON to Adobe AMF3
func JSONToAmf3(js []byte) ([]byte, error) {
var data any
err := json.Unmarshal(js, &data)
if err != nil {
return nil, err
}

var amf3 bytes.Buffer
e := new(amf.Encoder)
_, err = e.EncodeAmf3(&amf3, initAmfTypes(data))
if err != nil {
return nil, err
}

return deflate(amf3.Bytes())
}

// 1. empty arrays/maps returned from goamf.Decoder#DecodeAmf3 are nil pointers so they need to be initialized before marshalling to JSON
// 2. primitive map[string]any needs to be converted to goamf.Object first for goamf.Encoder#EncodeAmf3 to work properly
func initAmfTypes(p any) any {
switch v := p.(type) {
case map[string]any, amf.Object:
val, ok := v.(map[string]any)
if !ok {
val = map[string]any(v.(amf.Object))
}

obj := make(amf.Object)
for key, value := range val {
obj[key] = initAmfTypes(value)
}
return obj
case []any, amf.Array:
val, ok := v.([]any)
if !ok {
val = []any(v.(amf.Array))
}

arr := make(amf.Array, len(val))
for i, value := range val {
arr[i] = initAmfTypes(value)
}
return arr
default:
return v
}
}
25 changes: 24 additions & 1 deletion pkg/encoding/flate.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,30 @@ import (
"io"
)

func deflate(compressed []byte) ([]byte, error) {
// deflate compresses raw bytes
func deflate(raw []byte) ([]byte, error) {
var output bytes.Buffer
zw, err := flate.NewWriter(&output, flate.DefaultCompression)
if err != nil {
return nil, err
}
defer zw.Close()

_, err = zw.Write(raw)
if err != nil {
return nil, err
}

err = zw.Close()
if err != nil {
return nil, err
}

return output.Bytes(), nil
}

// inflate decompresses deflate-encoded bytes
func inflate(compressed []byte) ([]byte, error) {
zr := flate.NewReader(bytes.NewReader(compressed))
defer zr.Close()

Expand Down
8 changes: 6 additions & 2 deletions pkg/wf/packer.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,12 @@ func NewPacker(config *PackerConfig) (*Packer, error) {
}

parsers := []parser{
// &amf3Parser{ext: ".action.dsl"},
// &esdlParser{&amf3Parser{ext: ".esdl"}},
&amf3Parser{ext: ".action.dsl"},
&amf3Parser{ext: ".atlas"},
&amf3Parser{ext: ".frame"},
&amf3Parser{ext: ".parts"},
&amf3Parser{ext: ".timeline"},
&esdlParser{&amf3Parser{ext: ".esdl"}},
&pngParser{},
&orderedmapParser{}, // needs to be last because of ambiguous file extension
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/wf/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func (parser *amf3Parser) matchDest(dest string, config *PackerConfig) (string,
}

func (*amf3Parser) unparse(raw []byte, config *PackerConfig) ([]byte, error) {
return nil, fmt.Errorf("unparse amf3Parser: not implemented")
return encoding.JSONToAmf3(raw)
}

type esdlParser struct {
Expand Down

0 comments on commit 69781f0

Please sign in to comment.