Speed up base64 conversions, and add test with more data for the baseNN conversion to grind.
FossilOrigin-Name: 6c84ae4ba83713c751fddff8be41686bbcb525ac8135e1520436c62d0bc23d2c
This commit is contained in:
parent
809be56218
commit
9b9017def4
70
ext/misc/base64.c
Normal file → Executable file
70
ext/misc/base64.c
Normal file → Executable file
@ -92,42 +92,46 @@ static const char b64Numerals[64+1]
|
||||
#define IS_BX_DIGIT(bdp) (((ubyte)(bdp))<0x80)
|
||||
#define IS_BX_WS(bdp) ((bdp)==WS)
|
||||
#define IS_BX_PAD(bdp) ((bdp)==PC)
|
||||
#define BX_NUMERAL(dv) (b64Numerals[dv])
|
||||
#define BX_NUMERAL(dv) (b64Numerals[(ubyte)(dv)])
|
||||
/* Width of base64 lines. Should be an integer multiple of 4. */
|
||||
#define B64_DARK_MAX 72
|
||||
|
||||
/* Encode a byte buffer into base64 text. If pSep!=0, it's a C string
|
||||
** to be appended to encoded groups to limit their length to B64_DARK_MAX
|
||||
** or to terminate the last group (to aid concatenation.)
|
||||
/* Encode a byte buffer into base64 text with linefeeds appended to limit
|
||||
** encoded group lengths to B64_DARK_MAX or to terminate the last group.
|
||||
*/
|
||||
static char* toBase64( ubyte *pIn, int nbIn, char *pOut, char *pSep ){
|
||||
static char* toBase64( ubyte *pIn, int nbIn, char *pOut ){
|
||||
int nCol = 0;
|
||||
*pOut = 0;
|
||||
while( nbIn > 0 ){
|
||||
static signed char ncio[] = { 0, 2, 3, 4 };
|
||||
int nbi = (nbIn > 3)? 3 : nbIn;
|
||||
signed char nc;
|
||||
int nbe;
|
||||
unsigned long qv = (ubyte)*pIn++;
|
||||
for( nbe=1; nbe<3; ++nbe ){
|
||||
ubyte b = (nbe<nbi)? *pIn++ : 0;
|
||||
qv = (qv<<8) | b;
|
||||
while( nbIn >= 3 ){
|
||||
/* Do the bit-shuffle, exploiting unsigned input to avoid masking. */
|
||||
pOut[0] = BX_NUMERAL(pIn[0]>>2);
|
||||
pOut[1] = BX_NUMERAL(((pIn[0]<<4)|(pIn[1]>>4))&0x3f);
|
||||
pOut[2] = BX_NUMERAL(((pIn[1]&0xf)<<2)|(pIn[2]>>6));
|
||||
pOut[3] = BX_NUMERAL(pIn[2]&0x3f);
|
||||
pOut += 4;
|
||||
nbIn -= 3;
|
||||
pIn += 3;
|
||||
if( (nCol += 4)>=B64_DARK_MAX || nbIn<=0 ){
|
||||
*pOut++ = '\n';
|
||||
nCol = 0;
|
||||
}
|
||||
}
|
||||
if( nbIn > 0 ){
|
||||
signed char nco = nbIn+1;
|
||||
int nbe;
|
||||
unsigned long qv = *pIn++;
|
||||
for( nbe=1; nbe<3; ++nbe ){
|
||||
qv <<= 8;
|
||||
if( nbe<nbIn ) qv |= *pIn++;
|
||||
}
|
||||
nc = ncio[nbi];
|
||||
nbIn -= nbi;
|
||||
for( nbe=3; nbe>=0; --nbe ){
|
||||
char ce = (nbe<nc)? BX_NUMERAL((ubyte)(qv & 0x3f)) : PAD_CHAR;
|
||||
char ce = (nbe<nco)? BX_NUMERAL((ubyte)(qv & 0x3f)) : PAD_CHAR;
|
||||
qv >>= 6;
|
||||
pOut[nbe] = ce;
|
||||
}
|
||||
pOut += 4;
|
||||
if( pSep && ((nCol += 4)>=B64_DARK_MAX || nbIn<=0) ){
|
||||
char *p = pSep;
|
||||
while( *p ) *pOut++ = *p++;
|
||||
nCol = 0;
|
||||
}
|
||||
*pOut = 0;
|
||||
*pOut++ = '\n';
|
||||
}
|
||||
*pOut = 0;
|
||||
return pOut;
|
||||
}
|
||||
|
||||
@ -157,11 +161,12 @@ static ubyte* fromBase64( char *pIn, int ncIn, ubyte *pOut ){
|
||||
ubyte bdp = BX_DV_PROTO(c);
|
||||
switch( bdp ){
|
||||
case ND:
|
||||
/* Treat non-digits as pad, but they terminate decode too. */
|
||||
/* Treat dark non-digits as pad, but they terminate decode too. */
|
||||
ncIn = 0;
|
||||
/* fall thru */
|
||||
case WS:
|
||||
/* Treat whitespace as pad */
|
||||
/* Treat whitespace as pad and terminate this group.*/
|
||||
nti = nac;
|
||||
/* fall thru */
|
||||
case PC:
|
||||
bdp = 0;
|
||||
@ -172,10 +177,15 @@ static ubyte* fromBase64( char *pIn, int ncIn, ubyte *pOut ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
nti = 2;
|
||||
while( nbo-- > 0 ){
|
||||
*pOut++ = (qv >> (8*nti--))&0xff;
|
||||
switch( nbo ){
|
||||
case 3:
|
||||
pOut[2] = (qv) & 0xff;
|
||||
case 2:
|
||||
pOut[1] = (qv>>8) & 0xff;
|
||||
case 1:
|
||||
pOut[0] = (qv>>16) & 0xff;
|
||||
}
|
||||
pOut += nbo;
|
||||
}
|
||||
return pOut;
|
||||
}
|
||||
@ -200,7 +210,7 @@ static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
|
||||
cBuf = sqlite3_malloc(nc);
|
||||
if( !cBuf ) goto memFail;
|
||||
bBuf = (ubyte*)sqlite3_value_blob(av[0]);
|
||||
nc = (int)(toBase64(bBuf, nb, cBuf, "\n") - cBuf);
|
||||
nc = (int)(toBase64(bBuf, nb, cBuf) - cBuf);
|
||||
sqlite3_result_text(context, cBuf, nc, sqlite3_free);
|
||||
break;
|
||||
case SQLITE_TEXT:
|
||||
|
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Add\smore\sbaseNN\stests,\sget\soversize\serror\strapping\sworking,\sand\ssync\sw/trunk
|
||||
D 2022-11-22T22:46:41.866
|
||||
C Speed\sup\sbase64\sconversions,\sand\sadd\stest\swith\smore\sdata\sfor\sthe\sbaseNN\sconversion\sto\sgrind.
|
||||
D 2022-11-24T02:59:33.748
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -289,7 +289,7 @@ F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f23
|
||||
F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358
|
||||
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
|
||||
F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824
|
||||
F ext/misc/base64.c 0472f388e1a6c168912a363dfbe88d2d588325fba7ce6101f726d01b54fe6d3b
|
||||
F ext/misc/base64.c 6333194e5c2e85b0748116ad4004bf3e070347cc09984aaa8d462fb3fc0566b6 x
|
||||
F ext/misc/base85.c 9005549904fc06ec2f3ff96970709f92f76e2d9ec2b785553ac32908ddc1baa0
|
||||
F ext/misc/basexx.c 678dcc83894f78c26fd3662b322886777cc26bf2b40809236cd2abdad532a33c
|
||||
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
|
||||
@ -816,7 +816,7 @@ F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135
|
||||
F test/backup_malloc.test 0c9abdf74c51e7bedb66d504cd684f28d4bd4027
|
||||
F test/badutf.test d5360fc31f643d37a973ab0d8b4fb85799c3169f
|
||||
F test/badutf2.test f310fd3b24a491b6b77bccdf14923b85d6ebcce751068c180d93a6b8ff854399
|
||||
F test/basexx1.test 9b12557d2b5bd017f9f8a8698239438ced5899c3ee55d9a549f74d90b16e51a6
|
||||
F test/basexx1.test d8a50f0744b93dca656625597bcd3499ff4b9a4ea2a82432b119b7d46e3e0c08
|
||||
F test/bc_common.tcl b5e42d80305be95697e6370e015af571e5333a1c
|
||||
F test/bestindex1.test 856a453dff8c68b4568601eed5a8b5e20b4763af9229f3947c215729ed878db0
|
||||
F test/bestindex2.test 394ff8fbf34703391247116d6a44e1c50ee7282236ee77909044573cefc37bc0
|
||||
@ -2063,8 +2063,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P ff67460e1a3d21c9ca7cbd171fbc5e6cbdb3797de359887f851776b73b732fdf 9ec923b5dc24d6082da8d42bc0ee8ab1c418912625c0c56de9627be2c818ef98
|
||||
R 36565c16629af64673142ebb24820a85
|
||||
P 03819e9368fd9f78f351147a1dc865743f9634893e43a9d1e3d7cbaf4c966069
|
||||
R f94c977ea1969bc60efbcf2158a80ba4
|
||||
U larrybr
|
||||
Z 3e47c0e49ec42d7b0a58333b563577b4
|
||||
Z 312bc23355f0a0c3b5b7524b3c0fa709
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
03819e9368fd9f78f351147a1dc865743f9634893e43a9d1e3d7cbaf4c966069
|
||||
6c84ae4ba83713c751fddff8be41686bbcb525ac8135e1520436c62d0bc23d2c
|
@ -138,4 +138,18 @@ do_catchsql_test 116 {
|
||||
SELECT is_base85(x'00');
|
||||
} {1 {is_base85 accepts only text or NULL}}
|
||||
|
||||
# Round-trip many bigger random blobs.
|
||||
|
||||
do_execsql_test 117 {
|
||||
CREATE TABLE bs(b blob, num);
|
||||
INSERT INTO bs SELECT randomblob(4000 + n%3), n
|
||||
FROM (
|
||||
WITH RECURSIVE seq(n) AS (
|
||||
VALUES(1) UNION ALL SELECT n+1
|
||||
FROM seq WHERE n<100
|
||||
) SELECT n FROM seq);
|
||||
SELECT num FROM bs WHERE base64(base64(b))!=b;
|
||||
SELECT num FROM bs WHERE base85(base85(b))!=b;
|
||||
} {}
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user