| 668 | } |
| 669 | |
| 670 | Value serializeFileFromChunks(Standalone<IndexedBlobGranuleFile>& file, |
| 671 | Optional<BlobGranuleCipherKeysCtx> cipherKeysCtx, |
| 672 | std::vector<Value>& chunks, |
| 673 | int previousChunkBytes) { |
| 674 | Value indexBlockBytes = serializeIndexBlock(file, cipherKeysCtx); |
| 675 | int32_t indexSize = indexBlockBytes.size(); |
| 676 | chunks[0] = indexBlockBytes; |
| 677 | |
| 678 | // TODO: write this directly to stream to avoid extra copy? |
| 679 | Arena ret; |
| 680 | |
| 681 | size_t size = indexSize + previousChunkBytes; |
| 682 | uint8_t* buffer = new (ret) uint8_t[size]; |
| 683 | uint8_t* bufferStart = buffer; |
| 684 | |
| 685 | int idx = 0; |
| 686 | for (auto& it : chunks) { |
| 687 | if (BG_ENCRYPT_COMPRESS_DEBUG) { |
| 688 | TraceEvent(SevDebug, "SerializeFile") |
| 689 | .detail("ChunkIdx", idx++) |
| 690 | .detail("Size", it.size()) |
| 691 | .detail("Offset", buffer - bufferStart); |
| 692 | } |
| 693 | buffer = it.copyTo(buffer); |
| 694 | } |
| 695 | ASSERT(size == buffer - bufferStart); |
| 696 | |
| 697 | return Standalone<StringRef>(StringRef(bufferStart, size), ret); |
| 698 | } |
| 699 | |
| 700 | // TODO: this should probably be in actor file with yields? - move writing logic to separate actor file in server? |
| 701 | // TODO: optimize memory copying |
no test coverage detected