Blob Blame History Raw
// ------------------------------------------------------------------------------------------------

#include <windows.h>

#include <string>
#include <vector>

#include <IIEP_FileIn.H>
#include <IIEP_Hash.H>
#include <IIEP_String.H>

// ------------------------------------------------------------------------------------------------

struct MEM_FILE_IDX
{
  MEM_FILE_IDX(void)
  {
    m_dwID     = 0;
    m_dwLength = 0;
    m_pucData  = 0;
  }

  DWORD m_dwID;     // hash ID of filename
  DWORD m_dwLength; // file length
  PBYTE m_pucData;  // memory pointer
};

static std::vector <MEM_FILE_IDX> s_vecMemFile;

// ------------------------------------------------------------------------------------------------
// name: SearchMemFile()
// desc:
// ------------------------------------------------------------------------------------------------

static std::vector <MEM_FILE_IDX> :: iterator SearchMemFile(PCWSTR pcwsFileName)
{
  DWORD dwID = IIEP::HashFNV_1a(pcwsFileName);

  std::vector <MEM_FILE_IDX>::iterator it;

  for (it = s_vecMemFile.begin(); it < s_vecMemFile.end(); it ++)
  {
      if (it -> m_dwID == dwID) return it;
  }

  return s_vecMemFile.end();
}

// ------------------------------------------------------------------------------------------------

static std::vector <MEM_FILE_IDX> :: iterator SearchMemFile(const char *pcszFileName)
{
  WORD wzNameBuffer[0x1000];

  wzNameBuffer[0] = 0;

  IIEP::StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);

  return SearchMemFile(wzNameBuffer);
}

// ------------------------------------------------------------------------------------------------
// name: CreateMemoryFile()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::CreateMemoryFile(PVOID pMemory, DWORD dwLength, PCWSTR pcwsFileName)
{
  if (0 == pcwsFileName || 0 == *pcwsFileName) return false;

  RemoveMemoryFile(pcwsFileName);

  DWORD dwID = IIEP::HashFNV_1a(pcwsFileName);

  MEM_FILE_IDX soIDX;

  soIDX.m_dwID     = dwID;
  soIDX.m_dwLength = dwLength;
  soIDX.m_pucData  = (PBYTE) pMemory;

  s_vecMemFile.push_back(soIDX);

  return true;
}

// ------------------------------------------------------------------------------------------------

bool IIEP::CreateMemoryFile(PVOID pMemory, DWORD dwLength, const char *pcszFileName)
{
  WORD wzNameBuffer[0x1000];

  wzNameBuffer[0] = 0;

  StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);

  return CreateMemoryFile(pMemory, dwLength, wzNameBuffer);
}

// ------------------------------------------------------------------------------------------------
// name: RemoveMemoryFile()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::RemoveMemoryFile(PCWSTR pcwsFileName)
{
  if (0 == pcwsFileName || 0 == *pcwsFileName) return false;

  std::vector <MEM_FILE_IDX>::iterator it = SearchMemFile(pcwsFileName);

  if (it == s_vecMemFile.end()) return false;

  s_vecMemFile.erase(it);

  return true;
}

// ------------------------------------------------------------------------------------------------

bool IIEP::RemoveMemoryFile(const char *pcszFileName)
{
  WORD wzNameBuffer[0x1000];

  wzNameBuffer[0] = 0;

  StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);

  return RemoveMemoryFile(wzNameBuffer);
}

// ------------------------------------------------------------------------------------------------

void IIEP::RemoveMemoryFile(void)
{
  s_vecMemFile.clear();
}

// ------------------------------------------------------------------------------------------------
// name: CFileIn()
// desc:
// ------------------------------------------------------------------------------------------------

IIEP::CFileIn::CFileIn(void)
{
  m_pFile      = 0;
  m_pucMemData = 0;
  m_dwLength   = 0;
  m_dwReadPos  = 0;
}

// ------------------------------------------------------------------------------------------------
// name: ~CFileIn()
// desc:
// ------------------------------------------------------------------------------------------------

IIEP::CFileIn::~CFileIn(void)
{
  Close();
}

// ------------------------------------------------------------------------------------------------
// name: Open()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::CFileIn::Open(const char *pcszFileName)
{
  WORD wzNameBuffer[0x1000];

  wzNameBuffer[0] = 0;

  StringFromANSI(pcszFileName, wzNameBuffer, 0x1000);

  return Open(wzNameBuffer);
}

// ------------------------------------------------------------------------------------------------

bool IIEP::CFileIn::Open(const WORD *pcwsFileName)
{
  Close();

  if (0 == pcwsFileName || 0 == *pcwsFileName) return false;

  std::vector <MEM_FILE_IDX>::iterator it = SearchMemFile(pcwsFileName);

  if (it == s_vecMemFile.end()) // not found in memory
  {
    m_pFile = _wfopen(pcwsFileName, L"rb");

    if (m_pFile)
    {
      return true;  // found DOS file
    }

    return false;
  }

  if (s_vecMemFile.empty()) return false;

  m_pucMemData = it -> m_pucData;
  m_dwLength   = it -> m_dwLength;

  return true;
}

// ------------------------------------------------------------------------------------------------
// name: Close()
// desc:
// ------------------------------------------------------------------------------------------------

