失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > linux的rio包在哪个头文件 [Linux] RIO C++封装

linux的rio包在哪个头文件 [Linux] RIO C++封装

时间:2022-11-30 00:18:58

相关推荐

linux的rio包在哪个头文件 [Linux] RIO C++封装

RIO包是CSAPP中一个基于read和write函数实现的能够处理终端并提供了带缓冲区读取的IO包。代码很简单,但很巧妙。

缩减了原程序的初始化等函数之后,主要有以下四个对外函数:

1.ssize_t readn(int fd,void *usrbuf,size_t n);

fd为通过open得到的文件描述符,通常为一个小整数。该函数从指定文件读取n个byte到usrbuf中。如果成功执行,返回传输的字节数,如果读到EOF,返回0,如果出错,返回-1。

2.ssize_t writen(int fd,void *usrbuf,size_t n);

该函数将usebuf中最多n个字节写到文件中。如果成功,返回写入的字节数,如果出错返回-1.

3.ssize_t readlineb(rio_t rp,voidusrbuf,size_t maxlen);

rio_t是一个定义乐缓冲区的结构体,具体实现见下面代码。该函数一次从缓冲区/文件读取一行数据(最长不超过maxlen)

4.ssize_t readnb(rio_t rp,voidusrbuf,size_t n);

该函数是带有缓冲区版本的read,类似于readn。

myrio.h

#pragma once

#include

#include

#include

#include

#include

#include

//a buffer named rio_t

#define RIO_BUFSIZE 8192

typedef struct rio_t{

int rio_fd;

int rio_cnt; //unread bytes in rio_buf

char *rio_bufptr; //next unread byte in rio_buf

char rio_buf[RIO_BUFSIZE]; //internal buffer

rio_t(int fd)

:rio_fd(fd),rio_cnt(0),rio_bufptr(rio_buf){ }

} rio_t;

class Rio{

public:

//io function without internal buffer

//Succeed: return the number of byte; EOF: return 0; Fail: return -1

ssize_t readn(int fd,void *usrbuf,size_t n);

ssize_t writen(int fd,void *usrbuf,size_t n);

//io function with internal buffer

//Succeed: return the number of byte; EOF: return 0; Fail: return -1

ssize_t readlineb(rio_t *rp,void *usrbuf,size_t maxlen);

ssize_t readnb(rio_t *rp,void *usrbuf,size_t n);

private:

//read with buffer

ssize_t rio_read(rio_t *rp,char *usrbuf,size_t n);

};

myrio.cpp

#include "myrio.h"

//the difference between these function and system's is that:

//this function can deal with the interrupt.

ssize_t Rio::readn(int fd,void *usrbuf,size_t n){

size_t nleft = n;

ssize_t nread;

char *buf = static_cast(usrbuf);

while(nleft > 0){

if((nread = read(fd,buf,nleft))<0){

if(errno ==EINTR) nread = 0;

else return -1;

}else if(nleft == 0){

break;

}else{

nleft -= nread;

buf += nread;

}

}

return (n - nleft);

}

ssize_t Rio::writen(int fd,void *usrbuf,size_t n){

size_t nleft = n;

ssize_t nwriten;

char *buf = static_cast(usrbuf);

while(nleft > 0){

if((nwriten = write(fd,buf,nleft)) <= 0){

if(errno == EINTR) nwriten = 0;

else return -1;

}else{

nleft -= nwriten;

buf += nwriten;

}

return n;

}

}

ssize_t Rio::rio_read(rio_t *rp,char *usrbuf,size_t n){

int cnt;

while(rp->rio_cnt <= 0){ //refill rio_buf if buf is empty

rp->rio_cnt = read(rp->rio_fd,rp->rio_buf,sizeof(rp->rio_buf));

if(rp->rio_cnt < 0){

if(errno != EINTR) return -1;

}else if(rp->rio_cnt == 0){

return 0;

}else{

rp->rio_bufptr = rp->rio_buf;

}

}

cnt = n;

if(rp->rio_cnt < n)

cnt = rp->rio_cnt;

memcpy(usrbuf,rp->rio_bufptr,cnt);

rp->rio_bufptr += cnt;

rp->rio_cnt -= cnt;

return cnt;

}

ssize_t Rio::readlineb(rio_t *rp,void *usrbuf,size_t maxlen){

char c;

char *buf = static_cast(usrbuf);

int n,rc;

for(n=1;n

if((rc = rio_read(rp,&c,1)) == 1){

*buf = c;

buf++;

if(c == '\n')

break;

}else if(rc == 0){

if(n == 1) return 0;

else break;

}else{

return -1;

}

}

*buf = '\0';

return n;

}

ssize_t Rio::readnb(rio_t *rp,void *usrbuf,size_t n){

size_t nleft = n;

ssize_t nread;

char *buf = static_cast(usrbuf);

while(nleft > 0){

if((nread = rio_read(rp,buf,nleft)) < 0){

if(errno == EINTR) nread = 0;

else return -1;

}else if(nread == 0){

break;

}else{

nleft -= nread;

buf += nread;

}

}

return (n-nleft);

}

如果觉得《linux的rio包在哪个头文件 [Linux] RIO C++封装》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。