//Dynamic size entries are split into chunks that are spread around the file. We need to read per chunk unsafe ReadHandle ScheduleDynamicSizeElementArrayReads(Entry entry, uint elementOffset, uint elementCount, long readSize, void *buffer) { var block = m_Blocks[(int)entry.Header.BlockIndex]; byte *dst = (byte *)buffer; var chunkReads = new NativeBlockList <ReadCommand>(64, 64); for (int i = 0; i < elementCount; ++i) { var e = new ElementRead(); e.start = entry.GetAdditionalStoragePtr()[i + elementOffset]; e.end = i + elementOffset + 1 == entry.Count ? (long)entry.Header.HeaderMeta : entry.GetAdditionalStoragePtr()[i + elementOffset + 1]; e.readDst = dst; var readOffset = ProcessDynamicSizeElement(ref chunkReads, ref block, e); dst += readOffset; readSize -= readOffset; } Checks.CheckEquals(0, readSize); //TODO: find a way to use the block array chunks directly for scheduling, probably add readcommandbuffer using (NativeArray <ReadCommand> readCommands = new NativeArray <ReadCommand>((int)chunkReads.Count, Allocator.Temp)) { var cmdsPtr = (ReadCommand *)readCommands.GetUnsafePtr(); for (int i = 0; i < readCommands.Length; ++i) { *(cmdsPtr + i) = chunkReads[i]; } chunkReads.Dispose(); return(m_FileReader.Read(cmdsPtr, (uint)readCommands.Length, ReadMode.Async)); } }
//Returns ammount of written bytes unsafe static long ProcessDynamicSizeElement(ref NativeBlockList <ReadCommand> chunkReads, ref Block block, ElementRead elementRead) { long written = 0; var chunkSize = (long)block.Header.ChunkSize; var elementSize = elementRead.end - elementRead.start; var dst = elementRead.readDst; var chunkIndex = elementRead.start / chunkSize; var chunkOffset = block.GetOffsetsPtr()[chunkIndex]; var elementOffsetInChunk = elementRead.start % chunkSize; var remainingChunksize = chunkSize - elementOffsetInChunk; var rSize = Math.Min(chunkSize, elementSize); if (remainingChunksize != chunkSize) { chunkOffset += elementOffsetInChunk; //align the read if (rSize > remainingChunksize) { rSize = remainingChunksize; } } chunkReads.Push(ReadCommandBufferUtils.GetCommand(elementRead.readDst, rSize, chunkOffset)); elementRead.readDst += rSize; elementSize -= rSize; written += rSize; //if the element spans multiple chunks while (elementSize > 0) { chunkIndex++; chunkOffset = block.GetOffsetsPtr()[chunkIndex]; rSize = Math.Min(chunkSize, elementSize); chunkReads.Push(ReadCommandBufferUtils.GetCommand(elementRead.readDst, rSize, chunkOffset)); elementRead.readDst += rSize; elementSize -= rSize; written += rSize; } return(written); }