2021SC@SDUSC
接着上次继续看文件操作。
删除命名文件
static int winDelete(
sqlite3_vfs *pVfs, /*未用于win32 */
const char *zFilename, /* 要删除的文件名*/
int syncDir /* 未用于 win32 */
){
int cnt = 0;
int rc;
DWORD attr;
DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
SimulateIOError(return SQLITE_IOERR_DELETE);
OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
do {
#if SQLITE_OS_WINRT
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
&sAttrData) ){
attr = sAttrData.dwFileAttributes;
}else{
lastErrno = osGetLastError();
if( lastErrno==ERROR_FILE_NOT_FOUND
|| lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT;
}else{
rc = SQLITE_ERROR;
}
break;
}
#else
attr = osGetFileAttributesW(zConverted);
#endif
if ( attr==INVALID_FILE_ATTRIBUTES ){
lastErrno = osGetLastError();
if( lastErrno==ERROR_FILE_NOT_FOUND
|| lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT;
}else{
rc = SQLITE_ERROR;
}
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
rc = SQLITE_ERROR; /*只提供文件*/
break;
}
if ( osDeleteFileW(zConverted) ){
rc = SQLITE_OK; /* 删除完成*/
break;
}
if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* 不再重试*/
break;
}
} while(1);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
do {
attr = osGetFileAttributesA(zConverted);
if ( attr==INVALID_FILE_ATTRIBUTES ){
lastErrno = osGetLastError();
if( lastErrno==ERROR_FILE_NOT_FOUND
|| lastErrno==ERROR_PATH_NOT_FOUND ){
rc = SQLITE_IOERR_DELETE_NOENT;
}else{
rc = SQLITE_ERROR;
}
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
rc = SQLITE_ERROR;
break;
}
if ( osDeleteFileA(zConverted) ){
rc = SQLITE_OK; /* 删除完成 */
break;
}
if ( !winRetryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /*不再重试 */
break;
}
} while(1);
}
#endif
if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
}else{
winLogIoerr(cnt, __LINE__);
}
sqlite3_free(zConverted);
OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
return rc;
}
检查文件的存在和状态
static int winAccess(
sqlite3_vfs *pVfs, /*未用于 win32 */
const char *zFilename, /* 要检查的文件名 */
int flags, /* 要对这个文件进行测试的类型 */
int *pResOut /* 退出:结果 */
){
DWORD attr;
int rc = 0;
DWORD lastErrno = 0;
void *zConverted;
UNUSED_PARAMETER(pVfs);
SimulateIOError( return SQLITE_IOERR_ACCESS; );
OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
zFilename, flags, pResOut));
zConverted = winConvertFromUtf8Filename(zFilename);
if( zConverted==0 ){
OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
return SQLITE_IOERR_NOMEM_BKPT;
}
if( osIsNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
&sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
if( rc ){
/* 对于 SQLITE_ACCESS_EXISTS 查询, 将零长度文件视为不存在*/
if( flags==SQLITE_ACCESS_EXISTS
&& sAttrData.nFileSizeHigh==0
&& sAttrData.nFileSizeLow==0 ){
attr = INVALID_FILE_ATTRIBUTES;
}else{
attr = sAttrData.dwFileAttributes;
}
}else{
winLogIoerr(cnt, __LINE__);
if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
sqlite3_free(zConverted);
return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
zFilename);
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
attr = osGetFileAttributesA((char*)zConverted);
}
#endif
sqlite3_free(zConverted);
switch( flags ){
case SQLITE_ACCESS_READ:
case SQLITE_ACCESS_EXISTS:
rc = attr!=INVALID_FILE_ATTRIBUTES;
break;
case SQLITE_ACCESS_READWRITE:
rc = attr!=INVALID_FILE_ATTRIBUTES &&
(attr & FILE_ATTRIBUTE_READONLY)==0;
break;
default:
assert(!"Invalid flags argument");
}
*pResOut = rc;
OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
zFilename, pResOut, *pResOut));
return SQLITE_OK;
}
如果指定的路径以“长路径”前缀开头,则返回非零。
static BOOL winIsLongPathPrefix(
const char *zPathname
){
return ( zPathname[0]=='\\' && zPathname[1]=='\\'
&& zPathname[2]=='?' && zPathname[3]=='\\' );
}
如果指定的路径名以驱动器号开头,则返回非零值,后面跟着冒号字符。
static BOOL winIsDriveLetterAndColon(
const char *zPathname
){
return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
}
如果指定的路径名称应逐字使用,则返回非零。如果该函数返回非零,则调用函数必须逐字使用提供的路径名-或-使用GetFullPathName Win 32 API函数(如果可用)将其解析为完整路径名。
static BOOL winIsVerbatimPathname(
const char *zPathname
){
/*如果路径名以正斜杠、反斜杠、字母或冒号开头,则返回true*/
if ( winIsDirSep(zPathname[0]) ){
return TRUE;
}
if ( winIsDriveLetterAndColon(zPathname) ){
return TRUE;
}
将相对路径名转换为完整路径名。将完整的路径名写入Zout[]。Zout[]的大小至少为pVfs->mxPathname字节
static int winFullPathname(
sqlite3_vfs *pVfs, /*指向VFS对象的指针 */
const char *zRelative, /*可能是相对输入路径*/
int nFull, /* 输出缓冲区的大小(以字节为单位) */
char *zFull /*输出缓冲区 */
){
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
DWORD nByte;
void *zConverted;
char *zOut;
#endif
用于打开共享库、在共享库中查找入口点和关闭共享库的接口。
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
#if defined(__CYGWIN__)
int nFull = pVfs->mxPathname+1;
char *zFull = sqlite3MallocZero( nFull );
void *zConverted = 0;
if( zFull==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
sqlite3_free(zFull);
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
zConverted = winConvertFromUtf8Filename(zFull);
sqlite3_free(zFull);
#else
void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
#endif
随机采集者的状态信息。
typedef struct EntropyGatherer EntropyGatherer;
struct EntropyGatherer {
unsigned char *a; /*将熵聚集到这个缓冲区中*/
int na; /*a[]的大小(以字节为单位)*/
int i; /*XOR下一个输入到[i]*/
int nXor; /*已完成的异或操作数目*/};
#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
/*将熵的z字节混合到p.*/
static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){
int j, k;
for(j=0, k=p->i; j<sz; j++){
p->a[k++] ^= x[j];
if( k>=p->na ) k = 0;
}
p->i = k;
p->nXor += sz;
}
#endif
将随机的nBuf字节写入zBuf。
static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
UNUSED_PARAMETER(pVfs);
memset(zBuf, 0, nBuf);
return nBuf;
#else
EntropyGatherer e;
UNUSED_PARAMETER(pVfs);
memset(zBuf, 0, nBuf);
e.a = (unsigned char*)zBuf;
e.na = nBuf;
e.nXor = 0;
e.i = 0;
{
SYSTEMTIME x;
osGetSystemTime(&x);
xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));
}
{
DWORD pid = osGetCurrentProcessId();
xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));
}
}
睡眠一会儿,返回睡眠的时间。
static int winSleep(sqlite3_vfs *pVfs, int microsec){
sqlite3_win32_sleep((microsec+999)/1000);
UNUSED_PARAMETER(pVfs);
return ((microsec+999)/1000)*1000;
}
以下变量(如果设置为非零值)被解释为自1970年以来的秒数,并用于在测试期间设置sqlite3OsCurrentTime()的结果。
#ifdef SQLITE_TEST
int sqlite3_current_time = 0; /*自1970年以来,以秒为单位伪造系统时间。*/
#endif
查找当前时间(通用协调时间)。将当前时间和日期作为朱利安日号写入*prNow并返回0。如果找不到时间和日期,请返回1。
static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
int rc;
sqlite3_int64 i;
rc = winCurrentTimeInt64(pVfs, &i);
if( !rc ){
*prNow = i/86400000.0;
}
return rc;
}