func makeSigWriter(wc *wire.WriteContext) wsync.SignatureWriter { return func(bl wsync.BlockHash) error { return wc.WriteMessage(&BlockHash{ WeakHash: bl.WeakHash, StrongHash: bl.StrongHash, }) } }
// CompressWire wraps a wire.WriteContext into a compressor, according to given settings, // so that any messages written through the returned WriteContext will first be compressed. func CompressWire(ctx *wire.WriteContext, compression *CompressionSettings) (*wire.WriteContext, error) { if compression == nil { return nil, errors.Wrap(fmt.Errorf("no compression specified"), 1) } if compression.Algorithm == CompressionAlgorithm_NONE { return ctx, nil } compressor := compressors[compression.Algorithm] if compressor == nil { return nil, errors.Wrap(fmt.Errorf("no compressor registered for %s", compression.Algorithm.String()), 1) } compressedWriter, err := compressor.Apply(ctx.Writer(), compression.Quality) if err != nil { return nil, errors.Wrap(err, 1) } return wire.NewWriteContext(compressedWriter), nil }
func makeOpsWriter(wc *wire.WriteContext, dctx *DiffContext) wsync.OperationWriter { numOps := 0 wop := &SyncOp{} files := dctx.TargetContainer.Files return func(op wsync.Operation) error { numOps++ wop.Reset() switch op.Type { case wsync.OpBlockRange: wop.Type = SyncOp_BLOCK_RANGE wop.FileIndex = op.FileIndex wop.BlockIndex = op.BlockIndex wop.BlockSpan = op.BlockSpan fileSize := files[op.FileIndex].Size lastBlockIndex := op.BlockIndex + op.BlockSpan - 1 tailSize := ComputeBlockSize(fileSize, lastBlockIndex) dctx.ReusedBytes += BlockSize*(op.BlockSpan-1) + tailSize case wsync.OpData: wop.Type = SyncOp_DATA wop.Data = op.Data dctx.FreshBytes += int64(len(op.Data)) default: return errors.Wrap(fmt.Errorf("unknown rsync op type: %d", op.Type), 1) } err := wc.WriteMessage(wop) if err != nil { return errors.Wrap(err, 1) } return nil } }
// Do only create a file at WoundsPath when it receives the first wound. // If no wounds are ever received, Do will effectively be a no-op. func (ww *WoundsWriter) Do(container *tlc.Container, wounds chan *Wound) error { var fw *os.File var wc *wire.WriteContext defer func() { if wc != nil { wc.Close() } if fw != nil { fw.Close() } }() writeWound := func(wound *Wound) error { ww.totalCorrupted += wound.Size() if wc == nil { var err error fw, err = os.Create(ww.WoundsPath) if err != nil { return errors.Wrap(err, 1) } wc = wire.NewWriteContext(fw) if err != nil { return errors.Wrap(err, 1) } err = wc.WriteMagic(WoundsMagic) if err != nil { return errors.Wrap(err, 1) } err = wc.WriteMessage(&WoundsHeader{}) if err != nil { return errors.Wrap(err, 1) } err = wc.WriteMessage(container) if err != nil { return errors.Wrap(err, 1) } } err := wc.WriteMessage(wound) if err != nil { return errors.Wrap(err, 1) } return nil } for wound := range wounds { if wound.Healthy() { continue } ww.hasWounds = true err := writeWound(wound) if err != nil { return err } } return nil }