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

📄 stdio.cpp

📁 evc 下的flash播放器源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 * Append "t" or "b" for text and binary mode.
 *  "tu" forces the text-mode to Unicode; "ts" to Ansi.
 */

BOOL CXFileStream::Open(const TCHAR* pszPathName, const char* pszMode)
{
	if (NULL != _h)
		Close();

	BOOL fTruncate = FALSE, fCreateIfNecessary = FALSE;

	// Crack the 'mode' arg
	_fReading = _fWriting = _fAppending = FALSE;
	switch (*pszMode++)
	{
	case 'r':
		_fReading = TRUE;
		fCreateIfNecessary = FALSE;
		break;
	case 'w':
		_fWriting = TRUE;
		fTruncate = TRUE;
		fCreateIfNecessary = TRUE;
		break;
	case 'a':
		_fWriting = TRUE;
		_fAppending = TRUE;
		fTruncate = FALSE;
		fCreateIfNecessary = TRUE;
		break;
	default:
		return FALSE;
	}

	BOOL fForceUnicode = FALSE;
	BOOL fForceANSI = FALSE;
	BOOL fForceCooked = FALSE;
	BOOL fForceRaw = FALSE;

	while (*pszMode)
	{
		switch (*pszMode++)
		{
		case '+':
			if (_fReading) // r
				_fWriting = TRUE;
			else if (_fWriting) // w, a
				_fReading = TRUE;
			break;
		case 't':
			if (fForceRaw)
				return FALSE;
			fForceCooked = TRUE;
			break;
		case 'u':
			if (fForceANSI || fForceRaw)
				return FALSE;
			fForceCooked = TRUE;
			fForceUnicode = TRUE;
			break;
		case 's':
			if (fForceUnicode || fForceRaw)
				return FALSE;
			fForceCooked = TRUE;
			fForceANSI = TRUE;
			break;
		case 'b':
			if (fForceCooked)
				return FALSE;
			fForceRaw = TRUE;
			break;
		default:
			return FALSE;
		}
	}

	// Default read/write modes.
	// Lets i/o to native textfiles (e.g. *.scm) succeed.
	// Pocket Office uses ANSI textfiles! Go figure. Win95 braindamage?

	_fCooked = fForceCooked || !fForceRaw; // if neither, default to cooked
	_fUseUnicode = !(fForceANSI || !fForceUnicode); // if neither, default to ansi

	DWORD dwAccess = 0L;
	if (_fReading)
		dwAccess |= GENERIC_READ;
	if (_fWriting)
		dwAccess |= GENERIC_WRITE;
	DWORD dwShare = FILE_SHARE_READ;
	if (!_fWriting)
		dwShare |= FILE_SHARE_WRITE;
	DWORD dwCreate = 0L;
	if (!fCreateIfNecessary)
		dwCreate = OPEN_EXISTING;
	else if (fTruncate)
		dwCreate = CREATE_ALWAYS;
	else
		dwCreate = OPEN_ALWAYS;

	HANDLE h = ::CreateFile(pszPathName, dwAccess, dwShare, NULL, dwCreate, FILE_ATTRIBUTE_NORMAL, NULL);
	if (INVALID_HANDLE_VALUE == h)
		return FALSE;
	_h = h;

	BOOL fFoundUnicodeBOM = FALSE;

	if (_fCooked && _fReading)
	{
		// For read-only files, the presence or absence of the Unicode start sequence
		// dictates Unicode-mode, rather than the mode flags.

		WCHAR wch;
		DWORD cbReadActual = 0L;

		if (::ReadFile(_h, &wch, sizeof(wch), &cbReadActual, NULL) 
			&& (sizeof(wch) == cbReadActual)
			&& (wch == 0xFEFF))
		{
			// Indeed, file is Unicode.
			_fUseUnicode = TRUE;
			fFoundUnicodeBOM = TRUE;
		}
		else
		{
			::SetFilePointer(_h, 0, NULL, FILE_BEGIN);
			if (!_fWriting)
				_fUseUnicode = FALSE;
		}
	}
	if (_fCooked && _fWriting && _fUseUnicode && !fFoundUnicodeBOM)
	{
		// New cooked-output Unicode files need the Unicode BOM.

		WCHAR wch = 0xFEFF;
		DWORD cbWritten = 0L;

		if (::WriteFile(_h, &wch, sizeof(wch), &cbWritten, NULL) 
			&& (sizeof(wch) == cbWritten))
		{
			// File successfully stamped as Unicode.
			fFoundUnicodeBOM = TRUE;
		}
		else
		{
			::CloseHandle(_h);
			_h = NULL;
			return FALSE;
		}
	}

	return TRUE;
}


