我正在阅读内部 SeqAn 库(它处理特定于生物学的文件格式和数据结构),并且遇到了我不太了解的 C++ 习语。
有一个唯一的 id 变量record.rID
是 __int32。指向它的指针被传递给另一个函数,该函数从文件中读取一堆数据并改变 id。
这是电话:
res = streamReadBlock(reinterpret_cast<char *>(&record.rID), stream, 4);
下面是函数实现:
inline size_t
streamReadBlock(char * target, Stream<Bgzf> & stream, size_t maxLen)
{
if (!(stream._openMode & OPEN_RDONLY))
return 0; // File not open for reading.
// Memoize number of read bytes and pointer into the buffer target.
size_t bytesRead = 0;
char * destPtr = target;
// Read at most maxLen characters, each loop iteration corresponds to reading the end of the first, the beginning of
// the last or the whole "middle" buffers. Of course, the first and only iteration can also only read parts of the
// first buffer.
while (bytesRead < maxLen)
{
// If there are no more bytes left in the current block then read and decompress the next block.
int available = stream._blockLength - stream._blockOffset;
if (available <= 0)
{
if (_bgzfReadBlock(stream) != 0)
return -1; // Could not read next block.
available = stream._blockLength - stream._blockOffset;
if (available <= 0)
break;
}
// Copy out the number of bytes to be read or the number of available bytes in the next buffer, whichever number
// is smaller.
int copyLength = std::min(static_cast<int>(maxLen - bytesRead), available);
char * buffer = &stream._uncompressedBlock[0];
memcpy(destPtr, buffer + stream._blockOffset, copyLength);
// Advance to next block.
stream._blockOffset += copyLength;
destPtr += copyLength;
bytesRead += copyLength;
}
// If we read to the end of the block above then switch the block address to the next block and mark it as unread.
if (stream._blockOffset == stream._blockLength)
{
stream._blockPosition = tell(stream._file);
stream._blockOffset = 0;
stream._blockLength = 0;
}
return bytesRead;
}
进行一些跟踪,我可以看到 record.rID 被分配在那里,我猜这是memcpy(destPtr, buffer + stream._blockOffset, copyLength);
发生在哪里,但我不太明白发生了什么以及如何分配有意义的记录 id(但后来我没有没有太多处理这种反序列化代码的经验)。