//------------------------------------------------- //功能:带解压地读取包文件到缓冲区 //参数: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; }
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); }
//------------------------------------------------- //功能:把子文件数据添加到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; }
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 ); }
//--------------------------------------------------------------------------- // 功能: 分块读取文件 // 参数: 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); }
//获取某个子文件某个分块的大小 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; }
//获取文件分块的数目 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; }
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; }
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 }
/** 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); }