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

📄 resourcefile.cpp

📁 读取XML信息
💻 CPP
字号:
// ResourceFile.cpp  Version 1.0 - article available at www.codeproject.com
//
// Author:  Hans Dietrich
//          hdietrich@gmail.com
//
// History
//     Version 1.0 - 2007 July 4
//     - Initial public release
//
// License:
//     This software is released into the public domain.  You are free to use
//     it in any way you like, except that you may not sell this source code.
//
//     This software is provided "as is" with no expressed or implied warranty.
//     I accept no liability for any damage or loss of business that this 
//     software may cause.
//
// Public APIs:
//           NAME                              DESCRIPTION
//   ---------------------  ----------------------------------------------------
//   Close()                Close a file resource
//   DetachByteBuffer()     Return pointer to byte buffer and set flag so buffer
//                          will not be deleted when resource is closed
//   DuplicateByteBuffer()  Duplicate the buffer associated with the binary file 
//                          resource
//   GetByteBuffer()        Get pointer to binary file resource buffer
//   GetLength()            Get length of file resource
//   GetPosition()          Get current file position of file resource
//   IsAtEOF()              Check if file pointer is at end of file
//   IsOpen()               Check if file resource is open
//   Open()                 Open a file resource
//   Read()                 Read bytes from the binary file resource
//   Seek()                 Move pointer to specified position in resource buffer
//   SeekToBegin()          Position pointer to beginning of resource buffer
//   SeekToEnd()            Position pointer to end of resource buffer
//   SetByteBuffer()        Set a new buffer for the binary file resource
//
///////////////////////////////////////////////////////////////////////////////

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <malloc.h>
#include <crtdbg.h>
#include "ResourceFile.h"

#ifndef __noop
#if _MSC_VER < 1300
#define __noop ((void)0)
#endif
#endif

#undef TRACE
#define TRACE __noop

// if you want to see the TRACE output, 
// uncomment this line:
//#include "XTrace.h"

#pragma warning(disable : 4127)	// conditional expression is constant (_ASSERTE)
#pragma warning(disable : 4996)	// disable bogus deprecation warning

///////////////////////////////////////////////////////////////////////////////
// ctor
CResourceFile::CResourceFile()
  : m_pBytes(NULL),
	m_bText(FALSE),
	m_nBufLen(0),
	m_nPosition(0),
	m_bIsOpen(FALSE),
	m_bDoNotDeleteBuffer(FALSE)
{
	TRACE(_T("in CResourceFile::CResourceFile\n"));
}

///////////////////////////////////////////////////////////////////////////////
// copy ctor
CResourceFile::CResourceFile(const CResourceFile& rf)
{
	TRACE(_T("in CResourceFile::CResourceFile(const CResourceFile& rf)\n"));

	if (rf.m_bDoNotDeleteBuffer)
	{
		// buffer is allocated externally or has been detached
		m_pBytes = rf.m_pBytes;
	}
	else
	{
		m_pBytes = new BYTE [rf.m_nBufLen + 2];
		memset(m_pBytes, 0, rf.m_nBufLen+2);
		memcpy(m_pBytes, rf.m_pBytes, rf.m_nBufLen);
	}

	m_nBufLen = rf.m_nBufLen;
	m_nPosition = 0;
	m_bIsOpen = rf.m_bIsOpen;
	m_bText = rf.m_bText;
	m_bDoNotDeleteBuffer = rf.m_bDoNotDeleteBuffer;
}

///////////////////////////////////////////////////////////////////////////////
// assignment operator
CResourceFile& CResourceFile::operator=(const CResourceFile& rf)
{
	TRACE(_T("in CResourceFile::operator=\n"));

	if (m_pBytes != rf.m_pBytes)		// check for a = a
	{
		if (m_pBytes && !m_bDoNotDeleteBuffer)
			delete [] m_pBytes;

		if (rf.m_bDoNotDeleteBuffer)
		{
			// buffer is allocated externally or has been detached
			m_pBytes = rf.m_pBytes;
		}
		else
		{
			m_pBytes = new BYTE [rf.m_nBufLen + 2];
			memset(m_pBytes, 0, rf.m_nBufLen+2);
			memcpy(m_pBytes, rf.m_pBytes, rf.m_nBufLen);
		}

		m_nBufLen = rf.m_nBufLen;
		m_nPosition = 0;
		m_bIsOpen = rf.m_bIsOpen;
		m_bText = rf.m_bText;
		m_bDoNotDeleteBuffer = rf.m_bDoNotDeleteBuffer;
	}

	return *this;
}

