Index: src/test_multiplex.c ================================================================== --- src/test_multiplex.c +++ src/test_multiplex.c @@ -132,11 +132,11 @@ } *aReal; /* list of all chunks */ int nReal; /* Number of chunks */ char *zName; /* Base filename of this group */ int nName; /* Length of base filename */ int flags; /* Flags used for original opening */ - int nChunkSize; /* Chunk size used for this group */ + unsigned int szChunk; /* Chunk size used for this group */ int bEnabled; /* TRUE to use Multiplex VFS for this file */ multiplexGroup *pNext, *pPrev; /* Doubly linked list of all group objects */ }; /* @@ -492,22 +492,31 @@ rc = SQLITE_NOMEM; } } if( rc==SQLITE_OK ){ - const char *zChunkSize; /* assign pointers to extra space allocated */ char *p = (char *)&pGroup[1]; pMultiplexOpen->pGroup = pGroup; memset(pGroup, 0, sz); pGroup->bEnabled = -1; - pGroup->nChunkSize = SQLITE_MULTIPLEX_CHUNK_SIZE; + pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE; if( flags & SQLITE_OPEN_URI ){ + const char *zChunkSize; zChunkSize = sqlite3_uri_parameter(zName, "chunksize"); if( zChunkSize ){ - int n = atoi(zChunkSize); - if( n>0 ) pGroup->nChunkSize = (n+0xffff)&~0xffff; + unsigned int n = 0; + int i; + for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){ + n = n*10 + zChunkSize[i] - '0'; + } + if( n>0 ){ + pGroup->szChunk = (n+0xffff)&~0xffff; + }else{ + /* A zero or negative chunksize disabled the multiplexor */ + pGroup->bEnabled = 0; + } } } pGroup->zName = p; /* save off base filename, name length, and original open flags */ memcpy(pGroup->zName, zName, nName+1); @@ -533,13 +542,13 @@ ** just disable the multiplexor all togethre. */ rc3 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z, SQLITE_ACCESS_EXISTS, &exists); if( rc3==SQLITE_OK && exists && sz==(sz&0xffff0000) && sz>0 - && sz!=pGroup->nChunkSize ){ - pGroup->nChunkSize = sz; - }else if( rc3==SQLITE_OK && !exists && sz>pGroup->nChunkSize ){ + && sz!=pGroup->szChunk ){ + pGroup->szChunk = sz; + }else if( rc3==SQLITE_OK && !exists && sz>pGroup->szChunk ){ pGroup->bEnabled = 0; } } if( pSubOpen->pMethods->iVersion==1 ){ @@ -654,19 +663,18 @@ }else{ rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst); } }else{ while( iAmt > 0 ){ - int i = (int)(iOfst / pGroup->nChunkSize); + int i = (int)(iOfst / pGroup->szChunk); sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); if( pSubOpen ){ - int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - - pGroup->nChunkSize; + int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk; if( extra<0 ) extra = 0; iAmt -= extra; rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, - iOfst % pGroup->nChunkSize); + iOfst % pGroup->szChunk); if( rc!=SQLITE_OK ) break; pBuf = (char *)pBuf + iAmt; iOfst += iAmt; iAmt = extra; }else{ @@ -700,19 +708,19 @@ }else{ rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst); } }else{ while( iAmt > 0 ){ - int i = (int)(iOfst / pGroup->nChunkSize); + int i = (int)(iOfst / pGroup->szChunk); sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL); if( pSubOpen ){ - int extra = ((int)(iOfst % pGroup->nChunkSize) + iAmt) - - pGroup->nChunkSize; + int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - + pGroup->szChunk; if( extra<0 ) extra = 0; iAmt -= extra; rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, - iOfst % pGroup->nChunkSize); + iOfst % pGroup->szChunk); if( rc!=SQLITE_OK ) break; pBuf = (char *)pBuf + iAmt; iOfst += iAmt; iAmt = extra; }else{ @@ -745,16 +753,16 @@ int rc2; int i; sqlite3_file *pSubOpen; sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ /* delete the chunks above the truncate limit */ - for(i=(int)(size / pGroup->nChunkSize)+1; inReal; i++){ + for(i=(int)(size / pGroup->szChunk)+1; inReal; i++){ multiplexSubClose(pGroup, i, pOrigVfs); } - pSubOpen = multiplexSubOpen(pGroup, (int)(size/pGroup->nChunkSize), &rc2,0); + pSubOpen = multiplexSubOpen(pGroup, (int)(size/pGroup->szChunk), &rc2,0); if( pSubOpen ){ - rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->nChunkSize); + rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk); if( rc2!=SQLITE_OK ) rc = rc2; }else{ rc = SQLITE_IOERR_TRUNCATE; } } @@ -819,11 +827,11 @@ sqlite3_int64 sz; rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz); if( rc2!=SQLITE_OK ){ rc = rc2; }else{ - if( sz>pGroup->nChunkSize ){ + if( sz>pGroup->szChunk ){ rc = SQLITE_IOERR_FSTAT; } *pSize += sz; } }else{ @@ -889,18 +897,18 @@ rc = SQLITE_OK; } break; case MULTIPLEX_CTRL_SET_CHUNK_SIZE: if( pArg ) { - int nChunkSize = *(int *)pArg; - if( nChunkSize<1 ){ + unsigned int szChunk = *(unsigned*)pArg; + if( szChunk<1 ){ rc = SQLITE_MISUSE; }else{ /* Round up to nearest multiple of MAX_PAGE_SIZE. */ - nChunkSize = (nChunkSize + (MAX_PAGE_SIZE-1)); - nChunkSize &= ~(MAX_PAGE_SIZE-1); - pGroup->nChunkSize = nChunkSize; + szChunk = (szChunk + (MAX_PAGE_SIZE-1)); + szChunk &= ~(MAX_PAGE_SIZE-1); + pGroup->szChunk = szChunk; rc = SQLITE_OK; } } break; case MULTIPLEX_CTRL_SET_MAX_CHUNKS: @@ -1192,11 +1200,11 @@ } Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewIntObj(nChunks)); Tcl_ListObjAppendElement(interp, pGroupTerm, - Tcl_NewIntObj(pGroup->nChunkSize)); + Tcl_NewIntObj(pGroup->szChunk)); Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewIntObj(pGroup->nReal)); Tcl_ListObjAppendElement(interp, pResult, pGroupTerm); } Index: test/multiplex.test ================================================================== --- test/multiplex.test +++ test/multiplex.test @@ -78,11 +78,10 @@ do_test multiplex-1.9.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} do_test multiplex-1.9.2 { sqlite3 db test.db } {} do_test multiplex-1.9.3 { multiplex_set db main 32768 16 } {SQLITE_OK} do_test multiplex-1.9.4 { multiplex_set db main 32768 -1 } {SQLITE_OK} -do_test multiplex-1.9.5 { multiplex_set db main -1 16 } {SQLITE_MISUSE} do_test multiplex-1.9.6 { multiplex_set db main 31 16 } {SQLITE_OK} do_test multiplex-1.9.7 { multiplex_set db main 32768 100 } {SQLITE_OK} do_test multiplex-1.9.8 { multiplex_set db main 1073741824 1 } {SQLITE_OK} do_test multiplex-1.9.9 { db close } {} do_test multiplex-1.9.10 { sqlite3_multiplex_shutdown } {SQLITE_OK} @@ -89,11 +88,10 @@ do_test multiplex-1.10.1 { sqlite3_multiplex_initialize "" 1 } {SQLITE_OK} do_test multiplex-1.10.2 { sqlite3 db test.db } {} do_test multiplex-1.10.3 { lindex [ catchsql { SELECT multiplex_control(2, 32768); } ] 0 } {0} do_test multiplex-1.10.4 { lindex [ catchsql { SELECT multiplex_control(3, -1); } ] 0 } {0} -do_test multiplex-1.10.5 { lindex [ catchsql { SELECT multiplex_control(2, -1); } ] 0 } {1} do_test multiplex-1.10.6 { lindex [ catchsql { SELECT multiplex_control(2, 31); } ] 0 } {0} do_test multiplex-1.10.7 { lindex [ catchsql { SELECT multiplex_control(3, 100); } ] 0 } {0} do_test multiplex-1.10.8 { lindex [ catchsql { SELECT multiplex_control(2, 1073741824); } ] 0 } {0} do_test multiplex-1.10.9 { db close } {} do_test multiplex-1.10.10 { sqlite3_multiplex_shutdown } {SQLITE_OK}