package kgm import ( "fmt" "io" "github.com/unlock-music/cli/algo/common" ) type Decoder struct { header header cipher common.StreamDecoder rd io.ReadSeeker offset int } func NewDecoder(rd io.ReadSeeker) common.Decoder { return &Decoder{rd: rd} } var kgmCryptoInitializers = map[uint32]func(header *header) (common.StreamDecoder, error){ 3: newKgmCryptoV3, } func (d *Decoder) Validate() error { if err := d.header.FromFile(d.rd); err != nil { return err } // TODO; validate crypto version initializer, ok := kgmCryptoInitializers[d.header.CryptoVersion] if !ok { return fmt.Errorf("kgm: unsupported crypto version %d", d.header.CryptoVersion) } var err error d.cipher, err = initializer(&d.header) if err != nil { return fmt.Errorf("kgm: failed to initialize crypto: %w", err) } return nil } func (d *Decoder) Read(buf []byte) (int, error) { n, err := d.rd.Read(buf) if n > 0 { d.cipher.Decrypt(buf[:n], d.offset) d.offset += n } return n, err } func init() { // Kugou common.RegisterDecoder("kgm", false, NewDecoder) common.RegisterDecoder("kgma", false, NewDecoder) // Viper common.RegisterDecoder("vpr", false, NewDecoder) }