rv = APR_EOF;
break;
}
else if (bytesread == -1) {
rv = errno;
break;
}
thefile->dataRead = bytesread;
thefile->filePtr += thefile->dataRead;
thefile->bufpos = 0;
}
blocksize = size > thefile->dataRead - thefile->bufpos ? thefile->dataRead - thefile->bufpos : size;
memcpy(pos, thefile->buffer + thefile->bufpos, blocksize);
thefile->bufpos += blocksize;
pos += blocksize;
size -= blocksize;
}
while循环读取的核心代码就位于while循环中。dataRead是实际读取到缓冲区中的数据的长度,当然它肯定小于或者等于实际的文件的总长度。bufpos则是用户读取的缓冲区中的实际字节数目,当然bufpos肯定也是小于或者等于dataRead的。它们的关系如上图所示。用户如果从缓冲区中读取数据的话它最多只能读取到dataRead字节的长度。当用户从缓冲区中读取数据的时候,缓冲区的内部的指针变量bufpos不断往后移动。
函数将根据bufpos的位置做不同的策略:
(1)、起始的时候,bufpos=0,缓冲区中的数据为dataRead,用户请求的数据为size大小。此时将开始尝试读取缓冲区中的数据。如果请求的字节小于缓冲区的dataRead长度,那么直接将缓冲区中size大小的数据拷贝到输出缓冲区pos中。这种情况是最简单的一种。
由于filepos为0,这时候执行的代码将演变为如下:
blocksize = size;//size > thefile->dataRead -0 ? thefile->dataRead: size;
memcpy(pos, thefile->buffer + 0, blocksize);
thefile->bufpos += blocksize;
pos += size;
size -= size;
(2)、当bufpos=0,即开始读取的时候,如果用户请求的数据长度超出了dataRead的长度,那么此时用户第一次读取只能读取到dataRead的数据,还剩余size-dataRead需要从文件中读取。因此,第一次的读取演变为如下的代码: