File: fdunget.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 (64 lines) | stat: -rw-r--r-- 1,440 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
    #include <unistd.h>
    #include <streambuf>
    #include <ios>
    #include <algorithm>
    #include <cstring>

//CLASS
    class FdUnget: public std::streambuf
    {
        int     d_fd;
        size_t  d_bufsize;
        size_t  d_reserved;
        char   *d_buffer;
        char   *d_base;
        public:
            FdUnget(int fd, size_t bufsz, size_t unget);
            ~FdUnget() override;
        private:
            int underflow() override;
    };
//=
//CONS
    FdUnget::FdUnget(int fd, size_t bufsz, size_t unget)
    :
        d_fd(fd),
        d_reserved(unget)
    {
        size_t allocate =
                bufsz > d_reserved ?
                    bufsz
                :
                    d_reserved + 1;

        d_buffer = new char[allocate];

        d_base = d_buffer + d_reserved;
        setg(d_base, d_base, d_base);

        d_bufsize = allocate - d_reserved;
    }
//=
//DESTR
    inline FdUnget::~FdUnget()
    {
        delete[] d_buffer;
    }
//=
//UNDERFLOW
    int FdUnget::underflow()
    {
        size_t ungetsize = gptr() - eback();
        size_t move = std::min(ungetsize, d_reserved);

        memcpy(d_base - move, egptr() - move, move);

        int nread = read(d_fd, d_base, d_bufsize);
        if (nread <= 0)       // none read -> return EOF
            return EOF;

        setg(d_base - move, d_base, d_base + nread);

        return static_cast<unsigned char>(*gptr());
    }
//=