1: <?php
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: class Horde_Stream_Filter_Crc32 extends php_user_filter
27: {
28: 29: 30:
31: public function onCreate()
32: {
33: $this->params->crc32 = 0;
34:
35: return true;
36: }
37:
38: 39: 40:
41: public function filter($in, $out, &$consumed, $closing)
42: {
43: while ($bucket = stream_bucket_make_writeable($in)) {
44: $consumed += $bucket->datalen;
45: $this->params->crc32 = $this->_crc32Combine($this->params->crc32, crc32($bucket->data), $bucket->datalen);
46: stream_bucket_append($out, $bucket);
47: }
48:
49: return PSFS_PASS_ON;
50: }
51:
52: 53:
54: protected function _crc32Combine($crc1, $crc2, $len2)
55: {
56: $odd = array(0xedb88320);
57: $row = 1;
58:
59: for ($n = 1; $n < 32; ++$n) {
60: $odd[$n] = $row;
61: $row <<= 1;
62: }
63:
64: $this->_gf2MatrixSquare($even, $odd);
65: $this->_gf2MatrixSquare($odd, $even);
66:
67: do {
68:
69: $this->_gf2MatrixSquare($even, $odd);
70:
71: if ($len2 & 1) {
72: $crc1 = $this->_gf2MatrixTimes($even, $crc1);
73: }
74:
75: $len2>>=1;
76:
77:
78: if ($len2 == 0) {
79: break;
80: }
81:
82:
83: $this->_gf2MatrixSquare($odd, $even);
84: if ($len2 & 1) {
85: $crc1 = $this->_gf2MatrixTimes($odd, $crc1);
86: }
87:
88: $len2>>= 1;
89: } while ($len2 != 0);
90:
91: $crc1 ^= $crc2;
92:
93: return $crc1;
94: }
95:
96: 97:
98: protected function _gf2MatrixSquare(&$square, &$mat)
99: {
100: for ($n = 0; $n < 32; ++$n) {
101: $square[$n] = $this->_gf2MatrixTimes($mat, $mat[$n]);
102: }
103: }
104:
105: 106:
107: protected function _gf2MatrixTimes($mat, $vec)
108: {
109: $i = $sum = 0;
110:
111: while ($vec) {
112: if ($vec & 1) {
113: $sum ^= $mat[$i];
114: }
115:
116: $vec = ($vec >> 1) & 0x7FFFFFFF;
117: ++$i;
118: }
119:
120: return $sum;
121: }
122:
123: }
124: