We should add a new output argument for xRead method which is in
sqlite3_io_methods structure like this:
int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst, int*
piRealAmt);
The new 'piRealAmt' could be used to report the actual read data, this argument
will greatly boost the ability of VFS Shims. For example, with this argument,
we can write a encryption shim easily.
It's very simple. Basically, you only need adding just one line code per xRead
driver like this:
}else{
pFile->lastErrno = 0; /* not a system error */
/* Unread parts of the buffer must be zero-filled */
memset(&((char*)pBuf)[got], 0, amt-got);
if (piRealAmt) *piRealAmt = (int)got; // <----
return SQLITE_IOERR_SHORT_READ;
}
By using this simple extension, we can write code like this:
//! shim xRead driver for encryption
BAIY_LOCAL int
ReadMethod(
IN OUT sqlite3_file* piFile,
OUT void* pbBuf,
IN int nAmt,
IN sqlite_int64 nnOfst,
OPTIONAL OUT int* piRealAmt)
{
// =========================================================================
// = Init, Guard
ENCVFS_FILE* piOriFile = reinterpret_cast<ENCVFS_FILE*>(piFile);
if (piOriFile->btUnder.empty() || !piOriFile->thCipher.IsValid())
{
return SQLITE_IOERR_READ;
}
sqlite3_file* const piUnder = reinterpret_cast<sqlite3_file*>(
piOriFile->btUnder.ref()
);
// =========================================================================
// = Read
int nReadLen;
piOriFile->btBuf.reserve(nAmt);
const int r = piUnder->pMethods->xRead(
piUnder, piOriFile->btBuf.ref(), nAmt, nnOfst, &nReadLen
);
switch (r)
{
case SQLITE_OK:
nReadLen = nAmt;
break;
case SQLITE_IOERR_SHORT_READ:
break;
default:
return r; // <----
}
// =========================================================================
// = Decrypt
try
{
piOriFile->thCipher->SeekDecryptor(nnOfst);
piOriFile->thCipher->IterDecrypt(
bySBn((BYTE*)pbBuf, nReadLen), piOriFile->btBuf
);
if (SQLITE_IOERR_SHORT_READ == r)
{
memset(((BYTE*)pbBuf)+nReadLen, 0, nAmt-nReadLen);
if (piRealAmt)
{
*piRealAmt = nReadLen;
}
return SQLITE_IOERR_SHORT_READ;
}
else
{
return SQLITE_OK;
}
}
catch (...)
{
LogError(byT("ReadMethod"));
return SQLITE_IOERR_READ;
}
}
--
Best Regards
BaiYang
[email protected]
http://baiy.cn
**** < END OF EMAIL > ****
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users