Files
questshock/modding/hacked/ss1/resource/lgres/FragmentedChunkWriter.go
T

65 lines
2.0 KiB
Go

package lgres
import (
"io"
"github.com/inkyblackness/hacked/ss1/resource/lgres/internal/compression"
"github.com/inkyblackness/hacked/ss1/serial"
)
// CompoundResourceWriter writes a resource with zero, one, or more blocks.
// Multiple blocks can be created and then written concurrently. Only when the
// resource is finished, the blocks are finalized.
type CompoundResourceWriter struct {
target *serial.PositioningEncoder
compressed bool
dataPaddingSize int
blockStores []*serial.ByteStore
blockWriter []*BlockWriter
}
// CreateBlock provides a new, dedicated writer for a new block.
func (writer *CompoundResourceWriter) CreateBlock() *BlockWriter {
store := serial.NewByteStore()
blockWriter := &BlockWriter{target: serial.NewEncoder(store), finisher: func() {}}
writer.blockStores = append(writer.blockStores, store)
writer.blockWriter = append(writer.blockWriter, blockWriter)
return blockWriter
}
func (writer *CompoundResourceWriter) finish() (length uint32) {
var unpackedSize uint32
blockCount := len(writer.blockStores)
writer.target.Code(uint16(blockCount))
offset := 2 + (blockCount+1)*4 + writer.dataPaddingSize
for index, store := range writer.blockStores {
unpackedSize += writer.blockWriter[index].finish()
writer.target.Code(uint32(offset))
offset += len(store.Data())
}
writer.target.Code(uint32(offset))
unpackedSize += writer.target.CurPos() + uint32(writer.dataPaddingSize)
writer.writeBlocks()
return unpackedSize
}
func (writer *CompoundResourceWriter) writeBlocks() {
var targetWriter io.Writer = writer.target
targetFinisher := func() {}
if writer.compressed {
compressor := compression.NewCompressor(targetWriter)
targetWriter = compressor
targetFinisher = func() { compressor.Close() } // nolint: errcheck
}
for i := 0; i < writer.dataPaddingSize; i++ {
targetWriter.Write([]byte{0x00}) // nolint: errcheck
}
for _, store := range writer.blockStores {
targetWriter.Write(store.Data()) // nolint: errcheck
}
targetFinisher()
}