/// <summary> /// Creates a new stream that contains the XVA image. /// </summary> /// <returns>The new stream.</returns> public override SparseStream Build() { TarFileBuilder tarBuilder = new TarFileBuilder(); int[] diskIds; string ovaFileContent = GenerateOvaXml(out diskIds); tarBuilder.AddFile("ova.xml", Encoding.ASCII.GetBytes(ovaFileContent)); int diskIdx = 0; foreach (var diskRec in _disks) { SparseStream diskStream = diskRec.Second; List<StreamExtent> extents = new List<StreamExtent>(diskStream.Extents); int lastChunkAdded = -1; foreach (StreamExtent extent in extents) { int firstChunk = (int)(extent.Start / Sizes.OneMiB); int lastChunk = (int)((extent.Start + extent.Length - 1) / Sizes.OneMiB); for (int i = firstChunk; i <= lastChunk; ++i) { if (i != lastChunkAdded) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream; long diskBytesLeft = diskStream.Length - (i * Sizes.OneMiB); if (diskBytesLeft < Sizes.OneMiB) { chunkStream = new ConcatStream( Ownership.Dispose, new SubStream(diskStream, i * Sizes.OneMiB, diskBytesLeft), new ZeroStream(Sizes.OneMiB - diskBytesLeft)); } else { chunkStream = new SubStream(diskStream, i * Sizes.OneMiB, Sizes.OneMiB); } HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], i), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], i), new ChecksumStream(hashAlg)); lastChunkAdded = i; } } } // Make sure the last chunk is present, filled with zero's if necessary int lastActualChunk = (int)((diskStream.Length - 1) / Sizes.OneMiB); if (lastChunkAdded < lastActualChunk) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream = new ZeroStream(Sizes.OneMiB); HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], lastActualChunk), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], lastActualChunk), new ChecksumStream(hashAlg)); } ++diskIdx; } return tarBuilder.Build(); }
/// <summary> /// Creates a new stream that contains the XVA image. /// </summary> /// <returns>The new stream</returns> public override SparseStream Build() { TarFileBuilder tarBuilder = new TarFileBuilder(); int[] diskIds; string ovaFileContent = GenerateOvaXml(out diskIds); tarBuilder.AddFile("ova.xml", Encoding.ASCII.GetBytes(ovaFileContent)); int diskIdx = 0; foreach (var diskRec in _disks) { SparseStream diskStream = diskRec.Second; List <StreamExtent> extents = new List <StreamExtent>(diskStream.Extents); int lastChunkAdded = -1; foreach (StreamExtent extent in extents) { int firstChunk = (int)(extent.Start / Sizes.OneMiB); int lastChunk = (int)((extent.Start + extent.Length - 1) / Sizes.OneMiB); for (int i = firstChunk; i <= lastChunk; ++i) { if (i != lastChunkAdded) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream; long diskBytesLeft = diskStream.Length - (i * Sizes.OneMiB); if (diskBytesLeft < Sizes.OneMiB) { chunkStream = new ConcatStream( Ownership.Dispose, new SubStream(diskStream, i * Sizes.OneMiB, diskBytesLeft), new ZeroStream(Sizes.OneMiB - diskBytesLeft)); } else { chunkStream = new SubStream(diskStream, i * Sizes.OneMiB, Sizes.OneMiB); } HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], i), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], i), new ChecksumStream(hashAlg)); lastChunkAdded = i; } } } // Make sure the last chunk is present, filled with zero's if necessary int lastActualChunk = (int)((diskStream.Length - 1) / Sizes.OneMiB); if (lastChunkAdded < lastActualChunk) { HashAlgorithm hashAlg = new SHA1Managed(); Stream chunkStream = new ZeroStream(Sizes.OneMiB); HashStream chunkHashStream = new HashStream(chunkStream, Ownership.Dispose, hashAlg); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}", diskIds[diskIdx], lastActualChunk), chunkHashStream); tarBuilder.AddFile(string.Format(CultureInfo.InvariantCulture, "Ref:{0}/{1:D8}.checksum", diskIds[diskIdx], lastActualChunk), new ChecksumStream(hashAlg)); } ++diskIdx; } return(tarBuilder.Build()); }