KPakData.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:5k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KPakData.cpp
  5. // Date: 2000.08.08
  6. // Code: WangWei(Daphnis)
  7. // Desc: DataFile class used in package
  8. //---------------------------------------------------------------------------
  9. #include "KWin32.h"
  10. #include "KDebug.h"
  11. #include "KMemBase.h"
  12. #include "KFilePath.h"
  13. #include "KPakData.h"
  14. //---------------------------------------------------------------------------
  15. // 函数: KPakData()
  16. // 功能: 构造函数
  17. // 参数: void
  18. // 返回: void
  19. //---------------------------------------------------------------------------
  20. KPakData::KPakData()
  21. {
  22. m_pCodec = NULL;
  23. m_nFilesInPack = 0;
  24. m_nCompressMethod = CODEC_NONE;
  25. }
  26. //---------------------------------------------------------------------------
  27. // 函数: ~KPakData()
  28. // 功能: 析构函数
  29. // 参数: void
  30. // 返回: void
  31. //---------------------------------------------------------------------------
  32. KPakData::~KPakData()
  33. {
  34. Close();
  35. }
  36. //---------------------------------------------------------------------------
  37. // 函数: Open
  38. // 功能: 打开一个Pak文件包
  39. // 参数: FileName 文件名
  40. // 返回: TRUE 成功
  41. // FALSE 失败
  42. //---------------------------------------------------------------------------
  43. BOOL KPakData::Open(LPSTR FileName)
  44. {
  45. TPakFileHeader Header;
  46. // colse opened file
  47. if (m_nFilesInPack)
  48. Close();
  49. // open data file
  50. if (!m_File.Open(FileName))
  51. return FALSE;
  52. // read file header
  53. m_File.Read(&Header, sizeof(Header));
  54. // check file signature
  55. if (!g_MemComp(Header.Signature, "PACKAGE", 7))
  56. return FALSE;
  57. // get file number in pack
  58. m_nFilesInPack = Header.FilesInPack;
  59. // get compress method
  60. m_nCompressMethod = Header.CompressMethod;
  61. // alloc index table memory
  62. if (!m_MemIndex.Alloc(m_nFilesInPack * sizeof(TPakFileIndex)))
  63. return FALSE;
  64. // read index table
  65. m_File.Read(m_MemIndex.GetMemPtr(),
  66. m_nFilesInPack * sizeof(TPakFileIndex));
  67. // init decoder
  68. g_InitCodec(&m_pCodec, m_nCompressMethod);
  69. // return true
  70. return TRUE;
  71. }
  72. //---------------------------------------------------------------------------
  73. // 函数: Read
  74. // 功能: 读文件数据
  75. // 参数: lpBuffer 读取的数据缓存
  76. // dwLength 读取的字节长度
  77. // 返回: 实际读取的字节数
  78. //---------------------------------------------------------------------------
  79. DWORD KPakData::Read(LPVOID lpBuffer, DWORD dwLength)
  80. {
  81. return m_File.Read(lpBuffer, dwLength);
  82. }
  83. //---------------------------------------------------------------------------
  84. // 函数: Seek
  85. // 功能: 移动文件指针位置
  86. // 参数: pOffset 偏移量
  87. // dwMethod 基准位置
  88. // 返回: 实际移动到的位置
  89. //---------------------------------------------------------------------------
  90. DWORD KPakData::Seek(LONG lOffset, DWORD dwMethod)
  91. {
  92. return m_File.Seek(lOffset, dwMethod);
  93. }
  94. //---------------------------------------------------------------------------
  95. // 函数: Tell
  96. // 功能: 取得文件指针位置
  97. // 参数: 空
  98. // 返回: 实际文件指针的位置
  99. //---------------------------------------------------------------------------
  100. DWORD KPakData::Tell()
  101. {
  102. return m_File.Tell();
  103. }
  104. //---------------------------------------------------------------------------
  105. // 函数: Close
  106. // 功能: 关闭一个数据文件
  107. // 参数: void
  108. // 返回: void
  109. //---------------------------------------------------------------------------
  110. void KPakData::Close()
  111. {
  112. g_FreeCodec(&m_pCodec, m_nCompressMethod);
  113. m_File.Close();
  114. m_MemIndex.Free();
  115. m_nFilesInPack = 0;
  116. m_nCompressMethod = 0;
  117. }
  118. //---------------------------------------------------------------------------
  119. // 函数: Search
  120. // 功能: 在包中寻找一个文件
  121. // 参数: pFileName 要找的文件名
  122. // pOffset 找到文件的偏移
  123. // pLen 找到文件的长度
  124. // 返回: TRUE 找到了
  125. // FALSE 没找到
  126. //---------------------------------------------------------------------------
  127. BOOL KPakData::Search(LPSTR pFileName, PDWORD pOffset, PDWORD pLen)
  128. {
  129. char szPathName[MAXPATH];
  130. DWORD dwFileId;
  131. int nBegin;
  132. int nEnd;
  133. int nMid;
  134. // check file number
  135. if (m_nFilesInPack <= 0)
  136. return FALSE;
  137. // get file index table pointer
  138. TPakFileIndex* pIndex;
  139. pIndex = (TPakFileIndex*)m_MemIndex.GetMemPtr();
  140. // get pack file name with path
  141. g_GetPackPath(szPathName, pFileName);
  142. // get file id 
  143. dwFileId = g_FileName2Id(szPathName);
  144. // 用二分法查找匹配的文件
  145. nBegin = 0;
  146. nEnd = m_nFilesInPack - 1;
  147. while (nBegin <= nEnd)
  148. {
  149. nMid = (nBegin + nEnd) / 2;
  150. if (dwFileId == pIndex[nMid].FileId)
  151. {
  152. // 找到了
  153. *pOffset = pIndex[nMid].FileOffset;
  154. *pLen = pIndex[nMid].FileLength;
  155. return TRUE;
  156. }
  157. if (dwFileId < pIndex[nMid].FileId)
  158. nEnd = nMid - 1;
  159. else
  160. nBegin = nMid + 1;
  161. }
  162. // 没找到
  163. return FALSE;
  164. }
  165. //---------------------------------------------------------------------------
  166. // 函数: Decode
  167. // 功能: 解压缩
  168. // 参数: pCodeInfo 压缩数据指针
  169. // 返回: TRUE 成功
  170. // FALSE 失败
  171. //---------------------------------------------------------------------------
  172. BOOL KPakData::Decode(TCodeInfo* pCodeInfo)
  173. {
  174. return m_pCodec->Decode(pCodeInfo);
  175. }
  176. //---------------------------------------------------------------------------