FILE *fopen( const char *filename, const char *mode )
{
	for (int i = 0; i < MAXOPENFILES; ++i)
	{
		if (!RgStdioFiles[i].fActive)
		{
			TCHAR szPath[260+1];
			int cch = ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, filename, -1,
				szPath, sizeof(szPath)/sizeof(TCHAR));
			if (0 == cch)
				return NULL;

			CXFileStream* pstream = new CXFileStream;
			if (!pstream)
				return NULL;
			if (!pstream->Open(szPath, mode))
			{
				delete pstream;
				return NULL;
			}
			RgStdioFiles[i].pstream = pstream;
			RgStdioFiles[i].fActive = TRUE;
			return &RgStdioFiles[i];
		}
	}
	return NULL;
}


int fflush( FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	stream->pstream->Flush();
	return 0;
}


int fclose( FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	if (stdin == stream || stdout == stream)
		return -1;
	((CXFileStream*)(stream->pstream))->Close();
	delete stream->pstream;
	stream->pstream = NULL;
	stream->fActive = FALSE;
	return 0;
}


size_t fread( void *buffer, size_t size, size_t count, FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	unsigned cbActual;
	stream->pstream->Read((BYTE*)buffer, size*count, &cbActual);
	return (size_t)cbActual;
}


size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	unsigned cbActual;
	stream->pstream->Write((BYTE*)buffer, size*count, &cbActual);
	return (size_t)cbActual;
}


int getc( FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	unsigned char ch;
	unsigned cbActual = 0;
	stream->pstream->Read(&ch, 1, &cbActual);
	if (cbActual != 1)
		return EOF;
	return (int)ch;
}


int putc( int c, FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	unsigned char ch = (unsigned char)(unsigned int)c;
	unsigned cbActual = 0;
	stream->pstream->Write(&ch, 1, &cbActual);
	if (cbActual != 1)
		return EOF;
	return (int)ch;
}


int ungetc( int c, FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	if (EOF != c)
		stream->pstream->Pushback((unsigned char)(unsigned int)c);
	return c;
}


long ftell( FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	return (long)(stream->pstream->Tell());
}


int fseek( FILE *stream, long offset, int origin )
{
	if (IsInvalidFile(stream))
		return -1;
	if (!stream->pstream->Seek(offset, origin))
		return -1; // error
	return 0;
}


char *fgets( char *string, int n, FILE *stream )
{
	if (IsInvalidFile(stream))
		return NULL;
	char* pch = string;
	int cchRemaining = n-1;
	CXStdioStream *const pstream = stream->pstream;
	while (cchRemaining-- > 0)
	{
		unsigned char ch;
		unsigned cbActual = 0;
		pstream->Read(&ch, 1, &cbActual);
		if (cbActual != 1)
		{
			*pch = 0;
			return NULL;
		}

		*pch++ = ch;
		if ('\n' == ch)
			break;
	}
	*pch = 0;

	return string;
}


int fputs( const char *string, FILE *stream )
{
	if (IsInvalidFile(stream))
		return -1;
	const unsigned cbGiven = strlen(string);
	unsigned cbActual = 0;
	stream->pstream->Write((const BYTE*)string, cbGiven, &cbActual);
	return (cbGiven == cbActual ? 1 : EOF);
}


