《unix網絡編程》中readline函數改進版

自己加了註釋方便理解,希望幫到更多難以理解這段代碼的人…

/* my_read和readline的關係是,
 * readline調用my_read,my_read先讀入需要的全部數據進入自己的緩衝區,
 * 每次my_read返回一個字符,循環至readline通過調用間接把read_buf緩存區內的數據讀取完畢。
 * 已讀取的字節數由read_cnt存儲,在第一次被調用之後的每次調用都通過該變量自減來判斷緩存是否已被readline讀取完。
 * 在被讀取完之前,每次被調用時read_cnt是>0的,所以經過第一個if判斷之後,
 * 都只有這句話*ptr = *read_ptr++;起作用,作用是把緩衝區裏的下一個字符返回給readline,讓readline來判斷是否讀到了'\n'
 * 當--read_cnt;執行至read_cnt爲0時,my_read內的第一個if條件成立,執行if內的代碼,返回給readline一個0,此時調用者知道緩存區內的數據已經被讀取完了
 */
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include "stdio.h"
#include "unistd.h"

#define MAXLINE 40

static ssize_t my_read(int fd, char *ptr);

ssize_t readline(int fd, void *vptr, size_t maxlen);

static ssize_t read_cnt = -127;//設置一個爲負數的初始值
static char *read_ptr;
static char read_buf[MAXLINE];

int main(void) {

    return 0;
}

static ssize_t
my_read(int fd, char *ptr) {
    if (read_cnt < 0) {
        again:
        if ((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {//讀取失敗的情況
            if (errno == EINTR) {
                goto again;
            } else {
                return (-1);
            }
        } else if (read_cnt == 0) {
            return (0);
        } else {//讀取成功且返回值不等於0
            read_ptr = read_buf;
        }
    }
    --read_cnt;
    *ptr = *read_ptr++;
    return (1);
}

ssize_t readline(int fd, void *vptr, size_t maxlen) {
    char c, *ptr = vptr;
    ssize_t n, rc;
    for (n = 1; n < maxlen; ++n) {
        if ((rc = my_read(fd, &c)) == 1) {
            *ptr++ = c;
            if (c == '\n') {
                break;
            }
        } else if (rc == 0) {

            *ptr = NULL;
            return (n - 1);

        } else {
            return (-1);
        }
    }
    *ptr = NULL;
    return (n);
}








































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章