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; }
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; }
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; }