File: ifdnbuf.h

package info (click to toggle)
c%2B%2B-annotations 13.02.02-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,576 kB
  • sloc: cpp: 25,297; makefile: 1,523; ansic: 165; sh: 126; perl: 90; fortran: 27
file content (100 lines) | stat: -rw-r--r-- 2,209 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    #ifndef IFDNBUF_H_
    #define IFDNBUF_H_

    #include <unistd.h>
    #include <streambuf>
    #include <cstring>

//CLASS
    class IFdNStreambuf: public std::streambuf
    {
        protected:
            int         d_fd = -1;
            size_t      d_bufsize = 0;
            char*       d_buffer = 0;
        public:
            IFdNStreambuf() = default;
            IFdNStreambuf(int fd, size_t bufsize = 1);
            ~IFdNStreambuf() override;
            void open(int fd, size_t bufsize = 1);
        private:
            int underflow() override;
            std::streamsize xsgetn(char *dest, std::streamsize n) override;
    };
//=

//CONS
    inline IFdNStreambuf::IFdNStreambuf(int fd, size_t bufsize)
    {
        open(fd, bufsize);
    }
//=

    // In real applications, the following members should be defined in
    // source files. Headers should not have external linkage.

//DESTR
    IFdNStreambuf::~IFdNStreambuf()
    {
        if (d_bufsize)
        {
            close(d_fd);
            delete[] d_buffer;
        }
    }
//=
//OPEN
    void IFdNStreambuf::open(int fd, size_t bufsize)
    {
        d_fd = fd;
        d_bufsize =  bufsize == 0 ? 1 : bufsize;
        delete[] d_buffer;
        d_buffer = new char[d_bufsize];
        setg(d_buffer, d_buffer + d_bufsize, d_buffer + d_bufsize);
    }
//=
//UFLOW
    int IFdNStreambuf::underflow()
    {
        if (gptr() < egptr())
            return *gptr();

        int nread = read(d_fd, d_buffer, d_bufsize);

        if (nread <= 0)
            return EOF;

        setg(d_buffer, d_buffer, d_buffer + nread);
        return static_cast<unsigned char>(*gptr());
    }
//=
//XSGETN
    std::streamsize IFdNStreambuf::xsgetn(char *dest, std::streamsize n)
    {
        int nread = 0;

        while (n)
        {
            if (!in_avail())
            {
                if (underflow() == EOF)
                    break;
            }

            int avail = in_avail();

            if (avail > n)
                avail = n;

            memcpy(dest + nread, gptr(), avail);
            gbump(avail);

            nread += avail;
            n -= avail;
        }

        return nread;
    }
//=

    #endif