///////////////////////////////////////////////////////////////////////////////
// dtor
CResourceFile::~CResourceFile()
{
	Close();
}

///////////////////////////////////////////////////////////////////////////////
//
// Open()
//
// Purpose:     Open a file resource
//
// Parameters:  hInstance      - instance handle for the resource.  A value of 
//                               NULL specifies the exe (default).
//              lpszResId      - resource name or id (passed via MAKEINTRESOURCE)
//              lpszResType    - resource type string to look for
//
// Returns:     BOOL           - returns TRUE if resource opened ok, otherwise FALSE
//
BOOL CResourceFile::Open(HINSTANCE hInstance, 
						 LPCTSTR lpszResId, 
						 LPCTSTR lpszResType)
{
	BOOL rc = FALSE;

	Close();

	_ASSERTE(lpszResId);
	_ASSERTE(lpszResType);

	if (lpszResId && lpszResType)
	{
		TCHAR *pszRes = NULL;

		// is this a resource name string or an id?
		if (HIWORD(lpszResId) == 0)
		{
			// id
			pszRes = MAKEINTRESOURCE(LOWORD((UINT)(UINT_PTR)lpszResId));
		}
		else
		{
			// string
			pszRes = (TCHAR *)lpszResId;
			TRACE(_T("pszRes=%s\n"), pszRes);
		}

		HRSRC hrsrc = FindResource(hInstance, pszRes, lpszResType);
		_ASSERTE(hrsrc);

		if (hrsrc)
		{
			DWORD dwSize = SizeofResource(hInstance, hrsrc);	// in bytes
			TRACE(_T("dwSize=%d\n"), dwSize);

			HGLOBAL hglob = LoadResource(hInstance, hrsrc);
			_ASSERTE(hglob);

			if (hglob)
			{
				LPVOID lplock = LockResource(hglob);
				_ASSERTE(lplock);

				if (lplock)
				{
					// save resource as byte buffer

					m_pBytes = new BYTE [dwSize+16];
					memset(m_pBytes, 0, dwSize+16);
					m_nBufLen = (int) dwSize;
					memcpy(m_pBytes, lplock, m_nBufLen);

					m_nPosition = 0;
					m_bIsOpen = TRUE;
					m_bDoNotDeleteBuffer = FALSE;	// ok to delete the buffer
					rc = TRUE;
				}
			}
		}
	}

	return rc;
}

///////////////////////////////////////////////////////////////////////////////
//
// Close()
//
// Purpose:     Close a file resource, free memory if necessary
//
// Parameters:  None
//
// Returns:     None
//
void CResourceFile::Close()
{
	TRACE(_T("in CResourceFile::Close\n"));
	m_bIsOpen = FALSE;
	if (m_pBytes && !m_bDoNotDeleteBuffer)
		delete [] m_pBytes;
	m_pBytes = NULL;
	m_nBufLen = 0;
	m_nPosition = 0;
}

///////////////////////////////////////////////////////////////////////////////
//
// DetachByteBuffer()
//
// Purpose:     Returns pointer to byte buffer and sets flag so that the buffer
//              will not be deleted when resource is closed;  caller must 
//              delete buffer with delete.
//
// Parameters:  None
//
// Returns:     BYTE * - returns pointer to buffer, or NULL if not open or text
//
BYTE * CResourceFile::DetachByteBuffer()
{
	BYTE *p = NULL;

	if (m_bIsOpen && !m_bText)
	{
		m_bDoNotDeleteBuffer = TRUE; 
		p = m_pBytes;
	}
	
	return p;
}

