📄 fio.c
字号:
// either the required block is not found or the required block
// is the currnet block
if (curBlock == NULL)
{
// the required block is not found
pfile->currentBlock = NULL;
pfile->blockfpos = 0;
RDerrno = ERROR_FILE_STRUCTURE;
return 0;
}
// the required block is already the current block
}
// the file position now points to the current block which is uncompressed
curBlock = pfile->currentBlock;
remains = size;
// part 1: copy the data from the current block to the user-provided buffer
// the size of data from the file position to the end of the block
curSize = pfile->blockfpos + curBlock->actualSize - pfile->fpos;
if (remains <= curSize)
{
// the current block has enough data to satisfy the read operation
curSize = remains;
}
src = (unsigned char *)((unsigned long)curBlock + B_HEADER + (pfile->fpos - pfile->blockfpos));
prevBlock = curBlock;
if ((pfile->fileFlag & O_TEXT) == O_TEXT)
{
for (i = 0; i < curSize; i++)
{
if (*src == '\r' && curSize > 1)
{
if ((src + 1) < ((unsigned char*)curBlock + B_HEADER + curBlock->actualSize))
{
if ((*(src+1)) == '\n')
{
// skip '\r'
readCount -= 1;
src++;
continue;
}
}
else
{
// read the next block and check if the first character is '\n'
curBlock = curBlock->nextBlock;
// the new current block
pfile->currentBlock = curBlock;
#ifdef RAMDISK_COMPRESS_USE_ZLIB
// one more file handle is using this block
(pfile->currentBlock)->userCount++;
// uncompress the block if necessary
if (uncompressCurrentBlock(pfile) == -1)
{
pfile->currentBlock = NULL;
pfile->blockfpos = 0;
return i;
}
curBlock = pfile->currentBlock;
#endif
if (curBlock != NULL)
{
if (*((unsigned char*)curBlock + B_HEADER) == '\n')
{
// skip '\r'
readCount -= 1;
// we've reached the end of the block
break;
}
// compress the previous block if necessary
#ifdef RAMDISK_COMPRESS_USE_ZLIB
compressCurrentBlock(pfile);
// one less file handle is using this block
(pfile->currentBlock)->userCount--;
#endif
}
}
}
*buffer++ = *src++;
}
}
else // binary mode
{
// if both buffers are 4 byte-aligned
if ( (long)buffer % 4 == 0 && (long)src % 4 == 0)
{
for (i = 0; i < curSize / 4; i++)
{
*((int*)buffer) = *((int*)src);
buffer += 4;
src += 4;
}
for (i = 0; i < curSize % 4; i++)
*buffer++ = *src++;
}
else if ( (long)buffer % 2 == 0 && (long)src % 2 == 0)// if both buffers are 2 byte-aligned
{
for (i = 0; i < curSize / 2; i++)
{
*((short*)buffer) = *((short*)src);
buffer += 2;
src += 2;
}
for (i = 0; i < curSize % 2; i++)
*buffer++ = *src++;
}
else if ((long) buffer % 2 == 1 && (long) src % 2 == 1)
{
// move 1 byte first
*buffer++ = *src++;
if ((long)buffer % 4 == 0 && (long)src % 4 == 0)
{
// copy data short by short
for (i = 0; i < (curSize-1) / 4; i++)
{
*((int*)buffer) = *((int*)src);
buffer += 4;
src += 4;
}
for (i = 0; i < (curSize-1) % 4; i++)
*buffer++ = *src++;
}
else
{
// copy data short by short
for (i = 0; i < (curSize-1) / 2; i++)
{
*((short*)buffer) = *((short*)src);
buffer += 2;
src += 2;
}
for (i = 0; i < (curSize-1) % 2; i++)
*buffer++ = *src++;
}
}
else
{
for (i = 0; i < curSize; i++)
*buffer++ = *src++;
}
}
// restore the current block
// curBlock = prevBlock;
pfile->currentBlock = curBlock = prevBlock;
// update the positions
remains -= curSize;
pfile->fpos += curSize;
readCount += curSize;
if (remains == 0)
return readCount;
// part 2: read not done yet, go to part two
// part 2 reads the data of the blocks in between the first one and the last one
if (curBlock->nextBlock == NULL)
return readCount;
// continue with next block till the last block
while (remains > ((struct diskBlock *)(curBlock->nextBlock))->actualSize)
{
// update the file position of the 1st byte of the current block
pfile->blockfpos += curBlock->actualSize;
// get next block
curBlock = curBlock->nextBlock;
// compress the previous block if necessary
#ifdef RAMDISK_COMPRESS_USE_ZLIB
compressCurrentBlock(pfile);
// one less file handle is using this block
(pfile->currentBlock)->userCount--;
#endif
// the new current block
pfile->currentBlock = curBlock;
#ifdef RAMDISK_COMPRESS_USE_ZLIB
// one more file handle is using this block
(pfile->currentBlock)->userCount++;
// uncompress the block if necessary
if (uncompressCurrentBlock(pfile) == -1)
{
pfile->currentBlock = NULL;
pfile->blockfpos = 0;
return readCount;
}
curBlock = pfile->currentBlock;
#endif
src = (unsigned char *)((unsigned long)curBlock + B_HEADER);
prevBlock = curBlock;
if ((pfile->fileFlag & O_TEXT) == O_TEXT)
{
for (i = 0; i < curBlock->actualSize; i++)
{
if (*src == '\r')
{
if ((src + 1) < ((unsigned char*)curBlock + B_HEADER + curBlock->actualSize))
{
if ((*(src+1)) == '\n')
{
// skip '\r'
readCount -= 1;
src++;
continue;
}
}
else
{
// read the next block and check if the first character is '\n'
curBlock = curBlock->nextBlock;
// the new current block
pfile->currentBlock = curBlock;
#ifdef RAMDISK_COMPRESS_USE_ZLIB
// one more file handle is using this block
(pfile->currentBlock)->userCount++;
// uncompress the block if necessary
if (uncompressCurrentBlock(pfile) == -1)
{
pfile->currentBlock = NULL;
pfile->blockfpos = 0;
return (readCount + i);
}
curBlock = pfile->currentBlock;
#endif
if (curBlock != NULL)
{
if (*((unsigned char*)curBlock + B_HEADER) == '\n')
{
// skip '\r'
readCount -= 1;
// we've reached the end of the block
break;
}
// compress the previous block if necessary
#ifdef RAMDISK_COMPRESS_USE_ZLIB
compressCurrentBlock(pfile);
// one less file handle is using this block
(pfile->currentBlock)->userCount--;
#endif
}
}
}
*buffer++ = *src++;
}
}
else // binary mode
{
// if both buffers are 4 byte-aligned
if ((long)buffer % 4 == 0 && (long)src % 4 == 0)
{
for (i = 0; i < curBlock->actualSize / 4; i++)
{
*((int*)buffer) = *((int*)src);
buffer += 4;
src += 4;
}
for (i = 0; i < curBlock->actualSize % 4; i++)
*buffer++ = *src++;
}
else if ((long)buffer % 2 == 0 && (long)src % 2 == 0)// if both buffers are 2 byte-aligned
{
for (i = 0; i < curBlock->actualSize / 2; i++)
{
*((short*)buffer) = *((short*)src);
buffer +=2;
src += 2;
}
for (i = 0; i < curBlock->actualSize % 2; i++)
*buffer++ = *src++;
}
else if ((long) buffer % 2 == 1 && (long)src % 2 == 1)
{
// move 1 byte first to make both buffer & src located on even addresses
*buffer++ = *src++;
if ((long)buffer % 4 == 0 && (long)src % 4 == 0)
{
for (i = 0; i < (curBlock->actualSize-1) / 4; i++)
{
*((int*)buffer) = *((int*)src);
buffer += 4;
src += 4;
}
for (i = 0; i < (curBlock->actualSize-1) % 4; i++)
*buffer++ = *src++;
}
else
{
for (i = 0; i < (curBlock->actualSize-1) / 2; i++)
{
*((short*)buffer) = *((short*)src);
buffer +=2;
src += 2;
}
for (i = 0; i < (curBlock->actualSize-1) % 2; i++)
*buffer++ = *src++;
}
}
else
{
for (i = 0; i < curBlock->actualSize; i++)
*buffer++ = *src++;
}
}
// restore the current block
// curBlock = prevBlock;
pfile->currentBlock = curBlock = prevBlock;
remains -= curBlock->actualSize;
pfile->fpos += curBlock->actualSize;
readCount += curBlock->actualSize;
if (curBlock->nextBlock == NULL)
return readCount;
}
// part 3: transfer data from the last block to user buffer
// update the file position of the 1st byte of the current block
pfile->blockfpos += curBlock->actualSize;
// get next block
curBlock = curBlock->nextBlock;
// compress the previous block if necessary
#ifdef RAMDISK_COMPRESS_USE_ZLIB
compressCurrentBlock(pfile);
// one less file handle is using this block
(pfile->currentBlock)->userCount--;
#endif
// the new current block
pfile->currentBlock = curBlock;
#ifdef RAMDISK_COMPRESS_USE_ZLIB
// one more file handle is using this block
(pfile->currentBlock)->userCount++;
// uncompress the block if necessary
if (uncompressCurrentBlock(pfile) == -1)
{
pfile->currentBlock = NULL;
pfile->blockfpos = 0;
return readCount;
}
curBlock = pfile->currentBlock;
#endif
src = (unsigned char *)((unsigned long)curBlock + B_HEADER);
prevBlock = curBlock;
if ((pfile->fileFlag & O_TEXT) == O_TEXT)
{
for (i = 0; i < remains; i++)
{
if (*src == '\r')
{
// check if it's the last character of the curBlock
if ((src + 1) < ((unsigned char*)curBlock + B_HEADER + curBlock->actualSize))
{
if ((*(src+1)) == '\n')
{
// skip '\r'
readCount -= 1;
src++;
continue;
}
}
else
{
// read the next block and check if the first character is '\n'
curBlock = curBlock->nextBlock;
// the new current block
pfile->currentBlock = curBlock;
#ifdef RAMDISK_COMPRESS_USE_ZLIB
// one more file handle is using this block
(pfile->currentBlock)->userCount++;
// uncompress the block if necessary
if (uncompressCurrentBlock(pfile) == -1)
{
pfile->currentBlock = NULL;
pfile->blockfpos = 0;
return (readCount+i);
}
curBlock = pfile->currentBlock;
#endif
if (curBlock != NULL)
{
if (*((unsigned char*)curBlock + B_HEADER) == '\n')
{
// skip '\r'
readCount -= 1;
// we've reached the end of the block
break;
}
// compress the previous block if necessary
#ifdef RAMDISK_COMPRESS_USE_ZLIB
compressCurrentBlock(pfile);
// one less file handle is using this block
(pfile->currentBlock)->userCount--;
#endif
}
}
}
*buffer++ = *src++;
}
}
else // binary mode
{
// if both buffers are 4 byte-aligned
if ((long)buffer % 4 == 0 && (long)src % 4 == 0)
{
for (i = 0; i < remains / 4; i++)
{
*((int*)buffer) = *((int*)src);
buffer += 4;
src += 4;
}
for (i = 0; i < remains % 4; i++)
*buffer++ = *src++;
}
else if ((long)buffer % 2 == 0 && (long)src % 2 == 0)// if both buffers are 2 byte-aligned
{
for (i = 0; i < remains / 2; i++)
{
*((short*)buffer) = *((short*)src);
buffer += 2;
src += 2;
}
for (i = 0; i < remains % 2; i++)
*buffer++ = *src++;
}
else if ((long)buffer % 2 == 1 && (long)src % 2 == 1)
{
// move 1 byte first to make both buffer & src located on even addresses
*buffer++ = *src++;
if ((long)buffer % 4 == 0 && (long)src % 4 == 0)
{
for (i = 0; i < (remains-1) / 4; i++)
{
*((int*)buffer) = *((int*)src);
buffer += 4;
src += 4;
}
for (i = 0; i < (remains-1) % 4; i++)
*buffer++ = *src++;
}
else
{
for (i = 0; i < (remains-1) / 2; i++)
{
*((short*)buffer) = *((short*)src);
buffer += 2;
src += 2;
}
for (i = 0; i < (remains-1) % 2; i++)
*buffer++ = *src++;
}
}
else
{
for (i = 0; i < remains; i++)
*buffer++ = *src++;
}
}
// restore the current block
// curBlock = prevBlock;
pfile->currentBlock = curBlock = prevBlock;
pfile->fpos += remains;
readCount += remains;
remains = 0;
return readCount;
}
/*************************************************************
Function: RD_write_r
Description:
write data from file to user buffer
Input:
pfile - the target file structure
buffer - the user buffer
size - the size of data to be written
Output:
size of data written to the disk
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -