go-studybox/rom/write.go

131 lines
2.7 KiB
Go

package rom
import (
"bytes"
"encoding/binary"
"fmt"
"os"
)
func (sb *StudyBox) Write(filename string) error {
raw, err := sb.rawBytes()
if err != nil {
return err
}
if filename == "" {
filename = "output.studybox"
}
fmt.Println("Writing to " + filename)
return os.WriteFile(filename, raw, 0777)
}
func (sb *StudyBox) rawBytes() ([]byte, error) {
buffer := &bytes.Buffer{}
_, err := buffer.WriteString("STBX")
if err != nil {
return nil, err
}
// Remaining field length
err = binary.Write(buffer, binary.LittleEndian, uint32(4))
if err != nil {
return nil, fmt.Errorf("Error writing field length: %v", err)
}
// Version number (* 0x100)
err = binary.Write(buffer, binary.LittleEndian, uint32(1*0x100))
if err != nil {
return nil, fmt.Errorf("Error writing version: %v", err)
}
for _, page := range sb.Data.Pages {
raw, err := page.rawBytes()
if err != nil {
return nil, err
}
_, err = buffer.Write(raw)
if err != nil {
return nil, err
}
}
_, err = buffer.WriteString("AUDI")
if err != nil {
return nil, err
}
err = binary.Write(buffer, binary.LittleEndian, uint32(len(sb.Audio.Data)))
if err != nil {
return nil, err
}
var format uint32
switch sb.Audio.Format {
case AUDIO_WAV:
format = 0
case AUDIO_FLAC:
format = 1
case AUDIO_OGG:
format = 2
case AUDIO_MP3:
format = 3
default:
return nil, fmt.Errorf("Unsupported audio format: %s", sb.Audio.Format)
}
err = binary.Write(buffer, binary.LittleEndian, format)
if err != nil {
return nil, err
}
// For some reason there's 4 extra bytes. no idea why. chomp them off.
_, err = buffer.Write(sb.Audio.Data[0 : uint32(len(sb.Audio.Data))-4])
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}
func (page *Page) rawBytes() ([]byte, error) {
fieldBuffer := &bytes.Buffer{}
err := binary.Write(fieldBuffer, binary.LittleEndian, uint32(page.AudioOffsetLeadIn))
if err != nil {
return nil, err
}
err = binary.Write(fieldBuffer, binary.LittleEndian, uint32(page.AudioOffsetData))
if err != nil {
return nil, err
}
for _, packet := range page.Packets {
_, err = fieldBuffer.Write(packet.RawBytes())
if err != nil {
return nil, err
}
}
pageBuffer := &bytes.Buffer{}
_, err = pageBuffer.WriteString("PAGE")
if err != nil {
return nil, err
}
err = binary.Write(pageBuffer, binary.LittleEndian, uint32(fieldBuffer.Len()))
if err != nil {
return nil, err
}
_, err = pageBuffer.Write(fieldBuffer.Bytes())
if err != nil {
return nil, err
}
return pageBuffer.Bytes(), nil
}