///////////////////////////////////////////////////////////////////////////////
//
// DuplicateByteBuffer()
//
// Purpose:     Duplicate the buffer associated with the binary file resource
//
// Parameters:  None
//
// Returns:     BYTE * - returns pointer to duplicated buffer, or NULL
//
// Notes:       The buffer is duplicated by calling the function malloc().
//              It must be freed by the caller by using the free() function.
//
BYTE * CResourceFile::DuplicateByteBuffer()
{
	BYTE *dup = NULL;

	if (IsOpen() && !m_bText)
	{
		dup = (BYTE *) malloc(m_nBufLen+2);
		memset(dup, 0, m_nBufLen+2);
		memcpy(dup, m_pBytes, m_nBufLen);
	}

	return dup;
}

///////////////////////////////////////////////////////////////////////////////
//
// SetByteBuffer()
//
// Purpose:     Set a new buffer for the binary file resource.  This may be 
//              useful if the buffer is obtained from some external source,
//              and you wish to treat it like an in-memory file.
//
// Parameters:  buf - pointer to new buffer
//              len - buffer length in bytes
//
// Returns:     None
//
void CResourceFile::SetByteBuffer(BYTE * buf, DWORD len)
{
	_ASSERTE(buf);
	_ASSERTE(len != 0);
	_ASSERTE(m_pBytes == NULL);

	if (buf && (len > 0))
	{
		m_pBytes = buf;
		m_nBufLen = len;
		m_bText = FALSE;
		m_bDoNotDeleteBuffer = TRUE;	// do not delete this buffer
		m_bIsOpen = TRUE;
	}
	else
	{
		TRACE(_T("ERROR - SetByteBuffer: bad parameters\n"));
	}
}

///////////////////////////////////////////////////////////////////////////////
//
// Read()
//
// Purpose:     Read bytes from the binary file resource
//
// Parameters:  buf     - pointer to buffer that receives bytes
//              nBufLen - buffer length in bytes
//
// Returns:     int     - number of bytes returned
//
// Notes:       To determine how large the buffer should be, call Read() first 
//              with a NULL buf parameter - this will return the size of the 
//              required buffer.
//
int CResourceFile::Read(BYTE *buf, int nBufLen)
{
	int nOldPosition = m_nPosition;
	int nIndex = 0;
	if (buf)
		*buf = _T('\0');

	if (m_bIsOpen && m_pBytes && !m_bText)
	{
		while (!IsAtEOF())
		{
			BYTE b = m_pBytes[m_nPosition++];

			if (buf && (nIndex < nBufLen))
				buf[nIndex] = b;

			nIndex++;
		}
	}

	// if we were just getting buffer size, restore position
	if (!buf)
		m_nPosition = nOldPosition;

	return nIndex;
}

///////////////////////////////////////////////////////////////////////////////
//
// SeekToBegin()
//
// Purpose:     Position pointer to beginning of resource file buffer
//
// Parameters:  None
//
// Returns:     int - new file position (zero based), or -1
//
int CResourceFile::SeekToBegin()
{
	return Seek(0, SEEK_SET);
}

///////////////////////////////////////////////////////////////////////////////
//
// SeekToEnd()
//
// Purpose:     Position pointer to end of resource file buffer
//
// Parameters:  None
//
// Returns:     int - new file position (zero based), or -1
//
int CResourceFile::SeekToEnd()
{
	return Seek(0, SEEK_END);
}

///////////////////////////////////////////////////////////////////////////////
//
// Seek()
//
// Purpose:     Move pointer to specified position in resource file buffer
//
// Parameters:  offset - number of TCHARs/bytes from origin (can be negative)
//              origin - initial position; must be one of:
//                          SEEK_SET = beginning of file
//                          SEEK_CUR = current position of file pointer
//                          SEEK_END = end of file
//
// Returns:     int - new file position (zero based), or -1
//
int CResourceFile::Seek(int offset, int origin)
{
	int rc = -1;

	if (IsOpen())
	{
		switch (origin)
		{
			default:
			case SEEK_SET:		// beginning of file
				if (offset <= m_nBufLen)
				{
					m_nPosition = offset;
					rc = m_nPosition;
				}
				break;

			case SEEK_CUR:		// current position of file pointer
				if ((m_nPosition + offset) <= m_nBufLen)
				{
					m_nPosition += offset;
					rc = m_nPosition;
				}
				break;

			case SEEK_END:		// end of file
				m_nPosition = m_nBufLen;
				rc = m_nPosition;
				break;
		}
	}

	return rc;
}

⌨️ 快捷键说明

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