Beispiel #1
0
//-------------------------------------------------
//功能:带解压地读取包文件到缓冲区
//参数:pBuffer --> 缓冲区指针
//		uExtractSize  --> 数据(期望)解压后的大小,pBuffer缓冲区的大小不小于此数
//		lCompressType --> 直接从包中度取得原始(/压缩)大小
//		uOffset  --> 从包中的此偏移位置开始读取
//		uSize    --> 从包中直接读取得(压缩)数据的大小
//返回:成功与否
//-------------------------------------------------
int	XPackFile::ExtractRead(void* pBuffer, unsigned int uExtractSize,
						long lCompressType, unsigned int uOffset, unsigned int uSize)
{
	assert(pBuffer);
	int bResult = false;
	if (lCompressType == XPACK_METHOD_NONE)
	{
		if (uExtractSize == uSize)
			bResult = DirectRead(pBuffer, uOffset, uSize);
	}
	else
	{
		void*	pReadBuffer = malloc(uSize);
		if (pReadBuffer)
		{
		    if (lCompressType == XPACK_METHOD_UCL && DirectRead(pReadBuffer, uOffset, uSize))
			{
				unsigned int uDestLength = uExtractSize;
				ucl_nrv2b_decompress_safe_8((unsigned char*)pReadBuffer, uSize, (unsigned char*)pBuffer, &uDestLength, NULL);
				bResult =  (uDestLength == uExtractSize);
			}
			free (pReadBuffer);
		}
	}
	return bResult;
}
Beispiel #2
0
int File::Read(void *Data,int Size)
{
  Int64 FilePos;
  if (IgnoreReadErrors)
    FilePos=Tell();
  int ReadSize;
  while (true)
  {
    ReadSize=DirectRead(Data,Size);
    if (ReadSize==-1)
    {
      ErrorType=FILE_READERROR;
      if (AllowExceptions)
        if (IgnoreReadErrors)
        {
          ReadSize=0;
          for (int I=0;I<Size;I+=512)
          {
            Seek(FilePos+I,SEEK_SET);
            int SizeToRead=Min(Size-I,512);
            int ReadCode=DirectRead(Data,SizeToRead);
            ReadSize+=(ReadCode==-1) ? 512:ReadCode;
          }
        }
        else
        {
          if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName))
            continue;
          ErrHandler.ReadError(FileName);
        }
    }
    break;
  }
  return(ReadSize);
}
Beispiel #3
0
//-------------------------------------------------
//功能:把子文件数据添加到cache
//参数:pBuffer --> 存有子文件数据的缓冲区
//		nElemIndex --> 子文件在包中的索引
//返回:添加到cache的索引位置
//-------------------------------------------------
int XPackFile::AddElemFileToCache(void* pBuffer, int nElemIndex)
{
	assert(pBuffer && nElemIndex >= 0 && (unsigned long)nElemIndex < m_uElemFileCount);
	int nCacheIndex;
	if (ms_nNumElemFileCache < MAX_XPACKFILE_CACHE)
	{	//找到一个空位置
		nCacheIndex = ms_nNumElemFileCache++;
	}
	else
	{	//释放一个旧的cache节点
		nCacheIndex = 0;
		if (ms_ElemFileCache[0].uRefFlag)
			ms_ElemFileCache[0].uRefFlag --;
		for (int i = 1; i < MAX_XPACKFILE_CACHE; i++)
		{
			if (ms_ElemFileCache[i].uRefFlag)
				ms_ElemFileCache[i].uRefFlag --;
			if (ms_ElemFileCache[i].uRefFlag < ms_ElemFileCache[nCacheIndex].uRefFlag)
				nCacheIndex = i;

		}
		FreeElemCache(nCacheIndex);
	}

	ms_ElemFileCache[nCacheIndex].pBuffer = pBuffer;
	ms_ElemFileCache[nCacheIndex].uId = m_pIndexList[nElemIndex].uId;
	ms_ElemFileCache[nCacheIndex].lSize = m_pIndexList[nElemIndex].uSize;
	ms_ElemFileCache[nCacheIndex].nPackIndex = m_nSelfIndex;
	ms_ElemFileCache[nCacheIndex].nElemIndex = nElemIndex;
	ms_ElemFileCache[nCacheIndex].uRefFlag = 0xffffffff;
	ms_ElemFileCache[nCacheIndex].nNumFragment = 0;
	ms_ElemFileCache[nCacheIndex].pFragmentInfo = NULL;
	if ((m_pIndexList[nElemIndex].uCompressSizeFlag & XPACK_FLAG_FRAGMENT) == 0)
	{
		return nCacheIndex;
	}

	XPackFileFragmentElemHeader	header;
	if (DirectRead(&header, m_pIndexList[nElemIndex].uOffset, sizeof(header)))
	{
		int nInfoSize = sizeof(XPackFileFragmentInfo) * header.nNumFragment;
		ms_ElemFileCache[nCacheIndex].pFragmentInfo = (XPackFileFragmentInfo*)malloc(nInfoSize);
		if (ms_ElemFileCache[nCacheIndex].pFragmentInfo)
		{
			//读取指定数据块的分块信息
			if (DirectRead(ms_ElemFileCache[nCacheIndex].pFragmentInfo,  m_pIndexList[nElemIndex].uOffset + header.nFragmentInfoOffest, nInfoSize))
			{
				ms_ElemFileCache[nCacheIndex].nNumFragment = header.nNumFragment;
				return nCacheIndex;
			}
		}
	}

	ms_nNumElemFileCache --;
	if (nCacheIndex < ms_nNumElemFileCache)
		ms_ElemFileCache[nCacheIndex] = ms_ElemFileCache[ms_nNumElemFileCache];
	return -1;
}
Beispiel #4
0
void mCFileStream::Buffer( MIUInt a_uPosition )
{
    // Padding: Room for reading before a_uPosition or writing over end of file.
    enum
    {
        EPadding = mEFileBufferSize / 3
    };
    Flush();
    MIBool const bCanRead             = ( m_enuOpenMode & mEFileOpenMode_Read ? MITrue : MIFalse );
    MIBool const bCanWrite            = ( m_enuOpenMode & mEFileOpenMode_Write ? MITrue : MIFalse );
    MIUInt const uReadPadding         = bCanRead ? EPadding : 0 ;
    MIUInt const uWritePadding        = bCanRead ? ( bCanWrite ? EPadding : 0 ) : mEFileBufferSize;
    MIUInt const uMinBufferSize       = g_min( ( mEFileBufferSize - uWritePadding ), GetSize() );
    MIUInt const uMaxBufferedPosition = GetSize() - uMinBufferSize;
    MIUInt const uOldBufferedPosition = m_uBufferedPosition;
    if ( a_uPosition <= uReadPadding )
    {
        m_uBufferedPosition = 0;
    }
    else
    {
        m_uBufferedPosition = g_min( ( a_uPosition - uReadPadding ), uMaxBufferedPosition );
    }
    m_uOffset = a_uPosition - m_uBufferedPosition;
    if ( !bCanRead )
        return;
    MIUInt const uNewBufferSize = g_min< MIUInt >( mEFileBufferSize, ( GetSize() - m_uBufferedPosition ) );
    if ( !m_arrBuffer.GetCount() )
    {
        m_arrBuffer.Resize( uNewBufferSize );
        DirectRead( m_arrBuffer.AccessBuffer(), m_uBufferedPosition, uNewBufferSize );
        return;
    }
    m_arrBuffer.Resize( mEFileBufferSize );
    MILPChar const pData = m_arrBuffer.AccessBuffer();
    MIInt const iDifference = g_limit< MIInt >( ( m_uBufferedPosition - uOldBufferedPosition ), -mEFileBufferSize, mEFileBufferSize );
    if ( iDifference >= 0 )
    {
        MIUInt uSizeRetainable = ( mEFileBufferSize - iDifference );
        g_memmove( pData, ( pData + iDifference ), uSizeRetainable );
        DirectRead( ( pData + uSizeRetainable ), ( m_uBufferedPosition + uSizeRetainable ), iDifference );
    }
    else
    {
        MIUInt uSizeRetainable = ( mEFileBufferSize + iDifference );
        g_memmove( ( pData - iDifference ), pData, uSizeRetainable );
        DirectRead( pData, m_uBufferedPosition, -iDifference );
    }
    m_arrBuffer.Resize( uNewBufferSize );
}
Beispiel #5
0
//---------------------------------------------------------------------------
// 功能:	分块读取文件
// 参数:	nElemIndex		在包中定位要读取文件的索引
//			Buffer			缓冲区指针
//			ReadBytes		要读取的长度
//			Offset			传进去的值是相对于块文件中的偏移量,之后还要加上块文件相对于包文件头的偏移量 
//			CompressSize	文件压缩的大小,0表示没有压缩,读取方式为直接读取,其他的表示为解压读取
// 返回:	读到的字节长度
//---------------------------------------------------------------------------
unsigned long XPackFile::XElemReadFragment(int nElemIndex, int nFragmentIndex, void*& Buffer)
{
	MUTEX_LOCK(ms_ReadCritical);
	XPackFileFragmentElemHeader	header;
	if (!(m_pIndexList[nElemIndex].uCompressSizeFlag & XPACK_FLAG_FRAGMENT) ||		//不是分块压缩的,不能用XElemReadFragment来读取
		!DirectRead(&header, m_pIndexList[nElemIndex].uOffset, sizeof(header)) ||	//读取头结构
		nFragmentIndex >= header.nNumFragment)	
	{
		MUTEX_UNLOCK(ms_ReadCritical);
		return 0;
	}

	//读取指定数据块的分块信息
	XPackFileFragmentInfo	fragment;
	unsigned int			uOffset = m_pIndexList[nElemIndex].uOffset + header.nFragmentInfoOffest + sizeof(XPackFileFragmentInfo) * nFragmentIndex;
	if (!DirectRead(&fragment,  uOffset, sizeof(XPackFileFragmentInfo)))
	{
		MUTEX_UNLOCK(ms_ReadCritical);
		return 0;
	}
	uOffset = m_pIndexList[nElemIndex].uOffset + fragment.uOffset;

	//如果传入buffer为空,则分配buffer
	if (Buffer == NULL)
	{
		Buffer = malloc(fragment.uSize);
		if (Buffer == NULL)
		{
			MUTEX_UNLOCK(ms_ReadCritical);
			return 0;
		}
	}

	int bOk;
	if ((fragment.uCompressSizeFlag & XPACK_METHOD_FILTER) != XPACK_METHOD_NONE)
	{
		bOk = ExtractRead(Buffer, fragment.uSize, (fragment.uCompressSizeFlag & XPACK_METHOD_FILTER),
					uOffset, (fragment.uCompressSizeFlag & XPACK_COMPRESS_SIZE_FILTER));
	}
	else
	{
		bOk = DirectRead(Buffer, uOffset, fragment.uSize);
	}

	MUTEX_UNLOCK(ms_ReadCritical);
	return (bOk ? fragment.uSize : 0);
}
Beispiel #6
0
//获取某个子文件某个分块的大小
unsigned int XPackFile::ElemGetFragmentSize(int nElemIndex, int nFragmentIndex)
{
	if ((m_pIndexList[nElemIndex].uCompressSizeFlag & XPACK_FLAG_FRAGMENT) != 0)
	{
		MUTEX_LOCK(ms_ReadCritical);
		XPackFileFragmentElemHeader	header;
		XPackFileFragmentInfo		fragment;
		if (DirectRead(&header, m_pIndexList[nElemIndex].uOffset, sizeof(header)) && nFragmentIndex < header.nNumFragment)
		{
			unsigned int uOffset = m_pIndexList[nElemIndex].uOffset + header.nFragmentInfoOffest + sizeof(XPackFileFragmentInfo) * nFragmentIndex;
			//读取指定数据块的分块信息
			if (DirectRead(&fragment,  uOffset, sizeof(XPackFileFragmentInfo)))
			{
				MUTEX_UNLOCK(ms_ReadCritical);
				return fragment.uSize;
			}
		}
		MUTEX_UNLOCK(ms_ReadCritical);
	}
	return 0;
}
Beispiel #7
0
//获取文件分块的数目
int	XPackFile::XElemGetFragmentCount(int nElemIndex)
{
	if ((m_pIndexList[nElemIndex].uCompressSizeFlag & XPACK_FLAG_FRAGMENT) != 0)
	{
		XPackFileFragmentElemHeader	header;
		if (DirectRead(&header, m_pIndexList[nElemIndex].uOffset, sizeof(header)))
		{
			return header.nNumFragment;
		}
	}
	return 0;
}
Beispiel #8
0
int File::Read(void *Data,size_t Size)
{
  int64 FilePos=0; // Initialized only to suppress some compilers warning.

  if (IgnoreReadErrors)
    FilePos=Tell();
  int ReadSize;
  while (true)
  {
    ReadSize=DirectRead(Data,Size);
    if (ReadSize==-1)
    {
      ErrorType=FILE_READERROR;
      if (AllowExceptions)
        if (IgnoreReadErrors)
        {
          ReadSize=0;
          for (size_t I=0;I<Size;I+=512)
          {
            Seek(FilePos+I,SEEK_SET);
            size_t SizeToRead=Min(Size-I,512);
            int ReadCode=DirectRead(Data,SizeToRead);
            ReadSize+=(ReadCode==-1) ? 512:ReadCode;
          }
        }
        else
        {
          if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName))
            continue;
          ErrHandler.ReadError(FileName);
        }
    }
    break;
  }
  return ReadSize;
}
Beispiel #9
0
int File::DirectRead(void *Data,int Size)
{
#ifdef _WIN_32
  const int MaxDeviceRead=20000;
#endif
#ifndef _WIN_CE
  if (HandleType==FILE_HANDLESTD)
  {
#ifdef _WIN_32
    if (Size>MaxDeviceRead)
      Size=MaxDeviceRead;
    hFile=GetStdHandle(STD_INPUT_HANDLE);
#else
    hFile=stdin;
#endif
  }
#endif
#ifdef _WIN_32
  DWORD Read;
  if (!ReadFile(hFile,Data,Size,&Read,NULL))
  {
    if (IsDevice() && Size>MaxDeviceRead)
      return(DirectRead(Data,MaxDeviceRead));
    if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE)
      return(0);
    return(-1);
  }
  return(Read);
#else
  if (LastWrite)
  {
    fflush(hFile);
    LastWrite=false;
  }
  clearerr(hFile);
  int ReadSize=fread(Data,1,Size,hFile);
  if (ferror(hFile))
    return(-1);
  return(ReadSize);
#endif
}
Beispiel #10
0
/**
Read data from memory of size <code>Size</code>. Calls the <code>DirectRead(Data,Size)</code> function.
@param Data - a pointer to the memory location of the RAR file to be extracted 
@param Size - the length, in bytes, of the <code>Data</code> variable
@return the size that was read from the memory location
*/
int File::DirectRead(void *Data,size_t Size)
{ //Calls DirectRead function
	return DirectRead((byte*)Data, Size);
}
long Connection::ReadHeader(unsigned char *buf, long len)
{
    return DirectRead(buf,len);
}