void IIEP::CFileIn::Close(void)
{
  if (m_pFile)
  {
    fclose(m_pFile);

    m_pFile = 0;
  }

  m_pucMemData = 0;
  m_dwLength   = 0;
  m_dwReadPos  = 0;
}

// ------------------------------------------------------------------------------------------------
// name: GetFileSize()
// desc:
// ------------------------------------------------------------------------------------------------

DWORD IIEP::CFileIn::GetFileSize(void) const
{
  if (m_pFile)
  {
    DWORD dwPostion = ftell(m_pFile);

    fseek(m_pFile, 0, SEEK_END);

    DWORD dwFileSize = ftell(m_pFile);

    fseek(m_pFile, dwPostion, SEEK_SET);

    return dwFileSize;
  }

  return m_dwLength;
}

// ------------------------------------------------------------------------------------------------
// name: GetReadPosition()
// desc:
// ------------------------------------------------------------------------------------------------

DWORD IIEP::CFileIn::GetReadPosition(void) const
{
  if (m_pFile)
  {
    return ftell(m_pFile);
  }

  return m_dwReadPos;
}

// ------------------------------------------------------------------------------------------------
// name: Seek()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::CFileIn::Seek(long nOffset, long nOrigin)
{
  if (m_pFile)
  {
    return (0 == fseek(m_pFile, nOffset, nOrigin));
  }

  if (m_pucMemData)
  {
    switch (nOrigin)
    {
    case SEEK_SET:
      if (nOffset < 0 || nOffset >= (long) m_dwLength) return false;
      m_dwReadPos = nOffset;
      return true;

    case SEEK_CUR:
      nOffset += m_dwReadPos;
      if (nOffset < 0 || nOffset >= (long) m_dwLength) return false;
      m_dwReadPos = nOffset;
      return true;

    case SEEK_END:
      ASSERT(nOffset <= 0);   // 这个必须是负数
      nOffset = m_dwLength - 1 + nOffset;
      if (nOffset < 0 || nOffset >= (long) m_dwLength) return false;
      m_dwReadPos = nOffset;
      return true;
    }
  }

  return false;
}

// ------------------------------------------------------------------------------------------------
// name: Read()
// desc:
// ------------------------------------------------------------------------------------------------

DWORD IIEP::CFileIn::Read(PVOID pDataBuffer, DWORD dwReadSize)
{
  if (m_pFile)
  {
    return (DWORD) fread(pDataBuffer, 1, dwReadSize, m_pFile);
  }

  if (m_pucMemData)
  {
    if (m_dwReadPos + dwReadSize > m_dwLength) dwReadSize = m_dwLength - m_dwReadPos;

    memcpy(pDataBuffer, m_pucMemData + m_dwReadPos, dwReadSize);

    m_dwReadPos += dwReadSize;

    return dwReadSize;
  }

  return 0;
}

// ------------------------------------------------------------------------------------------------
// name: ReadAnsiLine()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::CFileIn::ReadAnsiLine(std::string &strLine)
{
  BYTE ucChar = 0;

  strLine.clear();

  while (ReadB(ucChar))
  {
    if (0x0D == ucChar)
    {
    }
    else
    if (0x0A == ucChar)
    {
      return true;
    }
    else
    {
      strLine.push_back(ucChar);
    }
  }

  if (strLine.empty()) return false;

  return true;
}

// ------------------------------------------------------------------------------------------------
// name: ReadUnicodeLine()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::CFileIn::ReadUnicodeLine(std::wstring &wstrLine, bool bBigEndian)
{
  WORD wChar  = 0;

  wstrLine.clear();

  while (bBigEndian ? ReadInverseW(wChar) : ReadW(wChar))
  {
    if (0x000D == wChar)
    {
    }
    else
    if (0x000A == wChar)
    {
      return true;
    }
    else
    {
      wstrLine.push_back(wChar);
    }
  }

  if (wstrLine.empty()) return false;

  return true;
}

// ------------------------------------------------------------------------------------------------
// name: ReadAnsiString()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::CFileIn::ReadAnsiString(char *pszBuffer, DWORD dwBufferLength)
{
  DWORD dwIndex = 0;
  BYTE  ucChar;

  while (ReadB(ucChar))
  {
    if (dwIndex >= dwBufferLength) return true;

    pszBuffer[dwIndex ++] = ucChar;

    if (0 == ucChar)
    {
      return true;
    }
  }

  return false;
}

// ------------------------------------------------------------------------------------------------
// name: ReadUnicodeString()
// desc:
// ------------------------------------------------------------------------------------------------

bool IIEP::CFileIn::ReadUnicodeString(WORD *pwzBuffer, DWORD dwBufferLength)
{
  DWORD dwIndex = 0;
  WORD  wChar;

  ReadInverseW(wChar);

  if (wChar == 0xFFFE)  // Unicode
  {
    while (ReadW(wChar))
    {
      if (dwIndex >= dwBufferLength) return true;

      pwzBuffer[dwIndex ++] = wChar;

      if (0 == wChar)
      {
        return true;
      }
    }
  }
  else
  if (wChar == 0xFEFF)  // Unicode big endian
  {
    while (ReadInverseW(wChar))
    {
      if (dwIndex >= dwBufferLength) return true;

      pwzBuffer[dwIndex ++] = wChar;

      if (0 == wChar)
      {
        return true;
      }
    }
  }

  return false;
}

// ------------------------------------------------------------------------------------------------