📄 file.cpp
字号:
}bool ThreadFile::operator++(void){ off_t eof; fcb_t *fcb = getFCB(); fcb->pos += fcb->len; enterMutex();#ifdef WIN32 eof = SetFilePointer(fd, 0l, NULL, FILE_END);#else eof = lseek(fd, 0l, SEEK_END);#endif leaveMutex(); if(fcb->pos >= eof) { fcb->pos = eof; return true; } return false;}bool ThreadFile::operator--(void){ fcb_t *fcb = getFCB(); fcb->pos -= fcb->len; if(fcb->pos <= 0) { fcb->pos = 0; return true; } return false;}SharedFile::SharedFile(const char *path) :RandomFile(path){ fcb.address = NULL; fcb.len = 0; fcb.pos = 0; open(path);}SharedFile::SharedFile(const SharedFile &sh) :RandomFile(sh){}SharedFile::~SharedFile(){ final();}SharedFile::Error SharedFile::open(const char *path){#ifdef WIN32 if(fd != INVALID_HANDLE_VALUE)#else if(fd > -1)#endif final(); if(path != pathname) { if(pathname) delString(pathname); pathname = newString(path); } flags.initial = false;#ifdef WIN32 fd = CreateFile(pathname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if(fd == INVALID_HANDLE_VALUE) { flags.initial = true; fd = CreateFile(pathname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); } if(fd == INVALID_HANDLE_VALUE) return errOpenFailed; return errSuccess;#else fd = ::open(pathname, O_RDWR); if(fd < 0) { flags.initial = true; fd = ::open(pathname, O_CREAT | O_RDWR | O_TRUNC, (int)attrPrivate); } if(fd < 0) return error(errOpenFailed);#ifdef LOCK_SH if(flock(fd, LOCK_SH | LOCK_NB)) { close(fd); fd = -1; return error(errOpenInUse); }#endif return errSuccess;#endif // WIN32}SharedFile::Error SharedFile::fetch(caddr_t address, ccxx_size_t len, off_t pos){#ifdef WIN32 if(fd == INVALID_HANDLE_VALUE)#else if(fd < 0)#endif return errNotOpened; enterMutex(); if(address) fcb.address = address; if(len) fcb.len = len; if(pos != -1) fcb.pos = pos;#ifdef WIN32 Thread::Cancel save = Thread::enterCancel(); OVERLAPPED over; SetFilePointer(fd, fcb.pos, NULL, FILE_BEGIN); over.hEvent = 0; over.Offset = fcb.pos; over.OffsetHigh = 0; LockFileEx(fd, LOCKFILE_EXCLUSIVE_LOCK, 0, fcb.len, 0, &over); DWORD count; if(!ReadFile(fd, fcb.address, fcb.len, &count, NULL)) { Thread::exitCancel(save); leaveMutex(); return errReadFailure; } Thread::exitCancel(save); leaveMutex(); if(count < fcb.len) return errReadIncomplete; return errSuccess;#else lseek(fd, fcb.pos, SEEK_SET); lockf(fd, F_LOCK, fcb.len); int io = ::read(fd, fcb.address, fcb.len); leaveMutex(); if((size_t) io == fcb.len) return errSuccess; if(io > -1) return errReadIncomplete; switch(errno) { case EINTR: return errReadInterrupted; default: return errReadFailure; }#endif}#ifndef WIN32SharedFile::Error SharedFile::clear(ccxx_size_t len, off_t pos){ if(fd < 0) return errNotOpened; enterMutex(); if(len) fcb.len = len; if(pos != -1) fcb.pos = pos; lseek(fd, fcb.pos, SEEK_SET); lockf(fd, F_ULOCK, fcb.len); leaveMutex(); return errSuccess;}#endif // ndef WIN32SharedFile::Error SharedFile::update(caddr_t address, ccxx_size_t len, off_t pos){#ifdef WIN32 if(fd == INVALID_HANDLE_VALUE)#else if(fd < 0)#endif return errNotOpened; enterMutex(); if(address) fcb.address = address; if(len) fcb.len = len; if(pos != -1) fcb.pos = pos;#ifdef WIN32 Thread::Cancel save = Thread::enterCancel(); OVERLAPPED over; SetFilePointer(fd, fcb.pos, NULL, FILE_BEGIN); over.hEvent = 0; over.Offset = pos; over.OffsetHigh = 0; DWORD count; if(!WriteFile(fd, fcb.address, fcb.len, &count, NULL)) { SetFilePointer(fd, fcb.pos, NULL, FILE_CURRENT); UnlockFileEx(fd, 0, len, 0, &over); Thread::exitCancel(save); leaveMutex(); return errWriteFailure; } SetFilePointer(fd, fcb.pos, NULL, FILE_CURRENT); UnlockFileEx(fd, 0, len, 0, &over); Thread::exitCancel(save); leaveMutex(); if(count < fcb.len) return errWriteIncomplete; return errSuccess;#else lseek(fd, fcb.pos, SEEK_SET); int io = ::write(fd, fcb.address, fcb.len); lockf(fd, F_ULOCK, fcb.len); leaveMutex(); if((size_t) io == fcb.len) return errSuccess; if(io > -1) return errWriteIncomplete; switch(errno) { case EINTR: return errWriteInterrupted; default: return errWriteFailure; }#endif // WIN32}SharedFile::Error SharedFile::append(caddr_t address, ccxx_size_t len){#ifdef WIN32 if(fd == INVALID_HANDLE_VALUE)#else if(fd < 0)#endif return errNotOpened; enterMutex(); if(address) fcb.address = address; if(len) fcb.len = len;#ifdef WIN32 Thread::Cancel save = Thread::enterCancel(); fcb.pos = SetFilePointer(fd, 0l, NULL, FILE_END); OVERLAPPED over; over.hEvent = 0; over.Offset = fcb.pos; over.OffsetHigh = 0; LONG eof = fcb.pos; LockFileEx(fd, LOCKFILE_EXCLUSIVE_LOCK, 0, 0x7fffffff, 0, &over); fcb.pos = SetFilePointer(fd, 0l, NULL, FILE_END); DWORD count; if(!WriteFile(fd, fcb.address, fcb.len, &count, NULL)) { SetFilePointer(fd, eof, NULL, FILE_CURRENT); Thread::exitCancel(save); UnlockFileEx(fd, 0, 0x7fffffff, 0, &over); Thread::exitCancel(save); leaveMutex(); return errWriteFailure; } SetFilePointer(fd, eof, NULL, FILE_CURRENT); UnlockFileEx(fd, 0, 0x7fffffff, 0, &over); Thread::exitCancel(save); leaveMutex(); if(count < fcb.len) return errWriteIncomplete; return errSuccess;#else fcb.pos = lseek(fd, 0l, SEEK_END); lockf(fd, F_LOCK, -1); fcb.pos = lseek(fd, 0l, SEEK_END); int io = ::write(fd, fcb.address, fcb.len); lseek(fd, fcb.pos, SEEK_SET); lockf(fd, F_ULOCK, -1); leaveMutex(); if((size_t) io == fcb.len) return errSuccess; if(io > -1) return errWriteIncomplete; switch(errno) { case EINTR: return errWriteInterrupted; default: return errWriteFailure; }#endif // WIN32}off_t SharedFile::getPosition(void){ return fcb.pos;}bool SharedFile::operator++(void){ off_t eof; enterMutex(); fcb.pos += fcb.len;#ifdef WIN32 eof = SetFilePointer(fd, 0l, NULL, FILE_END);#else eof = lseek(fd, 0l, SEEK_END);#endif if(fcb.pos >= eof) { fcb.pos = eof; leaveMutex(); return true; } leaveMutex(); return false;}bool SharedFile::operator--(void){ enterMutex(); fcb.pos -= fcb.len; if(fcb.pos <= 0) { fcb.pos = 0; leaveMutex(); return true; } leaveMutex(); return false;}size_t MappedFile::pageAligned(size_t size){ size_t pages = size / Process::getPageSize(); if(size % Process::getPageSize()) ++pages; return pages * Process::getPageSize();}#ifdef WIN32static void makemapname(const char *source, char *target){ unsigned count = 60; while(*source && count--) { if(*source == '/' || *source == '\\') *(target++) = '_'; else *(target++) = toupper(*source); ++source; } *target = 0;}MappedFile::MappedFile(const char *fname, Access mode, size_t size) :RandomFile(fname){ DWORD share, page; map = INVALID_HANDLE_VALUE; fcb.address = NULL; switch(mode) { case accessReadOnly: share = FILE_SHARE_READ; page = PAGE_READONLY; prot = FILE_MAP_READ; break; case accessWriteOnly: share = FILE_SHARE_WRITE; page = PAGE_WRITECOPY; prot = FILE_MAP_COPY; break; case accessReadWrite: share = FILE_SHARE_READ|FILE_SHARE_WRITE; page = PAGE_READWRITE; prot = FILE_MAP_WRITE; } fd = CreateFile(pathname, mode, share, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if(fd == INVALID_HANDLE_VALUE) { error(errOpenFailed); return; } SetFilePointer(fd, (LONG)size, 0, FILE_BEGIN); SetEndOfFile(fd); makemapname(fname, mapname); map = CreateFileMapping(fd, NULL, page, 0, 0, mapname); if(!map) error(errMapFailed); fcb.address = MapViewOfFile(map, prot, 0, 0, size); fcb.len = (ccxx_size_t)size; fcb.pos = 0; if(!fcb.address) error(errMapFailed);}MappedFile::MappedFile(const char *fname, Access mode) :RandomFile(fname){ DWORD share, page; map = INVALID_HANDLE_VALUE; fcb.address = NULL; switch(mode) { case accessReadOnly: share = FILE_SHARE_READ; page = PAGE_READONLY; prot = FILE_MAP_READ; break; case accessWriteOnly: share = FILE_SHARE_WRITE; page = PAGE_WRITECOPY; prot = FILE_MAP_COPY; break; case accessReadWrite: share = FILE_SHARE_READ|FILE_SHARE_WRITE; page = PAGE_READWRITE; prot = FILE_MAP_WRITE; } fd = CreateFile(pathname, mode, share, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if(fd == INVALID_HANDLE_VALUE) { error(errOpenFailed); return; } makemapname(fname, mapname); map = CreateFileMapping(fd, NULL, page, 0, 0, mapname); if(!map) error(errMapFailed);}MappedFile::MappedFile(const char *fname, pos_t pos, size_t len, Access mode) :RandomFile(fname){ DWORD share, page; map = INVALID_HANDLE_VALUE; fcb.address = NULL; switch(mode) { case accessReadOnly: share = FILE_SHARE_READ; page = PAGE_READONLY; prot = FILE_MAP_READ; break; case accessWriteOnly: share = FILE_SHARE_WRITE; page = PAGE_WRITECOPY; prot = FILE_MAP_COPY; break; case accessReadWrite: share = FILE_SHARE_READ|FILE_SHARE_WRITE; page = PAGE_READWRITE; prot = FILE_MAP_WRITE; } fd = CreateFile(pathname, mode, share, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); if(fd == INVALID_HANDLE_VALUE) { error(errOpenFailed); return; } makemapname(fname, mapname); map = CreateFileMapping(fd, NULL, page, 0, 0, mapname); if(!map) { error(errMapFailed); return; } fcb.address = MapViewOfFile(map, prot, 0, pos, len); fcb.len = (ccxx_size_t)len; fcb.pos = pos; if(!fcb.address) error(errMapFailed);}MappedFile::~MappedFile(){ if(fcb.address) { unlock(); UnmapViewOfFile(fcb.address); } if(map != INVALID_HANDLE_VALUE) CloseHandle(map); final();}void MappedFile::sync(void){}void MappedFile::sync(caddr_t address, size_t len){}void MappedFile::release(caddr_t address, size_t len){ if(fcb.address) { unlock(); UnmapViewOfFile(fcb.address); } fcb.address = NULL;}caddr_t MappedFile::fetch(off_t pos, size_t len){ if(fcb.address) { unlock(); UnmapViewOfFile(fcb.address); } fcb.address = MapViewOfFile(map, prot, 0, pos, len); fcb.len = (ccxx_size_t)len; fcb.pos = pos; if(!fcb.address) error(errMapFailed); return fcb.address;}void MappedFile::update(size_t offset, size_t len){}void MappedFile::update(caddr_t address, size_t len){}bool MappedFile::lock(void){ unlock(); if(VirtualLock(fcb.address, fcb.len)) fcb.locked = true; return fcb.locked;}void MappedFile::unlock(void){ if(!fcb.address) fcb.locked = false; if(!fcb.locked) return; VirtualUnlock(fcb.address, fcb.len); fcb.locked = false;}#else#ifdef HAVE_MLOCKMappedFile::MappedFile(const char *fname, Access mode) :RandomFile(fname){ fd = open(fname, (int)mode); if(fd < 0 && mode != accessReadOnly) fd = ::open(pathname, O_CREAT | O_RDWR | O_TRUNC, (int)attrPrivate); if(fd < 0) { error(errOpenFailed); return; } switch(mode) { case O_RDONLY: prot = PROT_READ; break; case O_WRONLY: prot = PROT_WRITE; break; default: prot = PROT_READ | PROT_WRITE; }}MappedFile::MappedFile(const char *fname, Access mode, size_t size) :RandomFile(fname){ fd = open(fname, (int)mode | O_CREAT, 0660); if(fd < 0) { error(errOpenFailed); return; } switch(mode) { case O_RDONLY: prot = PROT_READ; break; case O_WRONLY: prot = PROT_WRITE; break; default: prot = PROT_READ | PROT_WRITE; } enterMutex(); lseek(fd, size, SEEK_SET); fcb.address = (caddr_t)mmap(NULL, size, prot, MAP_SHARED, fd, 0); fcb.len = size; fcb.pos = 0; leaveMutex(); if((caddr_t)(fcb.address) == (caddr_t)(MAP_FAILED)) { close(fd); fd = -1; error(errMapFailed);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -