RZ

01: // LocalScanCircular.cc # the actual synthesize algorithm
02:
03: #include <unistd.h>
04: #include <sys/uio.h>
05:
06: #include <vector>
07:
08: #include "RZError.hh"
09: #include "LocalScan.hh"
10: #include "LocalReadCheck.hh"
11:
12: // #### circular buffer version is more up-to-date though no more readable ####
13:
14: void RZ::Scanner::scan_circular(int const givenfd)
15: {
16:     unsigned int const bufsize = block_size + 65536;
17:     std::vector< char > givenbuf(bufsize);
18:
19:     unsigned int chkc = 0;
20:     int lectum = -block_size;
21:     read_check(this, chkc, lectum, givenfd, &givenbuf[ 0 ], bufsize);
22:     for (
23:         unsigned int back = 0, next = block_size;
24:         lectum >= 0;
25:         back %= bufsize, next %= bufsize)
26:     {
27:         Range range = fast_range(chkc);
28:         if (has_more(range)) {
29:             if (back < next
30:                 ? check_more(range, &givenbuf[ back ])
31:                 : check_more(range, &givenbuf[ back ],
32:                     bufsize - back, &givenbuf[ 0 ]))
33:             {
34:                 if ((unsigned int)lectum > block_size) {
35:                     if (next + block_size < bufsize) {
36:                         chkc = c.checksum32(&givenbuf[ next ]);
37:                     }
38:                     else {
39:                         chkc = c.checksum32(&givenbuf[ next ],
40:                             bufsize - next, &givenbuf[ 0 ]);
41:                     }
42:                     lectum -= block_size;
43:                 }
44:                 else {
45:                     unsigned int nnext = next + lectum;
46:                     chkc = 0;
47:                     if (nnext < bufsize) {
48:                         c.accumulate(&givenbuf[ next ], lectum, chkc);
49:                     }
50:                     else {
51:                         unsigned int t = bufsize - next;
52:                         c.accumulate(&givenbuf[ next ], t, chkc);
53:                         c.accumulate(&givenbuf[ 0 ], lectum - t, chkc);
54:                         nnext -= bufsize;
55:                     }
56:                     lectum -= block_size;
57:                     struct iovec input[2];
58:                     input[0].iov_base = &givenbuf[ nnext ];
59:                     input[0].iov_len = bufsize - nnext;
60:                     input[1].iov_base = &givenbuf[ 0 ];
61:                     input[1].iov_len = nnext;
62:                     readv_check(this, chkc, lectum, givenfd, input, 2);
63:                 }
64:                 back += block_size;
65:                 next += block_size;
66:                 continue;
67:             }
68:         }
69:         if (lectum == 0) {
70:             int r;
71:             if (back < next) {
72:                 struct iovec input[2];
73:                 input[0].iov_base = &givenbuf[ next ];
74:                 input[0].iov_len = bufsize - next;
75:                 input[1].iov_base = &givenbuf[ 0 ];
76:                 input[1].iov_len = back;
77:                 do r = readv(givenfd, input, 2);
78:                 while (r == -1 && errno == EINTR);
79:             }
80:             else {
81:                 do r = read(givenfd, &givenbuf[ next ], back - next);
82:                 while (r == -1 && errno == EINTR);
83:             }
84:             IOError::what_if("Can't read given for scan!");
85:             if (!r) return;
86:             lectum += (unsigned int)r;
87:         }
88:         --lectum;
89:         chkc = c.rollingsum(chkc, givenbuf[ back ], givenbuf[ next ]);
90:         ++back;
91:         ++next;
92:     }
93: }
94:
95: // ######## ######## ######## ######## ######## ######## ######## ########
96:
97: // LocalScanCircular.cc # the actual synthesize algorithm