github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/registry/storage/driver/azure/zerofillwriter.go (about) 1 package azure 2 3 import ( 4 "bytes" 5 "io" 6 ) 7 8 type blockBlobWriter interface { 9 GetSize(container, blob string) (int64, error) 10 WriteBlobAt(container, blob string, offset int64, chunk io.Reader) (int64, error) 11 } 12 13 // zeroFillWriter enables writing to an offset outside a block blob's size 14 // by offering the chunk to the underlying writer as a contiguous data with 15 // the gap in between filled with NUL (zero) bytes. 16 type zeroFillWriter struct { 17 blockBlobWriter 18 } 19 20 func newZeroFillWriter(b blockBlobWriter) zeroFillWriter { 21 w := zeroFillWriter{} 22 w.blockBlobWriter = b 23 return w 24 } 25 26 // Write writes the given chunk to the specified existing blob even though 27 // offset is out of blob's size. The gaps are filled with zeros. Returned 28 // written number count does not include zeros written. 29 func (z *zeroFillWriter) Write(container, blob string, offset int64, chunk io.Reader) (int64, error) { 30 size, err := z.blockBlobWriter.GetSize(container, blob) 31 if err != nil { 32 return 0, err 33 } 34 35 var reader io.Reader 36 var zeroPadding int64 37 if offset <= size { 38 reader = chunk 39 } else { 40 zeroPadding = offset - size 41 offset = size // adjust offset to be the append index 42 zeros := bytes.NewReader(make([]byte, zeroPadding)) 43 reader = io.MultiReader(zeros, chunk) 44 } 45 46 nn, err := z.blockBlobWriter.WriteBlobAt(container, blob, offset, reader) 47 nn -= zeroPadding 48 return nn, err 49 }