// StdioFileEx.cpp: implementation of the CStdioFileEx class.
//
// Version 1.1 23 August 2003. Incorporated fixes from Dennis Jeryd.
// Version 1.3 19 February 2005. Incorporated fixes from Howard J Oh and some of my own.
// Version 1.4 26 February 2005. Fixed stupid screw-up in code from 1.3.
// Version 1.5 18 November 2005. - Incorporated fixes from Andy Goodwin.
// - Allows code page to be specified for reading/writing
// - Properly calculates multibyte buffer size instead of
// assuming lstrlen(s).
// - Should handle UTF8 properly.
// Version 1.6 19 July 2007. - ReadString incorrectly removed \r or \n characters
// immediately preceding line breaks.
// Fixed tab problem in these comments! (Perry).
// Made GetMultiByteStringFromUnicodeString input string const
// (Perry).
// Avoided double conversion if code page not set.
// (Konrad Windszus).
// Fixed ASSERT in GetUnicodeStringFromMultiByteString
// (Konrad Windszus).
// Maximum line length restriction removed. Lines of any length
// can now be read thanks to C.B. Falconer's fggets (fgoodgets),
// ably assisted by Ana Sayfa and Dave Kondrad.
// Substantial code reorganisation and tidying.
// Use of strlen/lstrlen eliminated. Conversion functions always used
// to calculate required buffers.
// Serious, systematic tests are now included with the code.
// Options included to switch off BOM writing and alter the Unicode
// filler char.
// BOM is only stripped off if actually there.
// UTF-8 BOM is now read and written. UTF-8 conversion works.
//
// Copyright David Pritchard 2003-2007. davidpritchard@ctv.es
//
// You can use this class freely, but please keep my ego happy
// by leaving this comment in place.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "StdioFileEx.h"
#include "ggets.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const unsigned char UTF8_BOM[] = { unsigned char(0xEF), unsigned char(0xBB), unsigned char(0xBF) };
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
// Add this flag to write in Unicode. For the moment, out of range of all the Visual Studio 2005 flags
/*static*/ const UINT CStdioFileEx::modeWriteUnicode = 0x200000;
CStdioFileEx::CStdioFileEx():
m_bCheckFilePos(true),
m_bIsUnicodeText(false),
m_nFileCodePage(-1),
m_cUnicodeFillerChar(sDEFAULT_UNICODE_FILLER_CHAR),
m_bWriteBOM(true), // By default, write the BOM
CStdioFile()
{
}
CStdioFileEx::CStdioFileEx(LPCTSTR lpszFileName,UINT nOpenFlags):
m_bCheckFilePos(true),
m_bIsUnicodeText(false),
m_nFileCodePage(-1),
m_cUnicodeFillerChar(sDEFAULT_UNICODE_FILLER_CHAR),
m_bWriteBOM(true), // By default, write the BOM
CStdioFile(lpszFileName, nOpenFlags)
{
}
// Set the code page for reading/writing
void CStdioFileEx::SetCodePage(IN const UINT nCodePage)
{
m_nFileCodePage = (int)nCodePage;
}
// Set the Unicode filler char - the char written when no conversion is possible for the target multibyte char set
void CStdioFileEx::SetFillerChar(IN const char cFiller)
{
m_cUnicodeFillerChar = cFiller;
}
// Determines whether the byte-order-mark is written at the start of a Unicode file
void CStdioFileEx::SetWriteBOM(IN const bool bWrite)
{
m_bWriteBOM = bWrite;
}
// Determines whether we try to interpret this file as Unicode
//void CStdioFileEx::SetUnicode(IN const bool bIsUnicode)
//{
// m_bIsUnicodeText = bIsUnicode;
//}
BOOL CStdioFileEx::Open(LPCTSTR lpszFileName,UINT nOpenFlags,CFileException* pError /*=NULL*/)
{
// Process any Unicode stuff. This no longer checks for the Unicode BOM. We do this on
// opening for efficiency.
ProcessFlags(nOpenFlags);
BOOL bOK = CStdioFile::Open(lpszFileName, nOpenFlags, pError);
if (bOK)
{
// If we are reading, see if it has a BOM. I tried making the Unicode-ness independent of the BOM (i.e. allowed the file to
// be identified as Unicode by the caller, with the BOM just being used as a check, or thrown away).
// But for some reason it wouldn't work. I'll no doubt try again at some point.
// if (!(nOpenFlags & CFile::modeCreate) && (nOpenFlags & CFile::modeRead || nOpenFlags & CFile::modeReadWrite))
if (!(nOpenFlags & CFile::modeCreate) && !(nOpenFlags & CFile::modeWrite ))
{
wchar_t cBOMTest;
wchar_t cBOM = nUNICODE_BOM;
Read(&cBOMTest, sizeof(wchar_t));
// If the first characters are NOT a BOM, reset to start of file
m_bIsUnicodeText = (wmemcmp(&cBOMTest, &cBOM, 1) == 0);
// Reset to start of file
SeekToBegin();
m_bCheckFilePos = true;
}
}
return bOK;
}
BOOL CStdioFileEx::ReadString(CString& rString)
{
ASSERT(m_pStream != NULL);
BOOL bReadData = FALSE;
LPTSTR lpsz;
int nLen = 0;
// If at position 0, discard byte-order mark before reading. To optimise reading, we only
// check this when the m_bCheckFilePos is set (this avoids a call to ftell every time we
// read a line)
if (m_bCheckFilePos && GetPosition() == 0)
{
// m_bReadBOM = false;
// Look for Unicode BOM
if (m_bIsUnicodeText)
{
wchar_t cBOMDummy;
// wchar_t cBOM = nUNICODE_BOM;
Read(&cBOMDummy, sizeof(wchar_t));
// // If the first characters are NOT a BOM, reset to start of file
// if (wmemcmp(&cBOMTest, &cBOM, 1) != 0)
// {
// SeekToBegin();
// ASSERT(GetPosition() == 0);
// }
// else
// {
// // Set read BOM flag
// m_bReadBOM = true;
// }
}
// Look for UTF8 BOM
else if (CP_UTF8 == m_nFileCodePage)
{
BYTE arrUTF8BOMTest[sizeof(UTF8_BOM)];
Read(arrUTF8BOMTest, sizeof(arrUTF8BOMTest));
// // If the first characters are NOT a BOM, reset to start of file
// if (memcmp(&arrUTF8BOMTest, UTF8_BOM, sizeof(arrUTF8BOMTest)) != 0)
// {
// SeekToBegin();
// ASSERT(GetPosition() == 0);
// }
// else
// {
// // Set read BOM flag
// m_bReadBOM = true;
// }
}
}
// Read Unicode line or multibyte line (implementations
// differ depending on the compilation)
if (m_bIsUnicodeText)
{
bReadData = ReadUnicodeLine(rString);
}
else
{
bReadData = ReadMultiByteLine(rString);
}
// Then remove end-of-line character as necessary.
// fggets keeps the end-of-line confusion level at maximum by stripping the \n
// from the end of lines, but leaving the \r. Grrrr.
// Remember that you could quite legitimately have a \r or \n at the end of
// your line before the actual \r\n line break.
if (bReadData)
{
// Copied from FileTxt.cpp but adapted to use of fgets
nLen = rString.GetLength();
lpsz = rString.GetBuffer(0);
// Strip \r from the end
if (nLen != 0 && (lpsz[nLen-1] == _T('\r') ))
{
rString.GetBufferSetLength(nLen-1);
}
rString.ReleaseBuffer();
// Now we've moved on in the file, don't bother to check any more unless the
// file pointer is moved
m_bCheckFilePos = false;
}
return bReadData;
}
/*virtual*/ LPTSTR CStdioFileEx::ReadString(LPTSTR lpsz,UINT nMax)
{
// Ca
支持UNICODE读写的MFC扩展类 CStdioFileEx
5星 · 超过95%的资源 需积分: 49 148 浏览量
2009-04-02
15:29:45
上传
评论 1
收藏 18KB ZIP 举报
cxonline
- 粉丝: 0
- 资源: 2
最新资源
- 航天器遥测数据故障检测系统python源码+文档说明+数据库(课程设计)
- 北京航空航天大学操作系统课设+ppt+实验报告
- 基于Vue+Echarts实现风力发电机中传感器的数据展示监控可视化系统+源代码+文档说明(高分课程设计)
- 基于单片机的风力发电机转速控制源码
- 基于C++实现的风力发电气动平衡监测系统+源代码+测量数据(高分课程设计)
- 毕业设计- 基于STM32F103C8T6 单片机,物联网技术的太阳能发电装置+源代码+文档说明+架构图+界面截图
- 基于 LSTM(长短期记忆)(即改进的循环神经网络)预测风力发电厂中风力涡轮机产生的功率+源代码+文档说明
- 基于stm32f103+空心杯电机+oled按键+运动算法
- 《CKA/CKAD应试指南/从docker到kubernetes 完全攻略》学习笔记 第1章docker基础(1.1-1.4)
- 基于python实现的水下压缩空气储能互补系统建模仿真与经济效益分析+源代码+论文
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