package lgres import ( "fmt" "io" "github.com/inkyblackness/hacked/ss1/resource" ) type resourceInconsistentError struct { ID resource.ID BlockCount int } func (err resourceInconsistentError) Error() string { return fmt.Sprintf("simple resource %v has invalid number of blocks: %d", err.ID, err.BlockCount) } // Write serializes the resources from given source into the target. // It is a convenience function for using Writer. func Write(target io.WriteSeeker, source resource.Viewer) error { writer, writerErr := NewWriter(target) if writerErr != nil { return writerErr } for _, id := range source.IDs() { entry, resourceErr := source.View(id) if resourceErr != nil { return resourceErr } switch { case entry.Compound(): resourceWriter, resourceWriterErr := writer.CreateCompoundResource(id, entry.ContentType(), entry.Compressed()) if resourceWriterErr != nil { return resourceWriterErr } copyErr := copyBlocks(entry, func() io.Writer { return resourceWriter.CreateBlock() }) if copyErr != nil { return copyErr } case entry.BlockCount() == 1: blockWriter, resourceWriterErr := writer.CreateResource(id, entry.ContentType(), entry.Compressed()) if resourceWriterErr != nil { return resourceWriterErr } copyErr := copyBlocks(entry, func() io.Writer { return blockWriter }) if copyErr != nil { return copyErr } default: return resourceInconsistentError{ID: id, BlockCount: entry.BlockCount()} } } return writer.Finish() } func copyBlocks(source resource.BlockProvider, nextWriter func() io.Writer) error { for blockIndex := 0; blockIndex < source.BlockCount(); blockIndex++ { blockReader, blockErr := source.Block(blockIndex) if blockErr != nil { return blockErr } _, copyErr := io.Copy(nextWriter(), blockReader) if copyErr != nil { return copyErr } } return nil }