⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//  // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however    // invalidate any other reasons why the executable file might be covered by// the GNU General Public License.    //// This exception applies only to the code released under the name GNU// Common C++.  If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//// needed for GNU/LINUX glibc otherwise pread/pwrite wont work#ifdef	__linux__#ifndef	_XOPEN_SOURCE#define	_XOPEN_SOURCE 500#endif/* * on old glibc's, this has to be * defined explicitly */#ifndef _XOPEN_SOURCE_EXTENDED#define _XOPEN_SOURCE_EXTENDED#endif#endif#include <cc++/config.h>#include <cc++/export.h>#include <cc++/exception.h>#include <cc++/thread.h>#include <cc++/file.h>#include <cc++/process.h>#include "private.h"#ifdef	__BORLANDC__#include <stdio.h>#else#include <cstdio>#endif#include <sys/stat.h>#include <cerrno>#ifndef WIN32#ifdef	HAVE_SYS_PARAM_H#include <sys/param.h>#endif#ifdef	HAVE_SYS_FILE_H#include <sys/file.h>#endif#ifdef  HAVE_SYS_LOCKF_H#include <sys/lockf.h>#endif#ifdef	COMMON_AIX_FIXES#undef	LOCK_EX#undef	LOCK_SH#endif#ifdef  MACOSX#define MISSING_LOCKF   #endif#ifndef	F_LOCK#define	MISSING_LOCKFenum{	F_ULOCK = 1,	F_LOCK,	F_TLOCK,	F_TEST};#endif#endif // ndef WIN32		#if defined(_OSF_SOURCE) && defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE > 1#undef	LOCK_EX#undef	LOCK_SH#endif#if 0/* * not used anymore ? (hen) */static const char *clearfile(const char *pathname){	remove(pathname);	return pathname;}static const char *clearfifo(const char *pathname, int mode){	remove(pathname);	mkfifo(pathname, mode);	return pathname;}#endif#ifdef	CCXX_NAMESPACESnamespace ost {#endifRandomFile::RandomFile(const char *name) : Mutex(name) {#ifdef WIN32	fd = INVALID_HANDLE_VALUE;	// immediate is not defined on Win32 #else	fd = -1;	flags.immediate = false;#endif	flags.thrown = flags.initial = flags.temp = false;	flags.count = 0;	pathname = NULL;}RandomFile::RandomFile(const RandomFile &rf) : Mutex() {	// first, `dup'-licate the file descriptor/handle#ifdef WIN32	HANDLE pidHandle = GetCurrentProcess();	HANDLE dupHandle;	if(rf.fd != INVALID_HANDLE_VALUE)	{		if(!DuplicateHandle(pidHandle, rf.fd, pidHandle, &dupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS))			fd = INVALID_HANDLE_VALUE;		else			fd = dupHandle;	}	else		fd = INVALID_HANDLE_VALUE;#else	if(rf.fd > -1)		fd = dup(rf.fd);	else		fd = -1;#endif		flags = rf.flags;	flags.count = 0;	if(rf.pathname)		pathname = newString(rf.pathname);			else		pathname = NULL;}RandomFile::~RandomFile(){	final();}File::Error RandomFile::restart(void){	return errOpenFailed;}File::Attr RandomFile::initialize(void){	return attrPublic;}void RandomFile::final(void){#ifdef WIN32	if(fd != INVALID_HANDLE_VALUE)	{		CloseHandle(fd);		if(flags.temp && pathname)			DeleteFile(pathname);	}#else	if(fd > -1)	{		close(fd);		if(flags.temp && pathname)			remove(pathname);	}#endif	if(pathname)	{		delString(pathname);		pathname = NULL;	}#ifdef WIN32	fd = INVALID_HANDLE_VALUE;#else	fd = -1;#endif	flags.count = 0;	flags.initial = false;}RandomFile::Error RandomFile::error(Error id, char *str){	errstr = str;	errid = id;	if(!flags.thrown)	{		flags.thrown = true;#ifdef	CCXX_EXCEPTIONS		if(Thread::getException() == Thread::throwObject)			throw(this);#ifdef	COMMON_STD_EXCEPTION		else if(Thread::getException() == Thread::throwException)		{			if(!str)				str = "";			throw FileException(str);		}#endif#endif	}	return id;}bool RandomFile::initial(void){	bool init;#ifdef WIN32	if(fd == INVALID_HANDLE_VALUE)#else	if(fd < 0)#endif				return false;	enterMutex();	init = flags.initial;	flags.initial = false;	if(!init)	{		leaveMutex();		return false;	}#ifdef WIN32	Attr access = initialize();	if(access == attrInvalid)	{		CloseHandle(fd);		if(pathname)			DeleteFile(pathname);		fd = INVALID_HANDLE_VALUE;		leaveMutex();		error(errInitFailed);		return false;	}#else	int mode = (int)initialize();	if(!mode)	{		close(fd);		fd = -1;		if(pathname)			remove(pathname);		leaveMutex();		error(errInitFailed);		return false;	}	fchmod(fd, mode);#endif		leaveMutex();	return init;}#ifndef WIN32RandomFile::Error RandomFile::setCompletion(Complete mode){	long flag = fcntl(fd, F_GETFL);	if(fd < 0)		return errNotOpened;	flags.immediate = false;#ifdef O_SYNC	flag &= ~(O_SYNC | O_NDELAY);#else	flag &= ~O_NDELAY;#endif	switch(mode)	{	case completionImmediate:#ifdef O_SYNC		flag |= O_SYNC;#endif		flags.immediate = true;		break;	case completionDelayed:		flag |= O_NDELAY;	//completionDeferred: ? (hen)	case completionDeferred:		break;	}	fcntl(fd, F_SETFL, flag);	return errSuccess;}#endifoff_t RandomFile::getCapacity(void){	off_t eof, pos = 0;#ifdef WIN32	if(!fd)#else	if(fd < 0)#endif		return 0;	enterMutex();#ifdef WIN32	pos = SetFilePointer(fd, 0l, NULL, FILE_CURRENT);	eof = SetFilePointer(fd, 0l, NULL, FILE_END);	SetFilePointer(fd, pos, NULL, FILE_BEGIN);#else	lseek(fd, pos, SEEK_SET);	pos = lseek(fd, 0l, SEEK_CUR);	eof = lseek(fd, 0l, SEEK_END);#endif	leaveMutex();	return eof;}bool RandomFile::operator!(void){#ifdef WIN32	return fd == INVALID_HANDLE_VALUE;#else	if(fd < 0)		return true;	return false;#endif}ThreadFile::ThreadFile(const char *path) : RandomFile(path){	first = NULL;	open(path);}ThreadFile::~ThreadFile(){	final();	fcb_t *next;	while(first)	{		next = first->next;		delete first;		first = next;	}}ThreadFile::Error ThreadFile::restart(void){	return open(pathname);}ThreadFile::Error ThreadFile::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, 0, 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, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);	}	if(fd == INVALID_HANDLE_VALUE)		return errOpenFailed;#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_EX	if(flock(fd, LOCK_EX | LOCK_NB))	{		close(fd);		fd = -1;		return error(errOpenInUse);	}#endif#endif // WIN32	return errSuccess;}ThreadFile::fcb_t *ThreadFile::getFCB(void){	fcb_t *fcb = (fcb_t *)state.getKey();	if(!fcb)	{		fcb = new fcb_t;		fcb->next = first;		first = fcb;		fcb->address = NULL;		fcb->len = 0;		fcb->pos = 0;		state.setKey(fcb);	}	return fcb;}ThreadFile::Error ThreadFile::fetch(caddr_t address, ccxx_size_t len, off_t pos){	fcb_t *fcb = getFCB();#ifdef WIN32	Thread::Cancel save;	if(fd == INVALID_HANDLE_VALUE)#else	if(fd < 0)#endif		return errNotOpened;	if(address)		fcb->address = address;	if(len)		fcb->len = len;	if(pos != -1)		fcb->pos = pos;#ifdef WIN32	enterMutex();	save = Thread::enterCancel();	SetFilePointer(fd, fcb->pos, NULL, FILE_BEGIN);	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#ifdef	HAVE_PREAD_PWRITE	int io = ::pread(fd, fcb->address, fcb->len, fcb->pos);#else	enterMutex();	lseek(fd, fcb->pos, SEEK_SET);	int io = ::read(fd, fcb->address, fcb->len);	leaveMutex();#endif	if((size_t) io == fcb->len)		return errSuccess;	if(io > -1)		return errReadIncomplete;	switch(errno)	{	case EINTR:		return errReadInterrupted;	default:		return errReadFailure;	}#endif // WIN32}ThreadFile::Error ThreadFile::update(caddr_t address, ccxx_size_t len, off_t pos){	fcb_t *fcb = getFCB();#ifdef WIN32	if(fd == INVALID_HANDLE_VALUE)#else	if(fd < 0)#endif		return errNotOpened;	if(address)		fcb->address = address;	if(len)		fcb->len = len;	if(pos != -1)		fcb->pos = pos;#ifdef WIN32	enterMutex();	Thread::Cancel save = Thread::enterCancel();	SetFilePointer(fd, fcb->pos, NULL, FILE_BEGIN);	DWORD count;	if(!WriteFile(fd, fcb->address, fcb->len, &count, NULL))	{		Thread::exitCancel(save);		leaveMutex();		return errWriteFailure;	}	Thread::exitCancel(save);	leaveMutex();	if(count < fcb->len)		return errWriteIncomplete;	return errSuccess;#else#ifdef	HAVE_PREAD_PWRITE	int io = ::pwrite(fd, fcb->address, fcb->len, fcb->pos);#else	enterMutex();	lseek(fd, fcb->pos, SEEK_SET);	int io = ::write(fd, fcb->address, fcb->len);	leaveMutex();#endif	if((size_t) io == fcb->len)		return errSuccess;	if(io > -1)		return errWriteIncomplete;	switch(errno)	{	case EINTR:		return errWriteInterrupted;	default:		return errWriteFailure;	}#endif //WIN32}ThreadFile::Error ThreadFile::append(caddr_t address, ccxx_size_t len){	fcb_t *fcb = getFCB();#ifdef WIN32	if(fd == INVALID_HANDLE_VALUE)#else	if(fd < 0)#endif		return errNotOpened;	if(address)		fcb->address = address;	if(len)		fcb->len = len;	enterMutex();#ifdef WIN32	Thread::Cancel save = Thread::enterCancel();	fcb->pos = SetFilePointer(fd, 0l, NULL, FILE_END);	DWORD count;	if(!WriteFile(fd, fcb->address, fcb->len, &count, NULL))	{		Thread::exitCancel(save);		leaveMutex();		return errWriteFailure;	}	Thread::exitCancel(save);	leaveMutex();	if(count < fcb->len)		return errWriteIncomplete;	return errSuccess;#else	fcb->pos = lseek(fd, 0l, SEEK_END);	int io = ::write(fd, fcb->address, 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}off_t ThreadFile::getPosition(void){	fcb_t *fcb = getFCB();	return fcb->pos;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -