Merge recent enhancements from trunk.
FossilOrigin-Name: edceaccd66a65d6b36e53ce33d760a7bd9c2261a592d12189f5f55417b5d5d74
This commit is contained in:
+272
-272
@@ -78,9 +78,9 @@ struct SHA3Context {
|
||||
*/
|
||||
static void KeccakF1600Step(SHA3Context *p){
|
||||
int i;
|
||||
u64 B0, B1, B2, B3, B4;
|
||||
u64 C0, C1, C2, C3, C4;
|
||||
u64 D0, D1, D2, D3, D4;
|
||||
u64 b0, b1, b2, b3, b4;
|
||||
u64 c0, c1, c2, c3, c4;
|
||||
u64 d0, d1, d2, d3, d4;
|
||||
static const u64 RC[] = {
|
||||
0x0000000000000001ULL, 0x0000000000008082ULL,
|
||||
0x800000000000808aULL, 0x8000000080008000ULL,
|
||||
@@ -95,301 +95,301 @@ static void KeccakF1600Step(SHA3Context *p){
|
||||
0x8000000080008081ULL, 0x8000000000008080ULL,
|
||||
0x0000000080000001ULL, 0x8000000080008008ULL
|
||||
};
|
||||
# define A00 (p->u.s[0])
|
||||
# define A01 (p->u.s[1])
|
||||
# define A02 (p->u.s[2])
|
||||
# define A03 (p->u.s[3])
|
||||
# define A04 (p->u.s[4])
|
||||
# define A10 (p->u.s[5])
|
||||
# define A11 (p->u.s[6])
|
||||
# define A12 (p->u.s[7])
|
||||
# define A13 (p->u.s[8])
|
||||
# define A14 (p->u.s[9])
|
||||
# define A20 (p->u.s[10])
|
||||
# define A21 (p->u.s[11])
|
||||
# define A22 (p->u.s[12])
|
||||
# define A23 (p->u.s[13])
|
||||
# define A24 (p->u.s[14])
|
||||
# define A30 (p->u.s[15])
|
||||
# define A31 (p->u.s[16])
|
||||
# define A32 (p->u.s[17])
|
||||
# define A33 (p->u.s[18])
|
||||
# define A34 (p->u.s[19])
|
||||
# define A40 (p->u.s[20])
|
||||
# define A41 (p->u.s[21])
|
||||
# define A42 (p->u.s[22])
|
||||
# define A43 (p->u.s[23])
|
||||
# define A44 (p->u.s[24])
|
||||
# define a00 (p->u.s[0])
|
||||
# define a01 (p->u.s[1])
|
||||
# define a02 (p->u.s[2])
|
||||
# define a03 (p->u.s[3])
|
||||
# define a04 (p->u.s[4])
|
||||
# define a10 (p->u.s[5])
|
||||
# define a11 (p->u.s[6])
|
||||
# define a12 (p->u.s[7])
|
||||
# define a13 (p->u.s[8])
|
||||
# define a14 (p->u.s[9])
|
||||
# define a20 (p->u.s[10])
|
||||
# define a21 (p->u.s[11])
|
||||
# define a22 (p->u.s[12])
|
||||
# define a23 (p->u.s[13])
|
||||
# define a24 (p->u.s[14])
|
||||
# define a30 (p->u.s[15])
|
||||
# define a31 (p->u.s[16])
|
||||
# define a32 (p->u.s[17])
|
||||
# define a33 (p->u.s[18])
|
||||
# define a34 (p->u.s[19])
|
||||
# define a40 (p->u.s[20])
|
||||
# define a41 (p->u.s[21])
|
||||
# define a42 (p->u.s[22])
|
||||
# define a43 (p->u.s[23])
|
||||
# define a44 (p->u.s[24])
|
||||
# define ROL64(a,x) ((a<<x)|(a>>(64-x)))
|
||||
|
||||
for(i=0; i<24; i+=4){
|
||||
C0 = A00^A10^A20^A30^A40;
|
||||
C1 = A01^A11^A21^A31^A41;
|
||||
C2 = A02^A12^A22^A32^A42;
|
||||
C3 = A03^A13^A23^A33^A43;
|
||||
C4 = A04^A14^A24^A34^A44;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
c0 = a00^a10^a20^a30^a40;
|
||||
c1 = a01^a11^a21^a31^a41;
|
||||
c2 = a02^a12^a22^a32^a42;
|
||||
c3 = a03^a13^a23^a33^a43;
|
||||
c4 = a04^a14^a24^a34^a44;
|
||||
d0 = c4^ROL64(c1, 1);
|
||||
d1 = c0^ROL64(c2, 1);
|
||||
d2 = c1^ROL64(c3, 1);
|
||||
d3 = c2^ROL64(c4, 1);
|
||||
d4 = c3^ROL64(c0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A11^D1), 44);
|
||||
B2 = ROL64((A22^D2), 43);
|
||||
B3 = ROL64((A33^D3), 21);
|
||||
B4 = ROL64((A44^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i];
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
b0 = (a00^d0);
|
||||
b1 = ROL64((a11^d1), 44);
|
||||
b2 = ROL64((a22^d2), 43);
|
||||
b3 = ROL64((a33^d3), 21);
|
||||
b4 = ROL64((a44^d4), 14);
|
||||
a00 = b0 ^((~b1)& b2 );
|
||||
a00 ^= RC[i];
|
||||
a11 = b1 ^((~b2)& b3 );
|
||||
a22 = b2 ^((~b3)& b4 );
|
||||
a33 = b3 ^((~b4)& b0 );
|
||||
a44 = b4 ^((~b0)& b1 );
|
||||
|
||||
B2 = ROL64((A20^D0), 3);
|
||||
B3 = ROL64((A31^D1), 45);
|
||||
B4 = ROL64((A42^D2), 61);
|
||||
B0 = ROL64((A03^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
b2 = ROL64((a20^d0), 3);
|
||||
b3 = ROL64((a31^d1), 45);
|
||||
b4 = ROL64((a42^d2), 61);
|
||||
b0 = ROL64((a03^d3), 28);
|
||||
b1 = ROL64((a14^d4), 20);
|
||||
a20 = b0 ^((~b1)& b2 );
|
||||
a31 = b1 ^((~b2)& b3 );
|
||||
a42 = b2 ^((~b3)& b4 );
|
||||
a03 = b3 ^((~b4)& b0 );
|
||||
a14 = b4 ^((~b0)& b1 );
|
||||
|
||||
B4 = ROL64((A40^D0), 18);
|
||||
B0 = ROL64((A01^D1), 1);
|
||||
B1 = ROL64((A12^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A34^D4), 8);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
b4 = ROL64((a40^d0), 18);
|
||||
b0 = ROL64((a01^d1), 1);
|
||||
b1 = ROL64((a12^d2), 6);
|
||||
b2 = ROL64((a23^d3), 25);
|
||||
b3 = ROL64((a34^d4), 8);
|
||||
a40 = b0 ^((~b1)& b2 );
|
||||
a01 = b1 ^((~b2)& b3 );
|
||||
a12 = b2 ^((~b3)& b4 );
|
||||
a23 = b3 ^((~b4)& b0 );
|
||||
a34 = b4 ^((~b0)& b1 );
|
||||
|
||||
B1 = ROL64((A10^D0), 36);
|
||||
B2 = ROL64((A21^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A43^D3), 56);
|
||||
B0 = ROL64((A04^D4), 27);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
b1 = ROL64((a10^d0), 36);
|
||||
b2 = ROL64((a21^d1), 10);
|
||||
b3 = ROL64((a32^d2), 15);
|
||||
b4 = ROL64((a43^d3), 56);
|
||||
b0 = ROL64((a04^d4), 27);
|
||||
a10 = b0 ^((~b1)& b2 );
|
||||
a21 = b1 ^((~b2)& b3 );
|
||||
a32 = b2 ^((~b3)& b4 );
|
||||
a43 = b3 ^((~b4)& b0 );
|
||||
a04 = b4 ^((~b0)& b1 );
|
||||
|
||||
B3 = ROL64((A30^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A02^D2), 62);
|
||||
B1 = ROL64((A13^D3), 55);
|
||||
B2 = ROL64((A24^D4), 39);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
b3 = ROL64((a30^d0), 41);
|
||||
b4 = ROL64((a41^d1), 2);
|
||||
b0 = ROL64((a02^d2), 62);
|
||||
b1 = ROL64((a13^d3), 55);
|
||||
b2 = ROL64((a24^d4), 39);
|
||||
a30 = b0 ^((~b1)& b2 );
|
||||
a41 = b1 ^((~b2)& b3 );
|
||||
a02 = b2 ^((~b3)& b4 );
|
||||
a13 = b3 ^((~b4)& b0 );
|
||||
a24 = b4 ^((~b0)& b1 );
|
||||
|
||||
C0 = A00^A20^A40^A10^A30;
|
||||
C1 = A11^A31^A01^A21^A41;
|
||||
C2 = A22^A42^A12^A32^A02;
|
||||
C3 = A33^A03^A23^A43^A13;
|
||||
C4 = A44^A14^A34^A04^A24;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
c0 = a00^a20^a40^a10^a30;
|
||||
c1 = a11^a31^a01^a21^a41;
|
||||
c2 = a22^a42^a12^a32^a02;
|
||||
c3 = a33^a03^a23^a43^a13;
|
||||
c4 = a44^a14^a34^a04^a24;
|
||||
d0 = c4^ROL64(c1, 1);
|
||||
d1 = c0^ROL64(c2, 1);
|
||||
d2 = c1^ROL64(c3, 1);
|
||||
d3 = c2^ROL64(c4, 1);
|
||||
d4 = c3^ROL64(c0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A31^D1), 44);
|
||||
B2 = ROL64((A12^D2), 43);
|
||||
B3 = ROL64((A43^D3), 21);
|
||||
B4 = ROL64((A24^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i+1];
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
b0 = (a00^d0);
|
||||
b1 = ROL64((a31^d1), 44);
|
||||
b2 = ROL64((a12^d2), 43);
|
||||
b3 = ROL64((a43^d3), 21);
|
||||
b4 = ROL64((a24^d4), 14);
|
||||
a00 = b0 ^((~b1)& b2 );
|
||||
a00 ^= RC[i+1];
|
||||
a31 = b1 ^((~b2)& b3 );
|
||||
a12 = b2 ^((~b3)& b4 );
|
||||
a43 = b3 ^((~b4)& b0 );
|
||||
a24 = b4 ^((~b0)& b1 );
|
||||
|
||||
B2 = ROL64((A40^D0), 3);
|
||||
B3 = ROL64((A21^D1), 45);
|
||||
B4 = ROL64((A02^D2), 61);
|
||||
B0 = ROL64((A33^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
b2 = ROL64((a40^d0), 3);
|
||||
b3 = ROL64((a21^d1), 45);
|
||||
b4 = ROL64((a02^d2), 61);
|
||||
b0 = ROL64((a33^d3), 28);
|
||||
b1 = ROL64((a14^d4), 20);
|
||||
a40 = b0 ^((~b1)& b2 );
|
||||
a21 = b1 ^((~b2)& b3 );
|
||||
a02 = b2 ^((~b3)& b4 );
|
||||
a33 = b3 ^((~b4)& b0 );
|
||||
a14 = b4 ^((~b0)& b1 );
|
||||
|
||||
B4 = ROL64((A30^D0), 18);
|
||||
B0 = ROL64((A11^D1), 1);
|
||||
B1 = ROL64((A42^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A04^D4), 8);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
b4 = ROL64((a30^d0), 18);
|
||||
b0 = ROL64((a11^d1), 1);
|
||||
b1 = ROL64((a42^d2), 6);
|
||||
b2 = ROL64((a23^d3), 25);
|
||||
b3 = ROL64((a04^d4), 8);
|
||||
a30 = b0 ^((~b1)& b2 );
|
||||
a11 = b1 ^((~b2)& b3 );
|
||||
a42 = b2 ^((~b3)& b4 );
|
||||
a23 = b3 ^((~b4)& b0 );
|
||||
a04 = b4 ^((~b0)& b1 );
|
||||
|
||||
B1 = ROL64((A20^D0), 36);
|
||||
B2 = ROL64((A01^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A13^D3), 56);
|
||||
B0 = ROL64((A44^D4), 27);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
b1 = ROL64((a20^d0), 36);
|
||||
b2 = ROL64((a01^d1), 10);
|
||||
b3 = ROL64((a32^d2), 15);
|
||||
b4 = ROL64((a13^d3), 56);
|
||||
b0 = ROL64((a44^d4), 27);
|
||||
a20 = b0 ^((~b1)& b2 );
|
||||
a01 = b1 ^((~b2)& b3 );
|
||||
a32 = b2 ^((~b3)& b4 );
|
||||
a13 = b3 ^((~b4)& b0 );
|
||||
a44 = b4 ^((~b0)& b1 );
|
||||
|
||||
B3 = ROL64((A10^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A22^D2), 62);
|
||||
B1 = ROL64((A03^D3), 55);
|
||||
B2 = ROL64((A34^D4), 39);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
b3 = ROL64((a10^d0), 41);
|
||||
b4 = ROL64((a41^d1), 2);
|
||||
b0 = ROL64((a22^d2), 62);
|
||||
b1 = ROL64((a03^d3), 55);
|
||||
b2 = ROL64((a34^d4), 39);
|
||||
a10 = b0 ^((~b1)& b2 );
|
||||
a41 = b1 ^((~b2)& b3 );
|
||||
a22 = b2 ^((~b3)& b4 );
|
||||
a03 = b3 ^((~b4)& b0 );
|
||||
a34 = b4 ^((~b0)& b1 );
|
||||
|
||||
C0 = A00^A40^A30^A20^A10;
|
||||
C1 = A31^A21^A11^A01^A41;
|
||||
C2 = A12^A02^A42^A32^A22;
|
||||
C3 = A43^A33^A23^A13^A03;
|
||||
C4 = A24^A14^A04^A44^A34;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
c0 = a00^a40^a30^a20^a10;
|
||||
c1 = a31^a21^a11^a01^a41;
|
||||
c2 = a12^a02^a42^a32^a22;
|
||||
c3 = a43^a33^a23^a13^a03;
|
||||
c4 = a24^a14^a04^a44^a34;
|
||||
d0 = c4^ROL64(c1, 1);
|
||||
d1 = c0^ROL64(c2, 1);
|
||||
d2 = c1^ROL64(c3, 1);
|
||||
d3 = c2^ROL64(c4, 1);
|
||||
d4 = c3^ROL64(c0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A21^D1), 44);
|
||||
B2 = ROL64((A42^D2), 43);
|
||||
B3 = ROL64((A13^D3), 21);
|
||||
B4 = ROL64((A34^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i+2];
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
b0 = (a00^d0);
|
||||
b1 = ROL64((a21^d1), 44);
|
||||
b2 = ROL64((a42^d2), 43);
|
||||
b3 = ROL64((a13^d3), 21);
|
||||
b4 = ROL64((a34^d4), 14);
|
||||
a00 = b0 ^((~b1)& b2 );
|
||||
a00 ^= RC[i+2];
|
||||
a21 = b1 ^((~b2)& b3 );
|
||||
a42 = b2 ^((~b3)& b4 );
|
||||
a13 = b3 ^((~b4)& b0 );
|
||||
a34 = b4 ^((~b0)& b1 );
|
||||
|
||||
B2 = ROL64((A30^D0), 3);
|
||||
B3 = ROL64((A01^D1), 45);
|
||||
B4 = ROL64((A22^D2), 61);
|
||||
B0 = ROL64((A43^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
b2 = ROL64((a30^d0), 3);
|
||||
b3 = ROL64((a01^d1), 45);
|
||||
b4 = ROL64((a22^d2), 61);
|
||||
b0 = ROL64((a43^d3), 28);
|
||||
b1 = ROL64((a14^d4), 20);
|
||||
a30 = b0 ^((~b1)& b2 );
|
||||
a01 = b1 ^((~b2)& b3 );
|
||||
a22 = b2 ^((~b3)& b4 );
|
||||
a43 = b3 ^((~b4)& b0 );
|
||||
a14 = b4 ^((~b0)& b1 );
|
||||
|
||||
B4 = ROL64((A10^D0), 18);
|
||||
B0 = ROL64((A31^D1), 1);
|
||||
B1 = ROL64((A02^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A44^D4), 8);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
b4 = ROL64((a10^d0), 18);
|
||||
b0 = ROL64((a31^d1), 1);
|
||||
b1 = ROL64((a02^d2), 6);
|
||||
b2 = ROL64((a23^d3), 25);
|
||||
b3 = ROL64((a44^d4), 8);
|
||||
a10 = b0 ^((~b1)& b2 );
|
||||
a31 = b1 ^((~b2)& b3 );
|
||||
a02 = b2 ^((~b3)& b4 );
|
||||
a23 = b3 ^((~b4)& b0 );
|
||||
a44 = b4 ^((~b0)& b1 );
|
||||
|
||||
B1 = ROL64((A40^D0), 36);
|
||||
B2 = ROL64((A11^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A03^D3), 56);
|
||||
B0 = ROL64((A24^D4), 27);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
b1 = ROL64((a40^d0), 36);
|
||||
b2 = ROL64((a11^d1), 10);
|
||||
b3 = ROL64((a32^d2), 15);
|
||||
b4 = ROL64((a03^d3), 56);
|
||||
b0 = ROL64((a24^d4), 27);
|
||||
a40 = b0 ^((~b1)& b2 );
|
||||
a11 = b1 ^((~b2)& b3 );
|
||||
a32 = b2 ^((~b3)& b4 );
|
||||
a03 = b3 ^((~b4)& b0 );
|
||||
a24 = b4 ^((~b0)& b1 );
|
||||
|
||||
B3 = ROL64((A20^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A12^D2), 62);
|
||||
B1 = ROL64((A33^D3), 55);
|
||||
B2 = ROL64((A04^D4), 39);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
b3 = ROL64((a20^d0), 41);
|
||||
b4 = ROL64((a41^d1), 2);
|
||||
b0 = ROL64((a12^d2), 62);
|
||||
b1 = ROL64((a33^d3), 55);
|
||||
b2 = ROL64((a04^d4), 39);
|
||||
a20 = b0 ^((~b1)& b2 );
|
||||
a41 = b1 ^((~b2)& b3 );
|
||||
a12 = b2 ^((~b3)& b4 );
|
||||
a33 = b3 ^((~b4)& b0 );
|
||||
a04 = b4 ^((~b0)& b1 );
|
||||
|
||||
C0 = A00^A30^A10^A40^A20;
|
||||
C1 = A21^A01^A31^A11^A41;
|
||||
C2 = A42^A22^A02^A32^A12;
|
||||
C3 = A13^A43^A23^A03^A33;
|
||||
C4 = A34^A14^A44^A24^A04;
|
||||
D0 = C4^ROL64(C1, 1);
|
||||
D1 = C0^ROL64(C2, 1);
|
||||
D2 = C1^ROL64(C3, 1);
|
||||
D3 = C2^ROL64(C4, 1);
|
||||
D4 = C3^ROL64(C0, 1);
|
||||
c0 = a00^a30^a10^a40^a20;
|
||||
c1 = a21^a01^a31^a11^a41;
|
||||
c2 = a42^a22^a02^a32^a12;
|
||||
c3 = a13^a43^a23^a03^a33;
|
||||
c4 = a34^a14^a44^a24^a04;
|
||||
d0 = c4^ROL64(c1, 1);
|
||||
d1 = c0^ROL64(c2, 1);
|
||||
d2 = c1^ROL64(c3, 1);
|
||||
d3 = c2^ROL64(c4, 1);
|
||||
d4 = c3^ROL64(c0, 1);
|
||||
|
||||
B0 = (A00^D0);
|
||||
B1 = ROL64((A01^D1), 44);
|
||||
B2 = ROL64((A02^D2), 43);
|
||||
B3 = ROL64((A03^D3), 21);
|
||||
B4 = ROL64((A04^D4), 14);
|
||||
A00 = B0 ^((~B1)& B2 );
|
||||
A00 ^= RC[i+3];
|
||||
A01 = B1 ^((~B2)& B3 );
|
||||
A02 = B2 ^((~B3)& B4 );
|
||||
A03 = B3 ^((~B4)& B0 );
|
||||
A04 = B4 ^((~B0)& B1 );
|
||||
b0 = (a00^d0);
|
||||
b1 = ROL64((a01^d1), 44);
|
||||
b2 = ROL64((a02^d2), 43);
|
||||
b3 = ROL64((a03^d3), 21);
|
||||
b4 = ROL64((a04^d4), 14);
|
||||
a00 = b0 ^((~b1)& b2 );
|
||||
a00 ^= RC[i+3];
|
||||
a01 = b1 ^((~b2)& b3 );
|
||||
a02 = b2 ^((~b3)& b4 );
|
||||
a03 = b3 ^((~b4)& b0 );
|
||||
a04 = b4 ^((~b0)& b1 );
|
||||
|
||||
B2 = ROL64((A10^D0), 3);
|
||||
B3 = ROL64((A11^D1), 45);
|
||||
B4 = ROL64((A12^D2), 61);
|
||||
B0 = ROL64((A13^D3), 28);
|
||||
B1 = ROL64((A14^D4), 20);
|
||||
A10 = B0 ^((~B1)& B2 );
|
||||
A11 = B1 ^((~B2)& B3 );
|
||||
A12 = B2 ^((~B3)& B4 );
|
||||
A13 = B3 ^((~B4)& B0 );
|
||||
A14 = B4 ^((~B0)& B1 );
|
||||
b2 = ROL64((a10^d0), 3);
|
||||
b3 = ROL64((a11^d1), 45);
|
||||
b4 = ROL64((a12^d2), 61);
|
||||
b0 = ROL64((a13^d3), 28);
|
||||
b1 = ROL64((a14^d4), 20);
|
||||
a10 = b0 ^((~b1)& b2 );
|
||||
a11 = b1 ^((~b2)& b3 );
|
||||
a12 = b2 ^((~b3)& b4 );
|
||||
a13 = b3 ^((~b4)& b0 );
|
||||
a14 = b4 ^((~b0)& b1 );
|
||||
|
||||
B4 = ROL64((A20^D0), 18);
|
||||
B0 = ROL64((A21^D1), 1);
|
||||
B1 = ROL64((A22^D2), 6);
|
||||
B2 = ROL64((A23^D3), 25);
|
||||
B3 = ROL64((A24^D4), 8);
|
||||
A20 = B0 ^((~B1)& B2 );
|
||||
A21 = B1 ^((~B2)& B3 );
|
||||
A22 = B2 ^((~B3)& B4 );
|
||||
A23 = B3 ^((~B4)& B0 );
|
||||
A24 = B4 ^((~B0)& B1 );
|
||||
b4 = ROL64((a20^d0), 18);
|
||||
b0 = ROL64((a21^d1), 1);
|
||||
b1 = ROL64((a22^d2), 6);
|
||||
b2 = ROL64((a23^d3), 25);
|
||||
b3 = ROL64((a24^d4), 8);
|
||||
a20 = b0 ^((~b1)& b2 );
|
||||
a21 = b1 ^((~b2)& b3 );
|
||||
a22 = b2 ^((~b3)& b4 );
|
||||
a23 = b3 ^((~b4)& b0 );
|
||||
a24 = b4 ^((~b0)& b1 );
|
||||
|
||||
B1 = ROL64((A30^D0), 36);
|
||||
B2 = ROL64((A31^D1), 10);
|
||||
B3 = ROL64((A32^D2), 15);
|
||||
B4 = ROL64((A33^D3), 56);
|
||||
B0 = ROL64((A34^D4), 27);
|
||||
A30 = B0 ^((~B1)& B2 );
|
||||
A31 = B1 ^((~B2)& B3 );
|
||||
A32 = B2 ^((~B3)& B4 );
|
||||
A33 = B3 ^((~B4)& B0 );
|
||||
A34 = B4 ^((~B0)& B1 );
|
||||
b1 = ROL64((a30^d0), 36);
|
||||
b2 = ROL64((a31^d1), 10);
|
||||
b3 = ROL64((a32^d2), 15);
|
||||
b4 = ROL64((a33^d3), 56);
|
||||
b0 = ROL64((a34^d4), 27);
|
||||
a30 = b0 ^((~b1)& b2 );
|
||||
a31 = b1 ^((~b2)& b3 );
|
||||
a32 = b2 ^((~b3)& b4 );
|
||||
a33 = b3 ^((~b4)& b0 );
|
||||
a34 = b4 ^((~b0)& b1 );
|
||||
|
||||
B3 = ROL64((A40^D0), 41);
|
||||
B4 = ROL64((A41^D1), 2);
|
||||
B0 = ROL64((A42^D2), 62);
|
||||
B1 = ROL64((A43^D3), 55);
|
||||
B2 = ROL64((A44^D4), 39);
|
||||
A40 = B0 ^((~B1)& B2 );
|
||||
A41 = B1 ^((~B2)& B3 );
|
||||
A42 = B2 ^((~B3)& B4 );
|
||||
A43 = B3 ^((~B4)& B0 );
|
||||
A44 = B4 ^((~B0)& B1 );
|
||||
b3 = ROL64((a40^d0), 41);
|
||||
b4 = ROL64((a41^d1), 2);
|
||||
b0 = ROL64((a42^d2), 62);
|
||||
b1 = ROL64((a43^d3), 55);
|
||||
b2 = ROL64((a44^d4), 39);
|
||||
a40 = b0 ^((~b1)& b2 );
|
||||
a41 = b1 ^((~b2)& b3 );
|
||||
a42 = b2 ^((~b3)& b4 );
|
||||
a43 = b3 ^((~b4)& b0 );
|
||||
a44 = b4 ^((~b0)& b1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+276
-29
@@ -56,6 +56,8 @@
|
||||
**
|
||||
** SWARMVTAB
|
||||
**
|
||||
** LEGACY SYNTAX:
|
||||
**
|
||||
** A "swarmvtab" virtual table is created similarly to a unionvtab table:
|
||||
**
|
||||
** CREATE VIRTUAL TABLE <name>
|
||||
@@ -66,13 +68,78 @@
|
||||
** the database file containing the source table. The <callback> option
|
||||
** is optional. If included, it is the name of an application-defined
|
||||
** SQL function that is invoked with the URI of the file, if the file
|
||||
** does not already exist on disk.
|
||||
** does not already exist on disk when required by swarmvtab.
|
||||
**
|
||||
** NEW SYNTAX:
|
||||
**
|
||||
** Using the new syntax, a swarmvtab table is created with:
|
||||
**
|
||||
** CREATE VIRTUAL TABLE <name> USING swarmvtab(
|
||||
** <sql-statement> [, <options>]
|
||||
** );
|
||||
**
|
||||
** where valid <options> are:
|
||||
**
|
||||
** missing=<udf-function-name>
|
||||
** openclose=<udf-function-name>
|
||||
** maxopen=<integer>
|
||||
** <sql-parameter>=<text-value>
|
||||
**
|
||||
** The <sql-statement> must return the same 4 columns as for a swarmvtab
|
||||
** table in legacy mode. However, it may also return a 5th column - the
|
||||
** "context" column. The text value returned in this column is not used
|
||||
** at all by the swarmvtab implementation, except that it is passed as
|
||||
** an additional argument to the two UDF functions that may be invoked
|
||||
** (see below).
|
||||
**
|
||||
** The "missing" option, if present, specifies the name of an SQL UDF
|
||||
** function to be invoked if a database file is not already present on
|
||||
** disk when required by swarmvtab. If the <sql-statement> did not provide
|
||||
** a context column, it is invoked as:
|
||||
**
|
||||
** SELECT <missing-udf>(<database filename/uri>);
|
||||
**
|
||||
** Or, if there was a context column:
|
||||
**
|
||||
** SELECT <missing-udf>(<database filename/uri>, <context>);
|
||||
**
|
||||
** The "openclose" option may also specify a UDF function. This function
|
||||
** is invoked right before swarmvtab opens a database, and right after
|
||||
** it closes one. The first argument - or first two arguments, if
|
||||
** <sql-statement> supplied the context column - is the same as for
|
||||
** the "missing" UDF. Following this, the UDF is passed integer value
|
||||
** 0 before a db is opened, and 1 right after it is closed. If both
|
||||
** a missing and openclose UDF is supplied, the application should expect
|
||||
** the following sequence of calls (for a single database):
|
||||
**
|
||||
** SELECT <openclose-udf>(<db filename>, <context>, 0);
|
||||
** if( db not already on disk ){
|
||||
** SELECT <missing-udf>(<db filename>, <context>);
|
||||
** }
|
||||
** ... swarmvtab uses database ...
|
||||
** SELECT <openclose-udf>(<db filename>, <context>, 1);
|
||||
**
|
||||
** The "maxopen" option is used to configure the maximum number of
|
||||
** database files swarmvtab will hold open simultaneously (default 9).
|
||||
**
|
||||
** If an option name begins with a ":" character, then it is assumed
|
||||
** to be an SQL parameter. In this case, the specified text value is
|
||||
** bound to the same variable of the <sql-statement> before it is
|
||||
** executed. It is an error of the named SQL parameter does not exist.
|
||||
** For example:
|
||||
**
|
||||
** CREATE VIRTUAL TABLE swarm USING swarmvtab(
|
||||
** 'SELECT :path || localfile, tbl, min, max FROM swarmdir',
|
||||
** :path='/home/user/databases/'
|
||||
** missing='missing_func'
|
||||
** );
|
||||
*/
|
||||
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
|
||||
@@ -128,6 +195,7 @@ struct UnionSrc {
|
||||
|
||||
/* Fields used by swarmvtab only */
|
||||
char *zFile; /* Database file containing table zTab */
|
||||
char *zContext; /* Context string, if any */
|
||||
int nUser; /* Current number of users */
|
||||
sqlite3 *db; /* Database handle */
|
||||
UnionSrc *pNextClosable; /* Next in list of closable sources */
|
||||
@@ -145,8 +213,11 @@ struct UnionTab {
|
||||
UnionSrc *aSrc; /* Array of source tables, sorted by rowid */
|
||||
|
||||
/* Used by swarmvtab only */
|
||||
int bHasContext; /* Has context strings */
|
||||
char *zSourceStr; /* Expected unionSourceToStr() value */
|
||||
char *zNotFoundCallback; /* UDF to invoke if file not found on open */
|
||||
sqlite3_stmt *pNotFound; /* UDF to invoke if file not found on open */
|
||||
sqlite3_stmt *pOpenClose; /* UDF to invoke on open and close */
|
||||
|
||||
UnionSrc *pClosable; /* First in list of closable sources */
|
||||
int nOpen; /* Current number of open sources */
|
||||
int nMaxOpen; /* Maximum number of open sources */
|
||||
@@ -351,6 +422,39 @@ static void unionFinalize(int *pRc, sqlite3_stmt *pStmt, char **pzErr){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** If an "openclose" UDF was supplied when this virtual table was created,
|
||||
** invoke it now. The first argument passed is the name of the database
|
||||
** file for source pSrc. The second is integer value bClose.
|
||||
**
|
||||
** If successful, return SQLITE_OK. Otherwise an SQLite error code. In this
|
||||
** case if argument pzErr is not NULL, also set (*pzErr) to an English
|
||||
** language error message. The caller is responsible for eventually freeing
|
||||
** any error message using sqlite3_free().
|
||||
*/
|
||||
static int unionInvokeOpenClose(
|
||||
UnionTab *pTab,
|
||||
UnionSrc *pSrc,
|
||||
int bClose,
|
||||
char **pzErr
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
if( pTab->pOpenClose ){
|
||||
sqlite3_bind_text(pTab->pOpenClose, 1, pSrc->zFile, -1, SQLITE_STATIC);
|
||||
if( pTab->bHasContext ){
|
||||
sqlite3_bind_text(pTab->pOpenClose, 2, pSrc->zContext, -1, SQLITE_STATIC);
|
||||
}
|
||||
sqlite3_bind_int(pTab->pOpenClose, 2+pTab->bHasContext, bClose);
|
||||
sqlite3_step(pTab->pOpenClose);
|
||||
if( SQLITE_OK!=(rc = sqlite3_reset(pTab->pOpenClose)) ){
|
||||
if( pzErr ){
|
||||
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is a no-op for unionvtab. For swarmvtab, it attempts to
|
||||
** close open database files until at most nMax are open. An SQLite error
|
||||
@@ -358,13 +462,16 @@ static void unionFinalize(int *pRc, sqlite3_stmt *pStmt, char **pzErr){
|
||||
*/
|
||||
static void unionCloseSources(UnionTab *pTab, int nMax){
|
||||
while( pTab->pClosable && pTab->nOpen>nMax ){
|
||||
UnionSrc *p;
|
||||
UnionSrc **pp;
|
||||
for(pp=&pTab->pClosable; (*pp)->pNextClosable; pp=&(*pp)->pNextClosable);
|
||||
assert( (*pp)->db );
|
||||
sqlite3_close((*pp)->db);
|
||||
(*pp)->db = 0;
|
||||
p = *pp;
|
||||
assert( p->db );
|
||||
sqlite3_close(p->db);
|
||||
p->db = 0;
|
||||
*pp = 0;
|
||||
pTab->nOpen--;
|
||||
unionInvokeOpenClose(pTab, p, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,13 +484,18 @@ static int unionDisconnect(sqlite3_vtab *pVtab){
|
||||
int i;
|
||||
for(i=0; i<pTab->nSrc; i++){
|
||||
UnionSrc *pSrc = &pTab->aSrc[i];
|
||||
if( pSrc->db ){
|
||||
unionInvokeOpenClose(pTab, pSrc, 1, 0);
|
||||
}
|
||||
sqlite3_free(pSrc->zDb);
|
||||
sqlite3_free(pSrc->zTab);
|
||||
sqlite3_free(pSrc->zFile);
|
||||
sqlite3_free(pSrc->zContext);
|
||||
sqlite3_close(pSrc->db);
|
||||
}
|
||||
sqlite3_finalize(pTab->pNotFound);
|
||||
sqlite3_finalize(pTab->pOpenClose);
|
||||
sqlite3_free(pTab->zSourceStr);
|
||||
sqlite3_free(pTab->zNotFoundCallback);
|
||||
sqlite3_free(pTab->aSrc);
|
||||
sqlite3_free(pTab);
|
||||
}
|
||||
@@ -496,29 +608,31 @@ static int unionSourceCheck(UnionTab *pTab, char **pzErr){
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Try to open the swarmvtab database. If initially unable, invoke the
|
||||
** not-found callback UDF and then try again.
|
||||
*/
|
||||
static int unionOpenDatabaseInner(UnionTab *pTab, UnionSrc *pSrc, char **pzErr){
|
||||
int rc = SQLITE_OK;
|
||||
static const int openFlags =
|
||||
SQLITE_OPEN_READONLY | SQLITE_OPEN_URI;
|
||||
static const int openFlags = SQLITE_OPEN_READONLY | SQLITE_OPEN_URI;
|
||||
int rc;
|
||||
|
||||
rc = unionInvokeOpenClose(pTab, pSrc, 0, pzErr);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
|
||||
rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0);
|
||||
if( rc==SQLITE_OK ) return rc;
|
||||
if( pTab->zNotFoundCallback ){
|
||||
char *zSql = sqlite3_mprintf("SELECT \"%w\"(%Q);",
|
||||
pTab->zNotFoundCallback, pSrc->zFile);
|
||||
if( pTab->pNotFound ){
|
||||
sqlite3_close(pSrc->db);
|
||||
pSrc->db = 0;
|
||||
if( zSql==0 ){
|
||||
*pzErr = sqlite3_mprintf("out of memory");
|
||||
return SQLITE_NOMEM;
|
||||
sqlite3_bind_text(pTab->pNotFound, 1, pSrc->zFile, -1, SQLITE_STATIC);
|
||||
if( pTab->bHasContext ){
|
||||
sqlite3_bind_text(pTab->pNotFound, 2, pSrc->zContext, -1, SQLITE_STATIC);
|
||||
}
|
||||
sqlite3_step(pTab->pNotFound);
|
||||
if( SQLITE_OK!=(rc = sqlite3_reset(pTab->pNotFound)) ){
|
||||
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
|
||||
return rc;
|
||||
}
|
||||
rc = sqlite3_exec(pTab->db, zSql, 0, 0, pzErr);
|
||||
sqlite3_free(zSql);
|
||||
if( rc ) return rc;
|
||||
rc = sqlite3_open_v2(pSrc->zFile, &pSrc->db, openFlags, 0);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -572,6 +686,7 @@ static int unionOpenDatabase(UnionTab *pTab, int iSrc, char **pzErr){
|
||||
}else{
|
||||
sqlite3_close(pSrc->db);
|
||||
pSrc->db = 0;
|
||||
unionInvokeOpenClose(pTab, pSrc, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,6 +742,132 @@ static int unionFinalizeCsrStmt(UnionCsr *pCsr){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the argument is a space, tab, CR or LF character.
|
||||
*/
|
||||
static int union_isspace(char c){
|
||||
return (c==' ' || c=='\n' || c=='\r' || c=='\t');
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the argument is an alphanumeric character in the
|
||||
** ASCII range.
|
||||
*/
|
||||
static int union_isidchar(char c){
|
||||
return ((c>='a' && c<='z') || (c>='A' && c<'Z') || (c>='0' && c<='9'));
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called to handle all arguments following the first
|
||||
** (the SQL statement) passed to a swarmvtab (not unionvtab) CREATE
|
||||
** VIRTUAL TABLE statement. It may bind parameters to the SQL statement
|
||||
** or configure members of the UnionTab object passed as the second
|
||||
** argument.
|
||||
**
|
||||
** Refer to header comments at the top of this file for a description
|
||||
** of the arguments parsed.
|
||||
**
|
||||
** This function is a no-op if *pRc is other than SQLITE_OK when it is
|
||||
** called. Otherwise, if an error occurs, *pRc is set to an SQLite error
|
||||
** code. In this case *pzErr may be set to point to a buffer containing
|
||||
** an English language error message. It is the responsibility of the
|
||||
** caller to eventually free the buffer using sqlite3_free().
|
||||
*/
|
||||
static void unionConfigureVtab(
|
||||
int *pRc, /* IN/OUT: Error code */
|
||||
UnionTab *pTab, /* Table to configure */
|
||||
sqlite3_stmt *pStmt, /* SQL statement to find sources */
|
||||
int nArg, /* Number of entries in azArg[] array */
|
||||
const char * const *azArg, /* Array of arguments to consider */
|
||||
char **pzErr /* OUT: Error message */
|
||||
){
|
||||
int rc = *pRc;
|
||||
int i;
|
||||
if( rc==SQLITE_OK ){
|
||||
pTab->bHasContext = (sqlite3_column_count(pStmt)>4);
|
||||
}
|
||||
for(i=0; rc==SQLITE_OK && i<nArg; i++){
|
||||
char *zArg = unionStrdup(&rc, azArg[i]);
|
||||
if( zArg ){
|
||||
int nOpt = 0; /* Size of option name in bytes */
|
||||
char *zOpt; /* Pointer to option name */
|
||||
char *zVal; /* Pointer to value */
|
||||
|
||||
unionDequote(zArg);
|
||||
zOpt = zArg;
|
||||
while( union_isspace(*zOpt) ) zOpt++;
|
||||
zVal = zOpt;
|
||||
if( *zVal==':' ) zVal++;
|
||||
while( union_isidchar(*zVal) ) zVal++;
|
||||
nOpt = zVal-zOpt;
|
||||
|
||||
while( union_isspace(*zVal) ) zVal++;
|
||||
if( *zVal=='=' ){
|
||||
zOpt[nOpt] = '\0';
|
||||
zVal++;
|
||||
while( union_isspace(*zVal) ) zVal++;
|
||||
zVal = unionStrdup(&rc, zVal);
|
||||
if( zVal ){
|
||||
unionDequote(zVal);
|
||||
if( zOpt[0]==':' ){
|
||||
/* A value to bind to the SQL statement */
|
||||
int iParam = sqlite3_bind_parameter_index(pStmt, zOpt);
|
||||
if( iParam==0 ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"swarmvtab: no such SQL parameter: %s", zOpt
|
||||
);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
rc = sqlite3_bind_text(pStmt, iParam, zVal, -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
}else if( nOpt==7 && 0==sqlite3_strnicmp(zOpt, "maxopen", 7) ){
|
||||
pTab->nMaxOpen = atoi(zVal);
|
||||
if( pTab->nMaxOpen<=0 ){
|
||||
*pzErr = sqlite3_mprintf("swarmvtab: illegal maxopen value");
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}else if( nOpt==7 && 0==sqlite3_strnicmp(zOpt, "missing", 7) ){
|
||||
if( pTab->pNotFound ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"swarmvtab: duplicate \"missing\" option");
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db,
|
||||
"SELECT \"%w\"(?%s)", zVal, pTab->bHasContext ? ",?" : ""
|
||||
);
|
||||
}
|
||||
}else if( nOpt==9 && 0==sqlite3_strnicmp(zOpt, "openclose", 9) ){
|
||||
if( pTab->pOpenClose ){
|
||||
*pzErr = sqlite3_mprintf(
|
||||
"swarmvtab: duplicate \"openclose\" option");
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
pTab->pOpenClose = unionPreparePrintf(&rc, pzErr, pTab->db,
|
||||
"SELECT \"%w\"(?,?%s)", zVal, pTab->bHasContext ? ",?" : ""
|
||||
);
|
||||
}
|
||||
}else{
|
||||
*pzErr = sqlite3_mprintf("swarmvtab: unrecognized option: %s",zOpt);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
sqlite3_free(zVal);
|
||||
}
|
||||
}else{
|
||||
if( i==0 && nArg==1 ){
|
||||
pTab->pNotFound = unionPreparePrintf(&rc, pzErr, pTab->db,
|
||||
"SELECT \"%w\"(?)", zArg
|
||||
);
|
||||
}else{
|
||||
*pzErr = sqlite3_mprintf( "swarmvtab: parse error: %s", azArg[i]);
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
}
|
||||
sqlite3_free(zArg);
|
||||
}
|
||||
}
|
||||
*pRc = rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** xConnect/xCreate method.
|
||||
**
|
||||
@@ -654,7 +895,7 @@ static int unionConnect(
|
||||
/* unionvtab tables may only be created in the temp schema */
|
||||
*pzErr = sqlite3_mprintf("%s tables must be created in TEMP schema", zVtab);
|
||||
rc = SQLITE_ERROR;
|
||||
}else if( argc!=4 && argc!=5 ){
|
||||
}else if( argc<4 || (argc>4 && bSwarm==0) ){
|
||||
*pzErr = sqlite3_mprintf("wrong number of arguments for %s", zVtab);
|
||||
rc = SQLITE_ERROR;
|
||||
}else{
|
||||
@@ -673,6 +914,17 @@ static int unionConnect(
|
||||
|
||||
/* Allocate the UnionTab structure */
|
||||
pTab = unionMalloc(&rc, sizeof(UnionTab));
|
||||
if( pTab ){
|
||||
assert( rc==SQLITE_OK );
|
||||
pTab->db = db;
|
||||
pTab->bSwarm = bSwarm;
|
||||
pTab->nMaxOpen = SWARMVTAB_MAX_OPEN;
|
||||
}
|
||||
|
||||
/* Parse other CVT arguments, if any */
|
||||
if( bSwarm ){
|
||||
unionConfigureVtab(&rc, pTab, pStmt, argc-4, &argv[4], pzErr);
|
||||
}
|
||||
|
||||
/* Iterate through the rows returned by the SQL statement specified
|
||||
** as an argument to the CREATE VIRTUAL TABLE statement. */
|
||||
@@ -715,17 +967,15 @@ static int unionConnect(
|
||||
}else{
|
||||
pSrc->zDb = unionStrdup(&rc, zDb);
|
||||
}
|
||||
if( pTab->bHasContext ){
|
||||
const char *zContext = (const char*)sqlite3_column_text(pStmt, 4);
|
||||
pSrc->zContext = unionStrdup(&rc, zContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
unionFinalize(&rc, pStmt, pzErr);
|
||||
pStmt = 0;
|
||||
|
||||
/* Capture the not-found callback UDF name */
|
||||
if( rc==SQLITE_OK && argc>=5 ){
|
||||
pTab->zNotFoundCallback = unionStrdup(&rc, argv[4]);
|
||||
unionDequote(pTab->zNotFoundCallback);
|
||||
}
|
||||
|
||||
/* It is an error if the SELECT statement returned zero rows. If only
|
||||
** because there is no way to determine the schema of the virtual
|
||||
** table in this case. */
|
||||
@@ -738,9 +988,6 @@ static int unionConnect(
|
||||
** compatible schemas. For swarmvtab, attach the first database and
|
||||
** check that the first table is a rowid table only. */
|
||||
if( rc==SQLITE_OK ){
|
||||
pTab->db = db;
|
||||
pTab->bSwarm = bSwarm;
|
||||
pTab->nMaxOpen = SWARMVTAB_MAX_OPEN;
|
||||
if( bSwarm ){
|
||||
rc = unionOpenDatabase(pTab, 0, pzErr);
|
||||
}else{
|
||||
|
||||
Reference in New Issue
Block a user