Exemplo n.º 1
0
Error VGA::read(IOBuffer & buffer, Size size, Size offset)
{
    if (offset + size > width * height * sizeof(u16))
    {
        return EFAULT;
    }
    buffer.write(vga + (offset / sizeof(u16)), size);
    return size;
}
Exemplo n.º 2
0
Error LinnDirectory::read(IOBuffer & buffer, Size size, Size offset)
{
    LinnSuperBlock *sb = fs->getSuperBlock();
    LinnDirectoryEntry dent;
    LinnInode *dInode;
    Size bytes = ZERO, blk;
    Error e;
    Dirent tmp;

    /* Read directory entries. */
    for (u32 ent = 0; ent < inode->size / sizeof(LinnDirectoryEntry); ent++)
    {
	/* Point to correct (direct) block. */
	if ((blk = (ent * sizeof(LinnDirectoryEntry)) / sb->blockSize)
	     >= LINN_INODE_DIR_BLOCKS)
	{
	    break;
	}
	/* Calculate offset to read. */
	u64 off = (inode->block[blk] * sb->blockSize) +
	    	  (ent * sizeof(LinnDirectoryEntry));

	/* Get the next entry. */
	if (fs->getStorage()->read(off, &dent,
			           sizeof(LinnDirectoryEntry)) < 0)
	{
	    return EACCES;
	}
	/* Can we read another entry? */
        if (bytes + sizeof(Dirent) > size)
        {
	    return EFAULT;
	}
	/* Fill in the Dirent. */
	if (!(dInode = fs->getInode(dent.inode)))
	{
	    return EINVAL;
	}
	strlcpy(tmp.name, dent.name, LINN_DIRENT_NAME_LEN);
	tmp.type = (FileType) dInode->type;

	/* Copy to the buffer. */
	if (( e = buffer.write(&tmp, sizeof(Dirent), bytes)) < 0)
	{
	    return e;
	}
	bytes += sizeof(Dirent);
    }
    /* All done. */
    return bytes;
}
Exemplo n.º 3
0
Error LinnFile::read(IOBuffer & buffer, Size size, Size offset)
{
    LinnSuperBlock *sb;
    Size bytes = 0, blockNr = 0;
    u64 storageOffset, copyOffset = offset;
    u8 *block;
    Size total = 0;
    Error e;

#warning very inefficient. blocks are not cached from storage and thrown away each time.

    /* Initialize variables. */
    sb     = fs->getSuperBlock();
    block  = new u8[sb->blockSize];

    /* Skip ahead blocks. */
    while ((sb->blockSize * (blockNr + 1)) <= copyOffset)
    {
        blockNr++;
    }
    /* Adjust the copy offset within this block. */
    copyOffset -= sb->blockSize * blockNr;

    /* Loop all blocks. */
    while (blockNr < LINN_INODE_NUM_BLOCKS(sb, inode) &&
	   total < size && inode->size - (offset + total) > 0)
    {
	/* Calculate the offset in storage for this block. */
	storageOffset = fs->getOffset(inode, blockNr);

        /* Fetch the next block. */
        if (fs->getStorage()->read(storageOffset, block, sb->blockSize) < 0)
	{
	    delete block;
	    return EIO;
	}
	/* Calculate the number of bytes to copy. */
	bytes = sb->blockSize - copyOffset;
	
	/* Respect the inode size. */
	if (bytes > inode->size - (offset + total))
	{
	    bytes = inode->size - (offset + total);
	}
	/* Respect the remote process buffer. */
	if (bytes > size - total)
	{
	    bytes = size - total;
	}
        /* Copy into the buffer. */
	if ((e = buffer.write(block + copyOffset, bytes, total)) < 0)
	{
	    delete block;
	    return e;
	}
	/* Update state. */
	total      += bytes;
	copyOffset  = 0;
	blockNr++;
    }
    /* Success. */
    delete block;
    return (Error) total;
}