static int _output(char* buffer, const char* format, va_list argptr)
{
	int cchFormat = strlen(format);
	TCHAR szFormat[128];
	const int cchFormatMax = sizeof(szFormat)/sizeof(TCHAR)-1;

	if (cchFormat > cchFormatMax)
		return 0;
	int i = mbstowcs(szFormat, format, cchFormatMax);
	if (((size_t)-1) == ((size_t)i))
		return 0;
	if (cchFormatMax == i)
		szFormat[cchFormatMax] = 0;
	cchFormat = i;

	// Patch format string to accommodate CE's Unicode sensibilities
	// %s -> %S
	// %c -> %C
	BOOL fFmt; // set when within a format-specifier
	for (i = 0, fFmt = FALSE; i < cchFormatMax && szFormat[i] != 0; ++i)
	{
		switch (szFormat[i])
		{
		case L'%':
			fFmt = !fFmt;
			break;
		case L'0':
		case L'1':
		case L'2':
		case L'3':
		case L'4':
		case L'5':
		case L'6':
		case L'7':
		case L'8':
		case L'9':
		case L'.':
			// Precision/width specifier: part of format
			break;
		case L'c':
			if (fFmt)
			{
				szFormat[i] = L'C';
				fFmt = FALSE;
			}
			break;
		case L's':
			if (fFmt)
			{
				szFormat[i] = L'S';
				fFmt = FALSE;
			}
			break;
		default:
			if (fFmt)
				fFmt = FALSE;
			break;
		}
	}

	// Put a fence on either side of output buffer to detect overflow.
	//$ BUGBUG - no bounds checking on this small buffer.
	// I wish that the CE RTL had _vnswprintf

	volatile int nFence0 = 1;
	TCHAR szOut[256];
	volatile int nFence1 = 1;

	const int cchOutMax = sizeof(szOut)/sizeof(TCHAR)-1;
	// This version from the crt (as opposed to wvsprintf) handles %g
	i = vswprintf(szOut, szFormat, argptr);
	assert(nFence0 == 1 && nFence1 == 1);
	if (nFence0 != 1 || nFence1 != 1)
		return 0;
	if (0 == i)
		return 0;
	if (cchOutMax == i)
		szOut[cchOutMax] = 0;

	// Now convert to mbcs.
	//$ REVIEW - if xstdio had wide-char entry points,
	// the fprintf version could zap this here into WriteW,
	// saving a wcs-to-mbcs-to-wcs round trip

	i = wcstombs(buffer, szOut, cchOutMax);
	if (((size_t)-1) == ((size_t)i))
		return 0;
	if (cchOutMax == i)
		buffer[cchOutMax] = 0;
	return i;
}


int __cdecl sprintf( char *buffer, const char *format, ... )
{
	va_list arglist;
	va_start(arglist, format);
	int i = _output(buffer, format, arglist);
	va_end(arglist);
	return i;
}


int __cdecl fprintf( FILE *stream, const char *format, ... )
{
	if (IsInvalidFile(stream))
		return 0;

	char szTmp[256];
	va_list arglist;
	va_start(arglist, format);
	int i = _output(szTmp, format, arglist);
	va_end(arglist);
	//$ REVIEW - would be good to short-circuit the wcs-mbcs-wcs loop
	fputs(szTmp, stream);
	return i;
}


int __cdecl printf( const char *format, ... )
{
	if (IsInvalidFile(stdout))
		return 0;

	char szTmp[256];
	va_list arglist;
	va_start(arglist, format);
	int i = _output(szTmp, format, arglist);
	va_end(arglist);
	//$ REVIEW - would be good to short-circuit the wcs-mbcs-wcs loop
	fputs(szTmp, stdout);
	return i;
}


int StdioCharReady( FILE *stream )
{
	if (IsInvalidFile(stream))
		return 0;
	return (stream->pstream->CharReady());
}



#endif

⌨️ 快捷键说明

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